Easily add all supported connectivity methods to your mbed OS project

Dependencies:   type-yd-driver

Files at this revision

API Documentation at this revision

Comitter:
MACRUM
Date:
Wed Jul 12 10:52:58 2017 +0000
Commit message:
Initial commit

Changed in this revision

README.md Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver.lib Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/HEAD Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/ORIG_HEAD Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/config Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/description Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/applypatch-msg.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/post-update.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/pre-applypatch.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/pre-commit.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/pre-rebase.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/prepare-commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/hooks/update.sample Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/index Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/info/exclude Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/logs/HEAD Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/logs/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/logs/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.idx Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.pack Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/packed-refs Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.git/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/.gitignore Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/LICENSE Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/README.md Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/apache-2.0.txt Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/module.json Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/source/AT86RFReg.h Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/source/NanostackRfPhyAtmel.cpp Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/source/at24mac.cpp Show annotated file Show diff for this revision Revisions of this file
atmel-rf-driver/source/at24mac.h Show annotated file Show diff for this revision Revisions of this file
easy-connect.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver.lib Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/ORIG_HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/config Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/description Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/applypatch-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/post-update.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/pre-applypatch.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/pre-commit.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/pre-rebase.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/prepare-commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/hooks/update.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/index Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/info/exclude Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/logs/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/logs/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/logs/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.idx Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.pack Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/packed-refs Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.git/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/.msub Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser.lib Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/ORIG_HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/config Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/description Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/applypatch-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/post-update.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/pre-applypatch.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/pre-commit.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/pre-rebase.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/prepare-commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/hooks/update.sample Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/index Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/info/exclude Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/logs/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/logs/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/logs/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/08/2f11ce298302a41ff877eed55ec226b944c24d Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/26/9f14532b98442669c50383782cbce1c67aced5 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/27/80390d5b3a7ed7a95478fc61b1a8632b843d1b Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/3b/fc95eb3c81fe98d7792e82608699e566f97603 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/45/c2c9504f680cc5f6b1624cd262117036a7a774 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/4d/677496a85bcdfd5a2d8bd5260f36d92bec09a5 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/52/f9e7d0c92be3026ed8e2d929f5a2f3af5c7216 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/6c/1e45c98871f7bf381fb2c43262ed9a05ebe1a9 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/7d/0e42380917cbd4e2b474ba5771a7e15215e74c Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/80/0d8517da4d091eb52094a1cac0a66903aed59a Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/84/0c6747d369737e2523eb7cc9e25b7ed0fcf3ee Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/85/cf37770993beecac1e4d1b9dd5fcb3d03acee5 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/93/e4cb7ebd99ce690370a168ac831cacea4034a9 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/98/76baf6df887b76b6cb5da0a2e9bec41146001b Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/ac/0e4a88ca41a9de0f9d03f1d6b75ac2ba0b4ccc Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/e2/3cc82f00dee6d8a91d5fd2bbdf6f4b548a0ffe Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/objects/f3/e3d6d5476b159f82b07d3dec0220e1047bd9b0 Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/packed-refs Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/.git/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/ATParser.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/ATParser.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedPrint.c Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ATParser/README.md Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ESP8266.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266/ESP8266.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266Interface.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/ESP8266Interface.h Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/README.md Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/.mbedignore Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/connectivity/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/gethostbyname/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/tcp_echo.py Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/tcp_echo.pyc Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/udp_echo.py Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/udp_echo.pyc Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/udp_shotgun.py Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/host_tests/udp_shotgun.pyc Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/tcp_echo/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/tcp_echo_parallel/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/tcp_hello_world/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/tcp_packet_pressure/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/tcp_packet_pressure_parallel/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/udp_dtls_handshake/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/udp_echo/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/udp_echo_parallel/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/udp_packet_pressure/main.cpp Show annotated file Show diff for this revision Revisions of this file
esp8266-driver/TESTS/net/udp_packet_pressure_parallel/main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed_lib.json Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver.lib Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/HEAD Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/ORIG_HEAD Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/config Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/description Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/applypatch-msg.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/post-update.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/pre-applypatch.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/pre-commit.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/pre-rebase.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/prepare-commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/hooks/update.sample Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/index Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/info/exclude Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/logs/HEAD Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/logs/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/logs/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.idx Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.pack Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/packed-refs Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.git/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/.gitignore Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/LICENSE Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/README.md Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/apache-2.0.txt Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/mcr20a-rf-driver/NanostackRfPhyMcr20a.h Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/module.json Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/MCR20Drv.c Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/MCR20Drv.h Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/MCR20Overwrites.h Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/MCR20Reg.h Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/NanostackRfPhyMcr20a.cpp Show annotated file Show diff for this revision Revisions of this file
mcr20a-rf-driver/source/XcvrSpi.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver.lib Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/HEAD Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/ORIG_HEAD Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/config Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/description Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/applypatch-msg.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/post-update.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/pre-applypatch.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/pre-commit.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/pre-rebase.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/prepare-commit-msg.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/hooks/update.sample Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/index Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/info/exclude Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/logs/HEAD Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/logs/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/logs/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.idx Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.pack Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/packed-refs Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/refs/heads/master Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.git/refs/remotes/origin/HEAD Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.gitignore Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/.meta Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/README.md Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/mbed_lib.json Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/NanostackRfPhySpirit1.cpp Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/SimpleSpirit1.cpp Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/README.md Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/contiki-conf.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/hw-config.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/ip64-conf.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/platform-conf.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/radio.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-config.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-const.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/stm32l-spirit1-config.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/Release_Notes.html Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/MCU_Interface.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Aes.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Calibration.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Commands.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Config.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Csma.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_DirectRF.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_General.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Gpio.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Irq.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_LinearFifo.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Management.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktBasic.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktCommon.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktMbus.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktStack.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Qi.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Radio.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Regs.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Timer.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Types.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Aes.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Calibration.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Commands.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Csma.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_DirectRF.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_General.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Gpio.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Irq.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_LinearFifo.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Management.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktBasic.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktCommon.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktMbus.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktStack.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Qi.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Radio.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Timer.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Types.c Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_gpio.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_shield_config.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/source/radio_spi.cpp Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/stm-spirit1-rf-driver/NanostackRfPhySpirit1.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/stm-spirit1-rf-driver/SimpleSpirit1.h Show annotated file Show diff for this revision Revisions of this file
stm-spirit1-rf-driver/stm-spirit1-rf-driver/radio_spi.h Show annotated file Show diff for this revision Revisions of this file
type-yd-driver.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 615f90842ce8 README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,111 @@
+# Easy Connect - Easily add all supported connectivity methods to your mbed OS project
+
+Often you want to give users of your application the choice to switch between connectivity methods. The `NetworkInterface` API makes this easy, but you'll still need a mechanism for the user to chooce the method, throw in some `#define`'s, etc. Easy Connect handles all this for you. Just declare the desired connectivity method in your `mbed_app.json` file, and call `easy_connect()` from your application.
+
+## Specifying connectivity method
+
+Add the following to your ``mbed_app.json`` file:
+
+```json
+{
+    "config": {
+        "network-interface":{
+            "help": "options are ETHERNET,WIFI_ESP8266,WIFI_ODIN,MESH_LOWPAN_ND,MESH_THREAD",
+            "value": "ETHERNET"
+        }
+    },
+    "target_overrides": {
+        "*": {
+            "target.features_add": ["NANOSTACK", "LOWPAN_ROUTER", "COMMON_PAL"],
+            "mbed-mesh-api.6lowpan-nd-channel-page": 0,
+            "mbed-mesh-api.6lowpan-nd-channel": 12
+        }
+    }
+}
+```
+If you choose `ETHERNET` with `UBLOX_ODIN_EVK_W2` you must add this to your `target-overrides` section in `mbed_app.json`:
+```json
+            "UBLOX_EVK_ODIN_W2": {
+            "target.device_has_remove": ["EMAC"]
+```
+
+If you choose `WIFI_ESP8266` or `WIFI_ODIN`, you'll also need to add the WiFi SSID and password:
+
+```json
+    "config": {
+        "network-interface":{
+            "help": "options are ETHERNET,WIFI_ESP8266,WIFI_ODIN,MESH_LOWPAN_ND,MESH_THREAD",
+            "value": "WIFI_ESP8266"
+        },
+        "esp8266-tx": {
+            "help": "Pin used as TX (connects to ESP8266 RX)",
+            "value": "PTD3"
+        },
+        "esp8266-rx": {
+            "help": "Pin used as RX (connects to ESP8266 TX)",
+            "value": "PTD2"
+        },
+        "esp8266-debug": {
+            "value": true
+        },
+        "wifi-ssid": {
+            "value": "\"SSID\""
+        },
+        "wifi-password": {
+            "value": "\"Password\""
+        }
+    }
+```
+
+If you use `MESH_LOWPAN_ND` or `MESH_THREAD` you will need to specify your radio module:
+
+```json
+    "config": {
+        "network-interface":{
+            "help": "options are ETHERNET,WIFI_ESP8266,WIFI_ODIN,MESH_LOWPAN_ND,MESH_THREAD",
+            "value": "MESH_LOWPAN_ND"
+        },
+        "mesh_radio_type": {
+        	"help": "options are ATMEL, MCR20, SPIRIT1",
+        	"value": "ATMEL"
+        }
+    }
+```
+
+## Using Easy Connect from your application
+
+Easy Connect has just one function which will either return a `NetworkInterface`-pointer or `NULL`:
+
+```cpp
+#include "easy-connect.h"
+
+int main(int, char**) {
+    NetworkInterface* network = easy_connect(true); /* has 1 argument, enable_logging (pass in true to log to serial port) */
+    if (!network) {
+        printf("Connecting to the network failed... See serial output.\r\n");
+        return 1;
+    }
+
+    // Rest of your program
+}
+```
+## CR/LF in serial output
+
+If you want to avoid using `\r\n` in your printouts and just use normal C-style `\n` instead, please specify these to your `mbed_app.json`
+
+```json
+       "target_overrides": {
+        "*": {
+            "platform.stdio-baud-rate": 115200,
+            "platform.stdio-convert-newlines": true
+        }
+    }
+```
+
+## Network errors
+
+If easy-connect cannot connect to the network it returns a network error, with an error code. To see what these error code mean, see the [mbed OS Communication API](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/communication/network_sockets/#network-errors).
+
+## Extra defines
+
+If you'd like to use Easy Connect with mbed Client then you're in luck. Easy Connect automatically defines the `MBED_SERVER_ADDRESS` macro depending on your connectivity method (either IPv4 or IPv6 address). Use this address to connect to the right instance of mbed Device Connector.
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/atmel-rf-driver/#0ae76ce17ae53766875dbdebb02d6a0f50928847
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0ae76ce17ae53766875dbdebb02d6a0f50928847
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/ORIG_HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/ORIG_HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0a833f0bac8470e678fdadb48326dc94405327f8
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/config	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/ARMmbed/atmel-rf-driver/
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/description
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/description	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/applypatch-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/applypatch-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/post-update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/post-update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/pre-applypatch.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/pre-applypatch.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/pre-commit.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/pre-commit.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/pre-rebase.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/pre-rebase.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/usr/bin/perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
+
+DOC_END
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/prepare-commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/prepare-commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /usr/bin/perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/hooks/update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/hooks/update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/index
Binary file atmel-rf-driver/.git/index has changed
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/info/exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/info/exclude	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,25 @@
+.hg
+.git
+.svn
+.CVS
+.cvs
+*.orig
+.build
+.export
+.msub
+.meta
+.ctags*
+*.uvproj
+*.uvopt
+*.project
+*.cproject
+*.launch
+*.ewp
+*.eww
+Makefile
+Debug
+*.htm
+*.settings
+mbed_settings.py
+*.py[cod]
+# subrepo ignores
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/logs/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/logs/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 0a833f0bac8470e678fdadb48326dc94405327f8 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209867 +0000	clone: from https://github.com/ARMmbed/atmel-rf-driver/
+0a833f0bac8470e678fdadb48326dc94405327f8 0ae76ce17ae53766875dbdebb02d6a0f50928847 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209868 +0000	checkout: moving from master to 0ae76ce17ae53766875dbdebb02d6a0f50928847
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/logs/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/logs/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 0a833f0bac8470e678fdadb48326dc94405327f8 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209867 +0000	clone: from https://github.com/ARMmbed/atmel-rf-driver/
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/logs/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/logs/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 0a833f0bac8470e678fdadb48326dc94405327f8 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209867 +0000	clone: from https://github.com/ARMmbed/atmel-rf-driver/
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.idx
Binary file atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.idx has changed
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.pack
Binary file atmel-rf-driver/.git/objects/pack/pack-36883ac08dda82e176ae8ea9b184b9ba928a9a22.pack has changed
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/packed-refs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/packed-refs	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,85 @@
+# pack-refs with: peeled 
+a2d72a667b7ed3ac4e70ae743fd3c02a6e02afda refs/remotes/origin/alpha2-release
+d11d8a2564ef5f946c99f8003533caea13599d7b refs/remotes/origin/alpha3-release
+6a5156bea2dc8981a7efd86bcdf341dc398307e3 refs/remotes/origin/dep_update
+dc0c089e6782d66f3ef379736f3062afae708ef2 refs/remotes/origin/eui_chip_check
+1bf67eedce0f85a16376876670d525144d887892 refs/remotes/origin/eui_mac_chip_check
+cc2f88b5903be3d98da865a22c0fb88444ebbf4c refs/remotes/origin/eventqueue
+c1841c90de9450093049f22e52aec334f2c5c704 refs/remotes/origin/feature_cmsis5
+f29a7aaefdba350fee57572a7d56bba66a87464e refs/remotes/origin/fhss_dev
+06296efdcc38e2719895af98e1f5ec911a1f00f8 refs/remotes/origin/mac_class_update
+a41e721bbb81e4e15b812909cd36005a000b03f9 refs/remotes/origin/maint_merge
+0a833f0bac8470e678fdadb48326dc94405327f8 refs/remotes/origin/master
+b73c78b4f8ccbfa3295fd419173ce576ff9ddcf6 refs/remotes/origin/morpheus_dependency
+248d04582db6ba2db423cf8eb4e3535d5ef4cb72 refs/remotes/origin/ns_minar_take2
+a36e17a728732268b404fc727940257830e208ac refs/remotes/origin/retries
+a729202ba68a7537e4bdbea5f6d91d1522280ccd refs/remotes/origin/spi_timing_fix
+a82eda14afc4bd57c0574d0d58443d4aa4dddf31 refs/remotes/origin/thread_start_cond
+37e636728520d0d6d4e6caafff5e36962e5ceec0 refs/remotes/origin/update_mbed_dep
+0f7255a79b69c09469f4b3377513a39a9e6b25f5 refs/remotes/origin/v1.0-maint
+a7ff1a1ea2b3060139a345a09b72bdbf244cf4dc refs/remotes/origin/v2.1-maint
+453e4e2324d1d634dad87b1e107a1bc762c8ff2f refs/tags/beta-release
+a16a4ed6f6e8d5f2d009f25b6ab7c38affb5019c refs/tags/mbed-os-5.1.0-rc3
+a16a4ed6f6e8d5f2d009f25b6ab7c38affb5019c refs/tags/mbed-os-5.1.0-rc4
+a2d72a667b7ed3ac4e70ae743fd3c02a6e02afda refs/tags/mbedOS-alpha2
+4d2d328030c538a15cde01baa6c6e8f15ba7e0f4 refs/tags/mbedos-16.01-release
+4d2d328030c538a15cde01baa6c6e8f15ba7e0f4 refs/tags/mbedos-16.03-release
+4a7b2df89566412ab1f78c34acd66e114c210965 refs/tags/mbedos-2016q1-oob1
+4a7b2df89566412ab1f78c34acd66e114c210965 refs/tags/mbedos-2016q1-oob2
+4d2d328030c538a15cde01baa6c6e8f15ba7e0f4 refs/tags/mbedos-2016q1-oob3
+dcd91e50e2cef8a8944ec4acc30a9186fd250838 refs/tags/mbedos-release-15-11
+083d0d49ede86c2bf6417bf0a951ff37e497480c refs/tags/mbedos-techcon-oob2
+cf743c8ed7a61cd9217d010415b872629afa92ca refs/tags/v0.0.10
+d11d8a2564ef5f946c99f8003533caea13599d7b refs/tags/v0.0.11
+3b4d57bc558e26d357280c56908a2e0a211541dc refs/tags/v0.0.12
+7ee6cb249980d2b9f4e18744273ddd4da446e43b refs/tags/v0.0.13
+0ab8f39aebb09c3d57b1b612f562c5f2ea8e8217 refs/tags/v0.0.14
+^607843bac2c6677f69805fa45b169a9f4a89147c
+5ddc1deddcabe511d9e92d82ba2943d4ab272901 refs/tags/v0.0.15
+^f2fa5831d8d80deaeff177fffb628c06f5e3f4ce
+1b68214c528ef2fa41827292d0a8b919f530d4e6 refs/tags/v0.0.16
+^60256bb25d369570403ca27e752a6847b35b1424
+761c9ed3ee0e01563a1fa4783c03f3d4b40eb87b refs/tags/v0.0.18
+^f245f7ae3556436d017827d097904d85f8d7061c
+83e3d05272235be8e2fbd671ecd0489f05974dd0 refs/tags/v0.0.19
+^7d53d340711421f2ceffa43bbc036530c1cab6d3
+4b57c221f603ec186f2939d25c17481954468ca4 refs/tags/v0.0.20
+^ec465a0701cf62542dea77b6a4933adcb3275028
+66cb6974dd688bb99be556ff87305a99cf6ff584 refs/tags/v0.0.21
+^453e4e2324d1d634dad87b1e107a1bc762c8ff2f
+a8ed93388a3952da5c2a15d1bda443f092afb746 refs/tags/v0.0.22
+^a293db7a32e00d4e96e2c0af3692c047d2126037
+05edb4fd8c8503181aa07c2cad5ab262d748cb27 refs/tags/v0.0.23
+^d57710cdad5df1e55af0a1be179b98a6e59c4ebd
+844097fe55cfcc3658bed3452469137badca2798 refs/tags/v0.0.24
+^6269d5ea5e313b33f011ece34318ecac79d6a626
+876b12b8b4f2bbe9399345259b68259d33d59909 refs/tags/v0.0.25
+^4614966ca81530bc1fb376062af078c120f24241
+1874e9cf58468a41e25450dcffeb0e0ca08d9ca6 refs/tags/v0.0.8
+cc0a6379a081f4fddc1dc98e96f1bc7c4573115c refs/tags/v0.0.9
+9b2561ff19aa36d2176cae99d05e883ddabcb70a refs/tags/v1.0.0
+^083d0d49ede86c2bf6417bf0a951ff37e497480c
+303705bca8f05d221c1f2a44290d46147af52b6f refs/tags/v1.0.1
+^dcd91e50e2cef8a8944ec4acc30a9186fd250838
+755358c39f9484546ef1330932e63d430550c825 refs/tags/v1.0.2
+^efe496dcf42e2eed98f6d70c33f8d6bd7cfd430e
+eeb91783261991c06f0541a547ccea44afea7370 refs/tags/v1.0.3
+^0f7255a79b69c09469f4b3377513a39a9e6b25f5
+b17a8d9177c6985379176ffa41cb836632644162 refs/tags/v2.0.0
+^a7a63cfea3492f9693f1904cda264b99037fe475
+8a6fb2273f4b1cbd9b6b6cb7d4aa58774f06a0be refs/tags/v2.0.1
+^232e2508475626865679b5b4e43e21f19e2d2b88
+91c188f0c616ce47b5d1d832bed97aeb5cc02384 refs/tags/v2.0.2
+^4a7b2df89566412ab1f78c34acd66e114c210965
+ca1cad744508e1abc981b4dbd359401385b4da75 refs/tags/v2.0.3
+^41441226a87109a7405e4c8ba048311484a4b1c4
+d382c3d7e1a3656176bbf1d05180928cded5217d refs/tags/v2.1.0
+^4d2d328030c538a15cde01baa6c6e8f15ba7e0f4
+17393a1acefd268c75c0376aaa24c3ae6617f2f3 refs/tags/v2.1.1
+^a7ff1a1ea2b3060139a345a09b72bdbf244cf4dc
+c81741ac293409229df9c2343398016205797eae refs/tags/v3.0.0
+^50889f6c316d0b80520c781841f053b3a8aa8cd3
+b13508e3cd625d723a153d10626bdd3b342382f7 refs/tags/v3.0.1
+^3de9de8fa23b2a699cef382dd49e7f9a1dec6e5d
+80b2af683c02ca10f40917dcf60dc0e5973504d8 refs/tags/v3.0.2
+^160ce634ac16723c18bb2be61f1ed21c776252c9
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0a833f0bac8470e678fdadb48326dc94405327f8
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.git/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.git/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/.gitignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/.gitignore	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,6 @@
+*~
+*.swo
+*.swp
+build
+yotta_modules
+yotta_targets
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/LICENSE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/LICENSE	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2 @@
+Unless specifically indicated otherwise in a file, files are licensed
+under the Apache 2.0 license, as can be found in: apache-2.0.txt
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,7 @@
+# Example RF driver for Atmel 802.15.4 transceivers #
+
+Support for:
+ * AT86RF233
+ * AT86RF212B
+
+This driver is used with 6LoWPAN stack.
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/apache-2.0.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/apache-2.0.txt	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,56 @@
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+    You must give any other recipients of the Work or Derivative Works a copy of this License; and
+    You must cause any modified files to carry prominent notices stating that You changed the files; and
+    You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+    If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/atmel-rf-driver/NanostackRfPhyAtmel.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NANOSTACK_RF_PHY_ATMEL_H_
+#define NANOSTACK_RF_PHY_ATMEL_H_
+
+#include "NanostackRfPhy.h"
+#include "at24mac.h"
+#include "PinNames.h"
+
+// Arduino pin defaults for convenience
+#if !defined(ATMEL_SPI_MOSI)
+#define ATMEL_SPI_MOSI   D11
+#endif
+#if !defined(ATMEL_SPI_MISO)
+#define ATMEL_SPI_MISO   D12
+#endif
+#if !defined(ATMEL_SPI_SCLK)
+#define ATMEL_SPI_SCLK   D13
+#endif
+#if !defined(ATMEL_SPI_CS)
+#define ATMEL_SPI_CS     D10
+#endif
+#if !defined(ATMEL_SPI_RST)
+#define ATMEL_SPI_RST    D5
+#endif
+#if !defined(ATMEL_SPI_SLP)
+#define ATMEL_SPI_SLP    D7
+#endif
+#if !defined(ATMEL_SPI_IRQ)
+#define ATMEL_SPI_IRQ    D9
+#endif
+#if !defined(ATMEL_I2C_SDA)
+#define ATMEL_I2C_SDA    D14
+#endif
+#if !defined(ATMEL_I2C_SCL)
+#define ATMEL_I2C_SCL    D15
+#endif
+
+class RFBits;
+
+class NanostackRfPhyAtmel : public NanostackRfPhy {
+public:
+    NanostackRfPhyAtmel(PinName spi_mosi, PinName spi_miso,
+            PinName spi_sclk, PinName spi_cs,  PinName spi_rst, PinName spi_slp, PinName spi_irq,
+            PinName i2c_sda, PinName i2c_scl);
+    ~NanostackRfPhyAtmel();
+    int8_t rf_register();
+    void rf_unregister();
+    void get_mac_address(uint8_t *mac);
+    void set_mac_address(uint8_t *mac);
+
+private:
+    AT24Mac _mac;
+    uint8_t _mac_addr[8];
+    RFBits *_rf;
+    bool _mac_set;
+
+    const PinName _spi_mosi;
+    const PinName _spi_miso;
+    const PinName _spi_sclk;
+    const PinName _spi_cs;
+    const PinName _spi_rst;
+    const PinName _spi_slp;
+    const PinName _spi_irq;
+};
+
+#endif /* NANOSTACK_RF_PHY_ATMEL_H_ */
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/module.json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/module.json	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,17 @@
+{
+  "name": "atmel-rf-driver",
+  "version": "3.0.2",
+  "description": "RF driver for Atmel AT86RF233",
+  "keywords": [
+    "rf",
+    "driver"
+  ],
+  "author": "Seppo Takalo <seppo.takalo@arm.com>",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "nanostack-libservice": "^3.0.0",
+    "sal-stack-nanostack": "^5.0.0",
+    "mbed-drivers": "^1.0.0"
+  },
+  "targetDependencies": {}
+}
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/source/AT86RFReg.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/source/AT86RFReg.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AT86RFREG_H_
+#define AT86RFREG_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*AT86RF212 PHY Modes*/
+#define BPSK_20                     0x00
+#define BPSK_40                     0x04
+#define BPSK_40_ALT                 0x14
+#define OQPSK_SIN_RC_100            0x08
+#define OQPSK_SIN_RC_200            0x09
+#define OQPSK_RC_100                0x18
+#define OQPSK_RC_200                0x19
+#define OQPSK_SIN_250               0x0c
+#define OQPSK_SIN_500               0x0d
+#define OQPSK_SIN_500_ALT           0x0f
+#define OQPSK_RC_250                0x1c
+#define OQPSK_RC_500                0x1d
+#define OQPSK_RC_500_ALT            0x1f
+#define OQPSK_SIN_RC_400_SCR_ON     0x2A
+#define OQPSK_SIN_RC_400_SCR_OFF    0x0A
+#define OQPSK_RC_400_SCR_ON         0x3A
+#define OQPSK_RC_400_SCR_OFF        0x1A
+#define OQPSK_SIN_1000_SCR_ON       0x2E
+#define OQPSK_SIN_1000_SCR_OFF      0x0E
+#define OQPSK_RC_1000_SCR_ON        0x3E
+#define OQPSK_RC_1000_SCR_OFF       0x1E
+
+/*Supported transceivers*/
+#define PART_AT86RF231              0x03
+#define PART_AT86RF212              0x07
+#define PART_AT86RF233              0x0B
+#define VERSION_AT86RF212           0x01
+#define VERSION_AT86RF212B          0x03
+
+/*RF Configuration Registers*/
+#define TRX_STATUS                  0x01
+#define TRX_STATE                   0x02
+#define TRX_CTRL_0                  0x03
+#define TRX_CTRL_1                  0x04
+#define PHY_TX_PWR                  0x05
+#define PHY_RSSI                    0x06
+#define PHY_ED_LEVEL                0x07
+#define PHY_CC_CCA                  0x08
+#define RX_CTRL                     0x0A
+#define SFD_VALUE                   0x0B
+#define TRX_CTRL_2                  0x0C
+#define ANT_DIV                     0x0D
+#define IRQ_MASK                    0x0E
+#define IRQ_STATUS                  0x0F
+#define VREG_CTRL                   0x10
+#define BATMON                      0x11
+#define XOSC_CTRL                   0x12
+#define CC_CTRL_0                   0x13
+#define CC_CTRL_1                   0x14
+#define RX_SYN                      0x15
+#define TRX_RPC                     0x16
+#define RF_CTRL_0                   0x16
+#define XAH_CTRL_1                  0x17
+#define FTN_CTRL                    0x18
+#define PLL_CF                      0x1A
+#define PLL_DCU                     0x1B
+#define PART_NUM                    0x1C
+#define VERSION_NUM                 0x1D
+#define MAN_ID_0                    0x1E
+#define MAN_ID_1                    0x1F
+#define SHORT_ADDR_0                0x20
+#define SHORT_ADDR_1                0x21
+#define PAN_ID_0                    0x22
+#define PAN_ID_1                    0x23
+#define IEEE_ADDR_0                 0x24
+#define IEEE_ADDR_1                 0x25
+#define IEEE_ADDR_2                 0x26
+#define IEEE_ADDR_3                 0x27
+#define IEEE_ADDR_4                 0x28
+#define IEEE_ADDR_5                 0x29
+#define IEEE_ADDR_6                 0x2A
+#define IEEE_ADDR_7                 0x2B
+#define XAH_CTRL_0                  0x2C
+#define CSMA_SEED_0                 0x2D
+#define CSMA_SEED_1                 0x2E
+#define CSMA_BE                     0x2F
+
+/* CSMA_SEED_1*/
+#define AACK_FVN_MODE1              7
+#define AACK_FVN_MODE0              6
+#define AACK_SET_PD                 5
+#define AACK_DIS_ACK                4
+#define AACK_I_AM_COORD             3
+#define CSMA_SEED_12                2
+#define CSMA_SEED_11                1
+#define CSMA_SEED_10                0
+
+/*TRX_STATUS bits*/
+#define CCA_STATUS                  0x40
+#define CCA_DONE                    0x80
+
+/*PHY_CC_CCA bits*/
+#define CCA_REQUEST                 0x80
+#define CCA_MODE_1                  0x20
+#define CCA_MODE_3                  0x60
+
+/*IRQ_MASK bits*/
+#define RX_START                    0x04
+#define TRX_END                     0x08
+#define CCA_ED_DONE                 0x10
+#define AMI                         0x20
+#define TRX_UR                      0x40
+
+/*ANT_DIV bits*/
+#define ANT_DIV_EN                  0x08
+#define ANT_EXT_SW_EN               0x04
+#define ANT_CTRL_DEFAULT            0x03
+
+/*TRX_CTRL_1 bits*/
+#define PA_EXT_EN                   0x80
+
+/*FTN_CTRL bits*/
+#define FTN_START                   0x80
+
+/*PHY_RSSI bits*/
+#define CRC_VALID                   0x80
+
+/*RX_SYN bits*/
+#define RX_PDT_DIS                  0x80
+
+/*TRX_RPC bits */
+#define RX_RPC_CTRL                 0xC0
+#define RX_RPC_EN                   0x20
+#define PDT_RPC_EN                  0x10
+#define PLL_RPC_EN                  0x08
+#define XAH_TX_RPC_EN               0x04
+#define IPAN_RPC_EN                 0x02
+#define TRX_RPC_RSVD_1              0x01
+
+/*XAH_CTRL_1 bits*/
+#define AACK_PROM_MODE              0x02
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AT86RFREG_H_ */
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/source/NanostackRfPhyAtmel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/source/NanostackRfPhyAtmel.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2479 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string.h>
+#include "platform/arm_hal_interrupt.h"
+#include "nanostack/platform/arm_hal_phy.h"
+#include "ns_types.h"
+#include "NanostackRfPhyAtmel.h"
+#include "randLIB.h"
+#include "AT86RFReg.h"
+#include "nanostack/platform/arm_hal_phy.h"
+#include "toolchain.h"
+
+/*Worst case sensitivity*/
+#define RF_DEFAULT_SENSITIVITY -88
+/*Run calibration every 5 minutes*/
+#define RF_CALIBRATION_INTERVAL 6000000
+/*Wait ACK for 2.5ms*/
+#define RF_ACK_WAIT_DEFAULT_TIMEOUT 50
+/*Base CCA backoff (50us units) - substitutes for Inter-Frame Spacing*/
+#define RF_CCA_BASE_BACKOFF 13 /* 650us */
+/*CCA random backoff (50us units)*/
+#define RF_CCA_RANDOM_BACKOFF 51 /* 2550us */
+
+#define RF_MTU 127
+
+#define RF_PHY_MODE OQPSK_SIN_250
+
+/*Radio RX and TX state definitions*/
+#define RFF_ON 0x01
+#define RFF_RX 0x02
+#define RFF_TX 0x04
+#define RFF_CCA 0x08
+#define RFF_PROT 0x10
+
+typedef enum
+{
+    RF_MODE_NORMAL = 0,
+    RF_MODE_SNIFFER = 1,
+    RF_MODE_ED = 2
+}rf_mode_t;
+
+/*Atmel RF Part Type*/
+typedef enum
+{
+    ATMEL_UNKNOW_DEV = 0,
+    ATMEL_AT86RF212,
+    ATMEL_AT86RF231, // No longer supported (doesn't give ED+status on frame read)
+    ATMEL_AT86RF233
+}rf_trx_part_e;
+
+/*Atmel RF states*/
+typedef enum
+{
+    NOP = 0x00,
+    BUSY_RX = 0x01,
+    RF_TX_START = 0x02,
+    FORCE_TRX_OFF = 0x03,
+    FORCE_PLL_ON = 0x04,
+    RX_ON = 0x06,
+    TRX_OFF = 0x08,
+    PLL_ON = 0x09,
+    BUSY_RX_AACK = 0x11,
+    SLEEP = 0x0F,
+    RX_AACK_ON = 0x16,
+    TX_ARET_ON = 0x19
+}rf_trx_states_t;
+
+static const uint8_t *rf_tx_data; // Points to Nanostack's buffer
+static uint8_t rf_tx_length;
+/*ACK wait duration changes depending on data rate*/
+static uint16_t rf_ack_wait_duration = RF_ACK_WAIT_DEFAULT_TIMEOUT;
+
+static int8_t rf_sensitivity = RF_DEFAULT_SENSITIVITY;
+static rf_mode_t rf_mode = RF_MODE_NORMAL;
+static uint8_t radio_tx_power = 0x00;   // Default to +4dBm
+static uint8_t rf_phy_channel = 12;
+static uint8_t rf_tuned = 1;
+static uint8_t rf_use_antenna_diversity = 0;
+static int16_t expected_ack_sequence = -1;
+static uint8_t rf_rx_mode = 0;
+static uint8_t rf_flags = 0;
+static int8_t rf_radio_driver_id = -1;
+static phy_device_driver_s device_driver;
+static uint8_t mac_tx_handle = 0;
+
+/* Channel configurations for 2.4 and sub-GHz */
+static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK};
+static const phy_rf_channel_configuration_s phy_subghz = {868300000U, 2000000U, 250000U, 11U, M_OQPSK};
+
+static const phy_device_channel_page_s phy_channel_pages[] = {
+        { CHANNEL_PAGE_0, &phy_24ghz},
+        { CHANNEL_PAGE_2, &phy_subghz},
+        { CHANNEL_PAGE_0, NULL}
+};
+
+/**
+ *  RF output power write
+ *
+ * \brief TX power has to be set before network start.
+ *
+ * \param power
+ *              AT86RF233
+ *              0 = 4 dBm
+ *              1 = 3.7 dBm
+ *              2 = 3.4 dBm
+ *              3 = 3 dBm
+ *              4 = 2.5 dBm
+ *              5 = 2 dBm
+ *              6 = 1 dBm
+ *              7 = 0 dBm
+ *              8 = -1 dBm
+ *              9 = -2 dBm
+ *              10 = -3 dBm
+ *              11 = -4 dBm
+ *              12 = -6 dBm
+ *              13 = -8 dBm
+ *              14 = -12 dBm
+ *              15 = -17 dBm
+ *
+ *              AT86RF212B
+ *              See datasheet for TX power settings
+ *
+ * \return 0, Supported Value
+ * \return -1, Not Supported Value
+ */
+static int8_t rf_tx_power_set(uint8_t power);
+static rf_trx_part_e rf_radio_type_read(void);
+static void rf_ack_wait_timer_start(uint16_t slots);
+static void rf_ack_wait_timer_stop(void);
+static void rf_handle_cca_ed_done(void);
+static void rf_handle_tx_end(void);
+static void rf_handle_rx_end(void);
+static void rf_on(void);
+static void rf_receive(void);
+static void rf_poll_trx_state_change(rf_trx_states_t trx_state);
+static void rf_init(void);
+static int8_t rf_device_register(const uint8_t *mac_addr);
+static void rf_device_unregister(void);
+static void rf_enable_static_frame_buffer_protection(void);
+static void rf_disable_static_frame_buffer_protection(void);
+static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol );
+static void rf_cca_abort(void);
+static void rf_calibration_cb(void);
+static void rf_init_phy_mode(void);
+static void rf_ack_wait_timer_interrupt(void);
+static void rf_calibration_timer_interrupt(void);
+static void rf_calibration_timer_start(uint32_t slots);
+static void rf_cca_timer_interrupt(void);
+static void rf_cca_timer_start(uint32_t slots);
+static uint8_t rf_scale_lqi(int8_t rssi);
+
+static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel);
+static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr);
+static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr);
+
+static void rf_if_cca_timer_start(uint32_t slots);
+static void rf_if_enable_promiscuous_mode(void);
+static void rf_if_lock(void);
+static void rf_if_unlock(void);
+static uint8_t rf_if_read_rnd(void);
+static void rf_if_calibration_timer_start(uint32_t slots);
+static void rf_if_interrupt_handler(void);
+static void rf_if_ack_wait_timer_start(uint16_t slots);
+static void rf_if_ack_wait_timer_stop(void);
+static void rf_if_ack_pending_ctrl(uint8_t state);
+static void rf_if_calibration(void);
+static uint8_t rf_if_read_register(uint8_t addr);
+static void rf_if_set_bit(uint8_t addr, uint8_t bit, uint8_t bit_mask);
+static void rf_if_clear_bit(uint8_t addr, uint8_t bit);
+static void rf_if_write_register(uint8_t addr, uint8_t data);
+static void rf_if_reset_radio(void);
+static void rf_if_enable_ant_div(void);
+static void rf_if_disable_ant_div(void);
+static void rf_if_enable_slptr(void);
+static void rf_if_disable_slptr(void);
+static void rf_if_write_antenna_diversity_settings(void);
+static void rf_if_write_set_tx_power_register(uint8_t value);
+static void rf_if_write_rf_settings(void);
+static uint8_t rf_if_check_cca(void);
+static uint8_t rf_if_read_trx_state(void);
+static uint16_t rf_if_read_packet(uint8_t data[RF_MTU], uint8_t *lqi_out, uint8_t *ed_out, bool *crc_good);
+static void rf_if_write_short_addr_registers(uint8_t *short_address);
+static uint8_t rf_if_last_acked_pending(void);
+static void rf_if_write_pan_id_registers(uint8_t *pan_id);
+static void rf_if_write_ieee_addr_registers(uint8_t *address);
+static void rf_if_write_frame_buffer(const uint8_t *ptr, uint8_t length);
+static void rf_if_change_trx_state(rf_trx_states_t trx_state);
+static void rf_if_enable_tx_end_interrupt(void);
+static void rf_if_enable_rx_end_interrupt(void);
+static void rf_if_enable_cca_ed_done_interrupt(void);
+static void rf_if_start_cca_process(void);
+static int8_t rf_if_scale_rssi(uint8_t ed_level);
+static void rf_if_set_channel_register(uint8_t channel);
+static void rf_if_enable_promiscuous_mode(void);
+static void rf_if_disable_promiscuous_mode(void);
+static uint8_t rf_if_read_part_num(void);
+static void rf_if_enable_irq(void);
+static void rf_if_disable_irq(void);
+
+#ifdef MBED_CONF_RTOS_PRESENT
+#include "mbed.h"
+#include "rtos.h"
+
+static void rf_if_irq_task_process_irq();
+
+#define SIG_RADIO       1
+#define SIG_TIMER_ACK   2
+#define SIG_TIMER_CAL   4
+#define SIG_TIMER_CCA   8
+
+#define SIG_TIMERS (SIG_TIMER_ACK|SIG_TIMER_CAL|SIG_TIMER_CCA)
+#define SIG_ALL (SIG_RADIO|SIG_TIMERS)
+#endif
+
+// HW pins to RF chip
+#define SPI_SPEED 7500000
+
+class UnlockedSPI : public SPI {
+public:
+    UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
+        SPI(mosi, miso, sclk) { }
+    virtual void lock() { }
+    virtual void unlock() { }
+};
+
+class RFBits {
+public:
+    RFBits(PinName spi_mosi, PinName spi_miso,
+           PinName spi_sclk, PinName spi_cs,
+           PinName spi_rst, PinName spi_slp, PinName spi_irq);
+    UnlockedSPI spi;
+    DigitalOut CS;
+    DigitalOut RST;
+    DigitalOut SLP_TR;
+    InterruptIn IRQ;
+    Timeout ack_timer;
+    Timeout cal_timer;
+    Timeout cca_timer;
+#ifdef MBED_CONF_RTOS_PRESENT
+    Thread irq_thread;
+    Mutex mutex;
+    void rf_if_irq_task();
+#endif
+};
+
+RFBits::RFBits(PinName spi_mosi, PinName spi_miso,
+               PinName spi_sclk, PinName spi_cs,
+               PinName spi_rst, PinName spi_slp, PinName spi_irq)
+    :   spi(spi_mosi, spi_miso, spi_sclk),
+        CS(spi_cs),
+        RST(spi_rst),
+        SLP_TR(spi_slp),
+        IRQ(spi_irq)
+#ifdef MBED_CONF_RTOS_PRESENT
+,irq_thread(osPriorityRealtime, 1024)
+#endif
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+    irq_thread.start(mbed::callback(this, &RFBits::rf_if_irq_task));
+#endif
+}
+
+static RFBits *rf;
+static uint8_t rf_part_num = 0;
+/*TODO: RSSI Base value setting*/
+static int8_t rf_rssi_base_val = -91;
+
+static uint8_t rf_if_spi_exchange(uint8_t out);
+
+static void rf_if_lock(void)
+{
+    platform_enter_critical();
+}
+
+static void rf_if_unlock(void)
+{
+    platform_exit_critical();
+}
+
+#ifdef MBED_CONF_RTOS_PRESENT
+static void rf_if_cca_timer_signal(void)
+{
+    rf->irq_thread.signal_set(SIG_TIMER_CCA);
+}
+
+static void rf_if_cal_timer_signal(void)
+{
+    rf->irq_thread.signal_set(SIG_TIMER_CAL);
+}
+
+static void rf_if_ack_timer_signal(void)
+{
+    rf->irq_thread.signal_set(SIG_TIMER_ACK);
+}
+#endif
+
+
+/* Delay functions for RF Chip SPI access */
+#ifdef __CC_ARM
+__asm static void delay_loop(uint32_t count)
+{
+1
+  SUBS a1, a1, #1
+  BCS  %BT1
+  BX   lr
+}
+#elif defined (__ICCARM__)
+static void delay_loop(uint32_t count)
+{
+  __asm volatile(
+    "loop: \n"
+    " SUBS %0, %0, #1 \n"
+    " BCS.n  loop\n"
+    : "+r" (count)
+    :
+    : "cc"
+  );
+}
+#else // GCC
+static void delay_loop(uint32_t count)
+{
+  __asm__ volatile (
+    "%=:\n\t"
+#if defined(__thumb__) && !defined(__thumb2__)
+    "SUB  %0, #1\n\t"
+#else
+    "SUBS %0, %0, #1\n\t"
+#endif
+    "BCS  %=b\n\t"
+    : "+l" (count)
+    :
+    : "cc"
+  );
+}
+#endif
+
+static void delay_ns(uint32_t ns)
+{
+  uint32_t cycles_per_us = SystemCoreClock / 1000000;
+  // Cortex-M0 takes 4 cycles per loop (SUB=1, BCS=3)
+  // Cortex-M3 and M4 takes 3 cycles per loop (SUB=1, BCS=2)
+  // Cortex-M7 - who knows?
+  // Cortex M3-M7 have "CYCCNT" - would be better than a software loop, but M0 doesn't
+  // Assume 3 cycles per loop for now - will be 33% slow on M0. No biggie,
+  // as original version of code was 300% slow on M4.
+  // [Note that this very calculation, plus call overhead, will take multiple
+  // cycles. Could well be 100ns on its own... So round down here, startup is
+  // worth at least one loop iteration.]
+  uint32_t count = (cycles_per_us * ns) / 3000;
+
+  delay_loop(count);
+}
+
+// t1 = 180ns, SEL falling edge to MISO active [SPI setup assumed slow enough to not need manual delay]
+#define CS_SELECT()  {rf->CS = 0; /* delay_ns(180); */}
+ // t9 = 250ns, last clock to SEL rising edge, t8 = 250ns, SPI idle time between consecutive access
+#define CS_RELEASE() {delay_ns(250); rf->CS = 1; delay_ns(250);}
+
+/*
+ * \brief Function sets the TX power variable.
+ *
+ * \param power TX power setting
+ *
+ * \return 0 Success
+ * \return -1 Fail
+ */
+MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power)
+{
+    int8_t ret_val = -1;
+
+    radio_tx_power = power;
+    rf_if_lock();
+    rf_if_write_set_tx_power_register(radio_tx_power);
+    rf_if_unlock();
+    ret_val = 0;
+
+    return ret_val;
+}
+
+/*
+ * \brief Read connected radio part.
+ *
+ * This function only return valid information when rf_init() is called
+ *
+ * \return
+ */
+static rf_trx_part_e rf_radio_type_read(void)
+{
+  rf_trx_part_e ret_val = ATMEL_UNKNOW_DEV;
+
+  switch (rf_part_num)
+  {
+    case PART_AT86RF212:
+      ret_val = ATMEL_AT86RF212;
+      break;
+    case PART_AT86RF233:
+      ret_val = ATMEL_AT86RF233;
+      break;
+    default:
+      break;
+  }
+
+  return ret_val;
+}
+
+
+/*
+ * \brief Function starts the ACK wait timeout.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_if_ack_wait_timer_start(uint16_t slots)
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+  rf->ack_timer.attach_us(rf_if_ack_timer_signal, slots*50);
+#else
+  rf->ack_timer.attach_us(rf_ack_wait_timer_interrupt, slots*50);
+#endif
+}
+
+/*
+ * \brief Function starts the calibration interval.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_if_calibration_timer_start(uint32_t slots)
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+  rf->cal_timer.attach_us(rf_if_cal_timer_signal, slots*50);
+#else
+  rf->cal_timer.attach_us(rf_calibration_timer_interrupt, slots*50);
+#endif
+}
+
+/*
+ * \brief Function starts the CCA interval.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_if_cca_timer_start(uint32_t slots)
+{
+#ifdef MBED_CONF_RTOS_PRESENT
+  rf->cca_timer.attach_us(rf_if_cca_timer_signal, slots*50);
+#else
+  rf->cca_timer.attach_us(rf_cca_timer_interrupt, slots*50);
+#endif
+}
+
+/*
+ * \brief Function stops the CCA interval.
+ *
+ * \return none
+ */
+static void rf_if_cca_timer_stop(void)
+{
+  rf->cca_timer.detach();
+}
+
+/*
+ * \brief Function stops the ACK wait timeout.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_ack_wait_timer_stop(void)
+{
+  rf->ack_timer.detach();
+}
+
+/*
+ * \brief Function sets bit(s) in given RF register.
+ *
+ * \param addr Address of the register to set
+ * \param bit Bit(s) to set
+ * \param bit_mask Masks the field inside the register
+ *
+ * \return none
+ */
+static void rf_if_set_bit(uint8_t addr, uint8_t bit, uint8_t bit_mask)
+{
+  uint8_t reg = rf_if_read_register(addr);
+  reg &= ~bit_mask;
+  reg |= bit;
+  rf_if_write_register(addr, reg);
+}
+
+/*
+ * \brief Function clears bit(s) in given RF register.
+ *
+ * \param addr Address of the register to clear
+ * \param bit Bit(s) to clear
+ *
+ * \return none
+ */
+static void rf_if_clear_bit(uint8_t addr, uint8_t bit)
+{
+  rf_if_set_bit(addr, 0, bit);
+}
+
+/*
+ * \brief Function writes register in RF.
+ *
+ * \param addr Address on the RF
+ * \param data Written data
+ *
+ * \return none
+ */
+static void rf_if_write_register(uint8_t addr, uint8_t data)
+{
+  uint8_t cmd = 0xC0;
+  CS_SELECT();
+  rf_if_spi_exchange(cmd | addr);
+  rf_if_spi_exchange(data);
+  CS_RELEASE();
+}
+
+/*
+ * \brief Function reads RF register.
+ *
+ * \param addr Address on the RF
+ *
+ * \return Read data
+ */
+static uint8_t rf_if_read_register(uint8_t addr)
+{
+  uint8_t cmd = 0x80;
+  uint8_t data;
+  CS_SELECT();
+  rf_if_spi_exchange(cmd | addr);
+  data = rf_if_spi_exchange(0);
+  CS_RELEASE();
+  return data;
+}
+
+/*
+ * \brief Function resets the RF.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_reset_radio(void)
+{
+  rf->spi.frequency(SPI_SPEED);
+  rf->IRQ.rise(0);
+  rf->RST = 1;
+  wait_ms(1);
+  rf->RST = 0;
+  wait_ms(10);
+  CS_RELEASE();
+  rf->SLP_TR = 0;
+  wait_ms(10);
+  rf->RST = 1;
+  wait_ms(10);
+
+  rf->IRQ.rise(&rf_if_interrupt_handler);
+}
+
+/*
+ * \brief Function enables the promiscuous mode.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_promiscuous_mode(void)
+{
+  /*Set AACK_PROM_MODE to enable the promiscuous mode*/
+  rf_if_set_bit(XAH_CTRL_1, AACK_PROM_MODE, AACK_PROM_MODE);
+}
+
+/*
+ * \brief Function enables the promiscuous mode.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_disable_promiscuous_mode(void)
+{
+  /*Set AACK_PROM_MODE to enable the promiscuous mode*/
+  rf_if_clear_bit(XAH_CTRL_1, AACK_PROM_MODE);
+}
+
+/*
+ * \brief Function enables the Antenna diversity usage.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_ant_div(void)
+{
+  /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/
+  rf_if_set_bit(ANT_DIV, ANT_EXT_SW_EN, ANT_EXT_SW_EN);
+}
+
+/*
+ * \brief Function disables the Antenna diversity usage.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_disable_ant_div(void)
+{
+  rf_if_clear_bit(ANT_DIV, ANT_EXT_SW_EN);
+}
+
+/*
+ * \brief Function sets the SLP TR pin.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_slptr(void)
+{
+  rf->SLP_TR = 1;
+}
+
+/*
+ * \brief Function clears the SLP TR pin.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_disable_slptr(void)
+{
+  rf->SLP_TR = 0;
+}
+
+/*
+ * \brief Function writes the antenna diversity settings.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_write_antenna_diversity_settings(void)
+{
+  /*Recommended setting of PDT_THRES is 3 when antenna diversity is used*/
+  rf_if_set_bit(RX_CTRL, 0x03, 0x0f);
+  rf_if_write_register(ANT_DIV, ANT_DIV_EN | ANT_EXT_SW_EN | ANT_CTRL_DEFAULT);
+}
+
+/*
+ * \brief Function writes the TX output power register.
+ *
+ * \param value Given register value
+ *
+ * \return none
+ */
+static void rf_if_write_set_tx_power_register(uint8_t value)
+{
+  rf_if_write_register(PHY_TX_PWR, value);
+}
+
+/*
+ * \brief Function returns the RF part number.
+ *
+ * \param none
+ *
+ * \return part number
+ */
+static uint8_t rf_if_read_part_num(void)
+{
+  return rf_if_read_register(PART_NUM);
+}
+
+/*
+ * \brief Function writes the RF settings and initialises SPI interface.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_write_rf_settings(void)
+{
+  /*Reset RF module*/
+  rf_if_reset_radio();
+
+  rf_part_num = rf_if_read_part_num();
+
+  rf_if_write_register(XAH_CTRL_0,0);
+  rf_if_write_register(TRX_CTRL_1, 0x20);
+
+  /*CCA Mode - Carrier sense OR energy above threshold. Channel list is set separately*/
+  rf_if_write_register(PHY_CC_CCA, 0x05);
+
+  /*Read transceiver PART_NUM*/
+  rf_part_num = rf_if_read_register(PART_NUM);
+
+  /*Sub-GHz RF settings*/
+  if(rf_part_num == PART_AT86RF212)
+  {
+    /*GC_TX_OFFS mode-dependent setting - OQPSK*/
+    rf_if_write_register(RF_CTRL_0, 0x32);
+
+    if(rf_if_read_register(VERSION_NUM) == VERSION_AT86RF212B)
+    {
+      /*TX Output Power setting - 0 dBm North American Band*/
+      rf_if_write_register(PHY_TX_PWR, 0x03);
+    }
+    else
+    {
+      /*TX Output Power setting - 0 dBm North American Band*/
+      rf_if_write_register(PHY_TX_PWR, 0x24);
+    }
+
+    /*PHY Mode: IEEE 802.15.4-2006/2011 - OQPSK-SIN-250*/
+    rf_if_write_register(TRX_CTRL_2, RF_PHY_MODE);
+    /*Based on receiver Characteristics. See AT86RF212B Datasheet where RSSI BASE VALUE in range -97 - -100 dBm*/
+    rf_rssi_base_val = -98;
+  }
+  /*2.4GHz RF settings*/
+  else
+  {
+#if 0
+    /* Disable power saving functions for now - can only impact reliability,
+     * and don't have any users demanding it. */
+    /*Set RPC register*/
+    rf_if_write_register(TRX_RPC, RX_RPC_CTRL|RX_RPC_EN|PLL_RPC_EN|XAH_TX_RPC_EN|IPAN_RPC_EN|TRX_RPC_RSVD_1);
+#endif
+    /*PHY Mode: IEEE 802.15.4 - Data Rate 250 kb/s*/
+    rf_if_write_register(TRX_CTRL_2, 0);
+    rf_rssi_base_val = -91;
+  }
+}
+
+/*
+ * \brief Function checks the channel availability
+ *
+ * \param none
+ *
+ * \return 1 Channel clear
+ * \return 0 Channel not clear
+ */
+static uint8_t rf_if_check_cca(void)
+{
+  uint8_t retval = 0;
+  if(rf_if_read_register(TRX_STATUS) & CCA_STATUS)
+  {
+    retval = 1;
+  }
+  return retval;
+}
+
+/*
+ * \brief Function returns the RF state
+ *
+ * \param none
+ *
+ * \return RF state
+ */
+static uint8_t rf_if_read_trx_state(void)
+{
+  return rf_if_read_register(TRX_STATUS) & 0x1F;
+}
+
+/*
+ * \brief Function reads packet buffer.
+ *
+ * \param data_out Output buffer
+ * \param lqi_out LQI output
+ * \param ed_out ED output
+ * \param crc_good CRC good indication
+ *
+ * \return PSDU length [0..RF_MTU]
+ */
+static uint16_t rf_if_read_packet(uint8_t data_out[RF_MTU], uint8_t *lqi_out, uint8_t *ed_out, bool *crc_good)
+{
+  CS_SELECT();
+  rf_if_spi_exchange(0x20);
+  uint8_t len = rf_if_spi_exchange(0) & 0x7F;
+  uint8_t *ptr = data_out;
+  for (uint_fast8_t i = 0; i < len; i++) {
+    *ptr++ = rf_if_spi_exchange(0);
+  }
+
+  *lqi_out = rf_if_spi_exchange(0);
+  *ed_out = rf_if_spi_exchange(0);
+  *crc_good = rf_if_spi_exchange(0) & 0x80;
+  CS_RELEASE();
+
+  return len;
+}
+
+/*
+ * \brief Function writes RF short address registers
+ *
+ * \param short_address Given short address
+ *
+ * \return none
+ */
+static void rf_if_write_short_addr_registers(uint8_t *short_address)
+{
+  rf_if_write_register(SHORT_ADDR_1, *short_address++);
+  rf_if_write_register(SHORT_ADDR_0, *short_address);
+}
+
+/*
+ * \brief Function sets the frame pending in ACK message
+ *
+ * \param state Given frame pending state
+ *
+ * \return none
+ */
+static void rf_if_ack_pending_ctrl(uint8_t state)
+{
+  rf_if_lock();
+  if(state)
+  {
+    rf_if_set_bit(CSMA_SEED_1, (1 << AACK_SET_PD), (1 << AACK_SET_PD));
+  }
+  else
+  {
+    rf_if_clear_bit(CSMA_SEED_1, (1 << AACK_SET_PD));
+  }
+  rf_if_unlock();
+}
+
+/*
+ * \brief Function returns the state of frame pending control
+ *
+ * \param none
+ *
+ * \return Frame pending state
+ */
+static uint8_t rf_if_last_acked_pending(void)
+{
+  uint8_t last_acked_data_pending;
+
+  rf_if_lock();
+  if(rf_if_read_register(CSMA_SEED_1) & 0x20)
+    last_acked_data_pending = 1;
+  else
+    last_acked_data_pending = 0;
+  rf_if_unlock();
+
+  return last_acked_data_pending;
+}
+
+/*
+ * \brief Function calibrates the RF part.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_calibration(void)
+{
+  rf_if_set_bit(FTN_CTRL, FTN_START, FTN_START);
+  /*Wait while calibration is running*/
+  while(rf_if_read_register(FTN_CTRL) & FTN_START);
+}
+
+/*
+ * \brief Function writes RF PAN Id registers
+ *
+ * \param pan_id Given PAN Id
+ *
+ * \return none
+ */
+static void rf_if_write_pan_id_registers(uint8_t *pan_id)
+{
+  rf_if_write_register(PAN_ID_1, *pan_id++);
+  rf_if_write_register(PAN_ID_0, *pan_id);
+}
+
+/*
+ * \brief Function writes RF IEEE Address registers
+ *
+ * \param address Given IEEE Address
+ *
+ * \return none
+ */
+static void rf_if_write_ieee_addr_registers(uint8_t *address)
+{
+  uint8_t i;
+  uint8_t temp = IEEE_ADDR_0;
+
+  for(i=0; i<8; i++)
+    rf_if_write_register(temp++, address[7-i]);
+}
+
+/*
+ * \brief Function writes data in RF frame buffer.
+ *
+ * \param ptr Pointer to data (PSDU, except FCS)
+ * \param length Pointer to length (PSDU length, minus 2 for FCS)
+ *
+ * \return none
+ */
+static void rf_if_write_frame_buffer(const uint8_t *ptr, uint8_t length)
+{
+  uint8_t i;
+  uint8_t cmd = 0x60;
+
+  CS_SELECT();
+  rf_if_spi_exchange(cmd);
+  rf_if_spi_exchange(length + 2);
+  for(i=0; i<length; i++)
+    rf_if_spi_exchange(*ptr++);
+
+  CS_RELEASE();
+}
+
+/*
+ * \brief Function returns 8-bit random value.
+ *
+ * \param none
+ *
+ * \return random value
+ */
+static uint8_t rf_if_read_rnd(void)
+{
+  uint8_t temp;
+  uint8_t tmp_rpc_val = 0;
+  /*RPC must be disabled while reading the random number*/
+  if(rf_part_num == PART_AT86RF233)
+  {
+    tmp_rpc_val = rf_if_read_register(TRX_RPC);
+    rf_if_write_register(TRX_RPC, RX_RPC_CTRL|TRX_RPC_RSVD_1);
+  }
+
+  wait_ms(1);
+  temp = ((rf_if_read_register(PHY_RSSI)>>5) << 6);
+  wait_ms(1);
+  temp |= ((rf_if_read_register(PHY_RSSI)>>5) << 4);
+  wait_ms(1);
+  temp |= ((rf_if_read_register(PHY_RSSI)>>5) << 2);
+  wait_ms(1);
+  temp |= ((rf_if_read_register(PHY_RSSI)>>5));
+  wait_ms(1);
+  if(rf_part_num == PART_AT86RF233)
+    rf_if_write_register(TRX_RPC, tmp_rpc_val);
+  return temp;
+}
+
+/*
+ * \brief Function changes the state of the RF.
+ *
+ * \param trx_state Given RF state
+ *
+ * \return none
+ */
+static void rf_if_change_trx_state(rf_trx_states_t trx_state)
+{
+  // XXX Lock claim apparently not required
+  rf_if_lock();
+  rf_if_write_register(TRX_STATE, trx_state);
+  /*Wait while not in desired state*/
+  rf_poll_trx_state_change(trx_state);
+  rf_if_unlock();
+}
+
+/*
+ * \brief Function enables the TX END interrupt
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_tx_end_interrupt(void)
+{
+  rf_if_set_bit(IRQ_MASK, TRX_END, TRX_END);
+}
+
+/*
+ * \brief Function enables the RX END interrupt
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_rx_end_interrupt(void)
+{
+  rf_if_set_bit(IRQ_MASK, TRX_END, TRX_END);
+}
+
+/*
+ * \brief Function enables the CCA ED interrupt
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_cca_ed_done_interrupt(void)
+{
+  rf_if_set_bit(IRQ_MASK, CCA_ED_DONE, CCA_ED_DONE);
+}
+
+/*
+ * \brief Function starts the CCA process
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_start_cca_process(void)
+{
+  rf_if_set_bit(PHY_CC_CCA, CCA_REQUEST, CCA_REQUEST);
+}
+
+/*
+ * \brief Function scales RSSI
+ *
+ * \param ed_level ED level read from chip
+ *
+ * \return appropriately scaled RSSI dBm
+ */
+static int8_t rf_if_scale_rssi(uint8_t ed_level)
+{
+  if (rf_part_num == PART_AT86RF212) {
+    /* Data sheet says to multiply by 1.03 - this is 1.03125, rounding down */
+    ed_level += ed_level >> 5;
+  }
+  return rf_rssi_base_val + ed_level;
+}
+
+/*
+ * \brief Function sets the RF channel field
+ *
+ * \param Given channel
+ *
+ * \return none
+ */
+static void rf_if_set_channel_register(uint8_t channel)
+{
+  rf_if_set_bit(PHY_CC_CCA, channel, 0x1f);
+}
+
+/*
+ * \brief Function enables RF irq pin interrupts in RF interface.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_enable_irq(void)
+{
+  rf->IRQ.enable_irq();
+}
+
+/*
+ * \brief Function disables RF irq pin interrupts in RF interface.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_disable_irq(void)
+{
+  rf->IRQ.disable_irq();
+}
+
+#ifdef MBED_CONF_RTOS_PRESENT
+static void rf_if_interrupt_handler(void)
+{
+    rf->irq_thread.signal_set(SIG_RADIO);
+}
+
+// Started during construction of rf, so variable
+// rf isn't set at the start. Uses 'this' instead.
+void RFBits::rf_if_irq_task(void)
+{
+    for (;;) {
+        osEvent event = irq_thread.signal_wait(0);
+        if (event.status != osEventSignal) {
+            continue;
+        }
+        rf_if_lock();
+        if (event.value.signals & SIG_RADIO) {
+            rf_if_irq_task_process_irq();
+        }
+        if (event.value.signals & SIG_TIMER_ACK) {
+            rf_ack_wait_timer_interrupt();
+        }
+        if (event.value.signals & SIG_TIMER_CCA) {
+            rf_cca_timer_interrupt();
+        }
+        if (event.value.signals & SIG_TIMER_CAL) {
+            rf_calibration_timer_interrupt();
+        }
+        rf_if_unlock();
+    }
+}
+
+static void rf_if_irq_task_process_irq(void)
+#else
+/*
+ * \brief Function is a RF interrupt vector. End of frame in RX and TX are handled here as well as CCA process interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_if_interrupt_handler(void)
+#endif
+{
+  uint8_t irq_status;
+
+  /*Read interrupt flag*/
+  irq_status = rf_if_read_register(IRQ_STATUS);
+
+  /*Disable interrupt on RF*/
+  rf_if_clear_bit(IRQ_MASK, irq_status);
+  /*RX start interrupt*/
+  if(irq_status & RX_START)
+  {
+  }
+  /*Address matching interrupt*/
+  if(irq_status & AMI)
+  {
+  }
+  if(irq_status & TRX_UR)
+  {
+  }
+  /*Frame end interrupt (RX and TX)*/
+  if(irq_status & TRX_END)
+  {
+    /*TX done interrupt*/
+    if(rf_if_read_trx_state() == PLL_ON || rf_if_read_trx_state() == TX_ARET_ON)
+    {
+      rf_handle_tx_end();
+    }
+    /*Frame received interrupt*/
+    else
+    {
+      rf_handle_rx_end();
+    }
+  }
+  if(irq_status & CCA_ED_DONE)
+  {
+    rf_handle_cca_ed_done();
+  }
+}
+
+/*
+ * \brief Function writes/read data in SPI interface
+ *
+ * \param out Output data
+ *
+ * \return Input data
+ */
+static uint8_t rf_if_spi_exchange(uint8_t out)
+{
+  uint8_t v;
+  v = rf->spi.write(out);
+  // t9 = t5 = 250ns, delay between LSB of last byte to next MSB or delay between LSB & SEL rising
+  // [SPI setup assumed slow enough to not need manual delay]
+  // delay_ns(250);
+  return v;
+}
+
+/*
+ * \brief Function sets given RF flag on.
+ *
+ * \param x Given RF flag
+ *
+ * \return none
+ */
+static void rf_flags_set(uint8_t x)
+{
+    rf_flags |= x;
+}
+
+/*
+ * \brief Function clears given RF flag on.
+ *
+ * \param x Given RF flag
+ *
+ * \return none
+ */
+static void rf_flags_clear(uint8_t x)
+{
+    rf_flags &= ~x;
+}
+
+/*
+ * \brief Function checks if given RF flag is on.
+ *
+ * \param x Given RF flag
+ *
+ * \return states of the given flags
+ */
+static uint8_t rf_flags_check(uint8_t x)
+{
+    return (rf_flags & x);
+}
+
+/*
+ * \brief Function clears all RF flags.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_flags_reset(void)
+{
+    rf_flags = 0;
+}
+
+/*
+ * \brief Function initialises and registers the RF driver.
+ *
+ * \param none
+ *
+ * \return rf_radio_driver_id Driver ID given by NET library
+ */
+static int8_t rf_device_register(const uint8_t *mac_addr)
+{
+    rf_trx_part_e radio_type;
+
+    rf_init();
+
+    radio_type = rf_radio_type_read();
+    if(radio_type != ATMEL_UNKNOW_DEV)
+    {
+        /*Set pointer to MAC address*/
+        device_driver.PHY_MAC = (uint8_t *)mac_addr;
+        device_driver.driver_description = (char*)"ATMEL_MAC";
+        //Create setup Used Radio chips
+        if(radio_type == ATMEL_AT86RF212)
+        {
+            device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
+        }
+        else
+        {
+            device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE;
+        }
+        device_driver.phy_channel_pages = phy_channel_pages;
+        /*Maximum size of payload is 127*/
+        device_driver.phy_MTU = 127;
+        /*No header in PHY*/
+        device_driver.phy_header_length = 0;
+        /*No tail in PHY*/
+        device_driver.phy_tail_length = 0;
+        /*Set address write function*/
+        device_driver.address_write = &rf_address_write;
+        /*Set RF extension function*/
+        device_driver.extension = &rf_extension;
+        /*Set RF state control function*/
+        device_driver.state_control = &rf_interface_state_control;
+        /*Set transmit function*/
+        device_driver.tx = &rf_start_cca;
+        /*NULLIFY rx and tx_done callbacks*/
+        device_driver.phy_rx_cb = NULL;
+        device_driver.phy_tx_done_cb = NULL;
+        /*Register device driver*/
+        rf_radio_driver_id = arm_net_phy_register(&device_driver);
+    }
+    return rf_radio_driver_id;
+}
+
+/*
+ * \brief Function unregisters the RF driver.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_device_unregister()
+{
+    if (rf_radio_driver_id >= 0) {
+        arm_net_phy_unregister(rf_radio_driver_id);
+        rf_radio_driver_id = -1;
+    }
+}
+
+/*
+ * \brief Enable frame buffer protection
+ *
+ * If protection is enabled, reception cannot start - the radio will
+ * not go into RX_BUSY or write into the frame buffer if in receive mode.
+ * Setting this won't abort an already-started reception.
+ * We can still write the frame buffer ourselves.
+ */
+static void rf_enable_static_frame_buffer_protection(void)
+{
+  if (!rf_flags_check(RFF_PROT)) {
+    /* This also writes RX_PDT_LEVEL to 0 - maximum RX sensitivity */
+    /* Would need to modify this function if messing with that */
+    rf_if_write_register(RX_SYN, RX_PDT_DIS);
+    rf_flags_set(RFF_PROT);
+  }
+}
+
+/*
+ * \brief Disable frame buffer protection
+ */
+static void rf_disable_static_frame_buffer_protection(void)
+{
+  if (rf_flags_check(RFF_PROT)) {
+    /* This also writes RX_PDT_LEVEL to 0 - maximum RX sensitivity */
+    /* Would need to modify this function if messing with that */
+    rf_if_write_register(RX_SYN, 0);
+    rf_flags_clear(RFF_PROT);
+  }
+}
+
+
+/*
+ * \brief Function is a call back for ACK wait timeout.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_interrupt(void)
+{
+    rf_if_lock();
+    expected_ack_sequence = -1;
+    /*Force PLL state*/
+    rf_if_change_trx_state(FORCE_PLL_ON);
+    rf_poll_trx_state_change(PLL_ON);
+    /*Start receiver in RX_AACK_ON state*/
+    rf_rx_mode = 0;
+    rf_flags_clear(RFF_RX);
+    rf_receive();
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function is a call back for calibration interval timer.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_calibration_timer_interrupt(void)
+{
+    /*Calibrate RF*/
+    rf_calibration_cb();
+    /*Start new calibration timeout*/
+    rf_calibration_timer_start(RF_CALIBRATION_INTERVAL);
+}
+
+/*
+ * \brief Function is a call back for cca interval timer.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_cca_timer_interrupt(void)
+{
+    /*Disable reception - locks against entering BUSY_RX and overwriting frame buffer*/
+    rf_enable_static_frame_buffer_protection();
+
+    if(rf_if_read_trx_state() == BUSY_RX_AACK)
+    {
+        /*Reception already started - re-enable reception and say CCA fail*/
+        rf_disable_static_frame_buffer_protection();
+        if(device_driver.phy_tx_done_cb){
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 0, 0);
+        }
+    }
+    else
+    {
+        /*Load the frame buffer with frame to transmit */
+        rf_if_write_frame_buffer(rf_tx_data, rf_tx_length);
+        /*Make sure we're in RX state to read channel (any way we could not be?)*/
+        rf_receive();
+        rf_flags_set(RFF_CCA);
+        /*Start CCA process*/
+        rf_if_enable_cca_ed_done_interrupt();
+        rf_if_start_cca_process();
+    }
+}
+
+/*
+ * \brief Function starts the ACK wait timeout.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_start(uint16_t slots)
+{
+    rf_if_ack_wait_timer_start(slots);
+}
+
+/*
+ * \brief Function starts the calibration interval.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_calibration_timer_start(uint32_t slots)
+{
+    rf_if_calibration_timer_start(slots);
+}
+
+/*
+ * \brief Function starts the CCA backoff.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_cca_timer_start(uint32_t slots)
+{
+    rf_if_cca_timer_start(slots);
+}
+
+/*
+ * \brief Function stops the CCA backoff.
+ *
+ * \return none
+ */
+static void rf_cca_timer_stop(void)
+{
+    rf_if_cca_timer_stop();
+}
+
+/*
+ * \brief Function stops the ACK wait timeout.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_stop(void)
+{
+    rf_if_ack_wait_timer_stop();
+}
+
+/*
+ * \brief Function writes various RF settings in startup.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_write_settings(void)
+{
+    rf_if_lock();
+    rf_if_write_rf_settings();
+    /*Set output power*/
+    rf_if_write_set_tx_power_register(radio_tx_power);
+    /*Initialise Antenna Diversity*/
+    if(rf_use_antenna_diversity)
+        rf_if_write_antenna_diversity_settings();
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function writes 16-bit address in RF address filter.
+ *
+ * \param short_address Given short address
+ *
+ * \return none
+ */
+static void rf_set_short_adr(uint8_t * short_address)
+{
+    rf_if_lock();
+    /*Wake up RF if sleeping*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_disable_slptr();
+        rf_poll_trx_state_change(TRX_OFF);
+    }
+    /*Write address filter registers*/
+    rf_if_write_short_addr_registers(short_address);
+    /*RF back to sleep*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_enable_slptr();
+    }
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function writes PAN Id in RF PAN Id filter.
+ *
+ * \param pan_id Given PAN Id
+ *
+ * \return none
+ */
+static void rf_set_pan_id(uint8_t *pan_id)
+{
+    rf_if_lock();
+    /*Wake up RF if sleeping*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_disable_slptr();
+        rf_poll_trx_state_change(TRX_OFF);
+    }
+    /*Write address filter registers*/
+    rf_if_write_pan_id_registers(pan_id);
+    /*RF back to sleep*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_enable_slptr();
+    }
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function writes 64-bit address in RF address filter.
+ *
+ * \param address Given 64-bit address
+ *
+ * \return none
+ */
+static void rf_set_address(uint8_t *address)
+{
+    rf_if_lock();
+    /*Wake up RF if sleeping*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_disable_slptr();
+        rf_poll_trx_state_change(TRX_OFF);
+    }
+    /*Write address filter registers*/
+    rf_if_write_ieee_addr_registers(address);
+    /*RF back to sleep*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_enable_slptr();
+    }
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function sets the RF channel.
+ *
+ * \param ch New channel
+ *
+ * \return none
+ */
+static void rf_channel_set(uint8_t ch)
+{
+    rf_if_lock();
+    rf_phy_channel = ch;
+    if(ch < 0x1f)
+        rf_if_set_channel_register(ch);
+    rf_if_unlock();
+}
+
+
+/*
+ * \brief Function initialises the radio driver and resets the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_init(void)
+{
+    /*Reset RF module*/
+    rf_if_reset_radio();
+
+    rf_if_lock();
+
+    /*Write RF settings*/
+    rf_write_settings();
+    /*Initialise PHY mode*/
+    rf_init_phy_mode();
+    /*Clear RF flags*/
+    rf_flags_reset();
+    /*Set RF in TRX OFF state*/
+    rf_if_change_trx_state(TRX_OFF);
+    /*Set RF in PLL_ON state*/
+    rf_if_change_trx_state(PLL_ON);
+    /*Start receiver*/
+    rf_receive();
+    /*Read randomness, and add to seed*/
+    randLIB_add_seed(rf_if_read_rnd());
+    /*Start RF calibration timer*/
+    rf_calibration_timer_start(RF_CALIBRATION_INTERVAL);
+
+    rf_if_unlock();
+}
+
+/**
+ * \brief Function gets called when MAC is setting radio off.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_off(void)
+{
+    if(rf_flags_check(RFF_ON))
+    {
+        rf_if_lock();
+        rf_cca_abort();
+        uint16_t while_counter = 0;
+        /*Wait while receiving*/
+        while(rf_if_read_trx_state() == BUSY_RX_AACK)
+        {
+            while_counter++;
+            if(while_counter == 0xffff)
+                break;
+        }
+        /*RF state change: RX_AACK_ON->PLL_ON->TRX_OFF->SLEEP*/
+        if(rf_if_read_trx_state() == RX_AACK_ON)
+        {
+            rf_if_change_trx_state(PLL_ON);
+        }
+        rf_if_change_trx_state(TRX_OFF);
+        rf_if_enable_slptr();
+
+        /*Disable Antenna Diversity*/
+        if(rf_use_antenna_diversity)
+            rf_if_disable_ant_div();
+        rf_if_unlock();
+    }
+
+    /*Clears all flags*/
+    rf_flags_reset();
+}
+
+/*
+ * \brief Function polls the RF state until it has changed to desired state.
+ *
+ * \param trx_state RF state
+ *
+ * \return none
+ */
+static void rf_poll_trx_state_change(rf_trx_states_t trx_state)
+{
+    uint16_t while_counter = 0;
+    // XXX lock apparently not needed
+    rf_if_lock();
+
+    if(trx_state != RF_TX_START)
+    {
+        if(trx_state == FORCE_PLL_ON)
+            trx_state = PLL_ON;
+        else if(trx_state == FORCE_TRX_OFF)
+            trx_state = TRX_OFF;
+
+        while(rf_if_read_trx_state() != trx_state)
+        {
+            while_counter++;
+            if(while_counter == 0x1ff)
+                break;
+        }
+    }
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO.
+ *
+ * \param data_ptr Pointer to TX data (excluding FCS)
+ * \param data_length Length of the TX data (excluding FCS)
+ * \param tx_handle Handle to transmission
+ * \return 0 Success
+ * \return -1 Busy
+ */
+static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol )
+{
+    (void)data_protocol;
+    rf_if_lock();
+    /*Check if transmitter is busy*/
+    if(rf_if_read_trx_state() == BUSY_RX_AACK || data_length > RF_MTU - 2)
+    {
+        rf_if_unlock();
+        /*Return busy*/
+        return -1;
+    }
+    else
+    {
+        expected_ack_sequence = -1;
+
+        /*Nanostack has a static TX buffer, which will remain valid until we*/
+        /*generate a callback, so we just note the pointer for reading later.*/
+        rf_tx_data = data_ptr;
+        rf_tx_length = data_length;
+        /*Start CCA timeout*/
+        rf_cca_timer_start(RF_CCA_BASE_BACKOFF + randLIB_get_random_in_range(0, RF_CCA_RANDOM_BACKOFF));
+        /*Store TX handle*/
+        mac_tx_handle = tx_handle;
+        rf_if_unlock();
+    }
+
+    /*Return success*/
+    return 0;
+}
+
+/*
+ * \brief Function aborts CCA process.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_cca_abort(void)
+{
+    rf_cca_timer_stop();
+    rf_flags_clear(RFF_CCA);
+    rf_disable_static_frame_buffer_protection();
+}
+
+/*
+ * \brief Function starts the transmission of the frame.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_start_tx(void)
+{
+    /*Only start transmitting from RX state*/
+    uint8_t trx_state = rf_if_read_trx_state();
+    if(trx_state != RX_AACK_ON)
+    {
+        rf_disable_static_frame_buffer_protection();
+        if(device_driver.phy_tx_done_cb){
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 0, 0);
+        }
+    }
+    else
+    {
+        /*RF state change: ->PLL_ON->RF_TX_START*/
+        rf_if_change_trx_state(FORCE_PLL_ON);
+        rf_flags_clear(RFF_RX);
+        /*Now we're out of receive mode, can release protection*/
+        rf_disable_static_frame_buffer_protection();
+        rf_if_enable_tx_end_interrupt();
+        rf_flags_set(RFF_TX);
+        rf_if_change_trx_state(RF_TX_START);
+    }
+}
+
+/*
+ * \brief Function sets the RF in RX state.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_receive(void)
+{
+    uint16_t while_counter = 0;
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_on();
+    }
+    /*If not yet in RX state set it*/
+    if(rf_flags_check(RFF_RX) == 0)
+    {
+        rf_if_lock();
+        /*Wait while receiving data*/
+        while(rf_if_read_trx_state() == BUSY_RX_AACK)
+        {
+            while_counter++;
+            if(while_counter == 0xffff)
+            {
+                break;
+            }
+        }
+
+        rf_if_change_trx_state(PLL_ON);
+
+        if((rf_mode == RF_MODE_SNIFFER) || (rf_mode == RF_MODE_ED))
+        {
+            rf_if_change_trx_state(RX_ON);
+        }
+        else
+        {
+            /*ACK is always received in promiscuous mode to bypass address filters*/
+            if(rf_rx_mode)
+            {
+                rf_rx_mode = 0;
+                rf_if_enable_promiscuous_mode();
+            }
+            else
+            {
+                rf_if_disable_promiscuous_mode();
+            }
+            rf_if_change_trx_state(RX_AACK_ON);
+        }
+        /*If calibration timer was unable to calibrate the RF, run calibration now*/
+        if(!rf_tuned)
+        {
+            /*Start calibration. This can be done in states TRX_OFF, PLL_ON or in any receive state*/
+            rf_if_calibration();
+            /*RF is tuned now*/
+            rf_tuned = 1;
+        }
+
+        rf_channel_set(rf_phy_channel);
+        rf_flags_set(RFF_RX);
+        // Don't receive packets when ED mode enabled
+        if (rf_mode != RF_MODE_ED)
+        {
+            rf_if_enable_rx_end_interrupt();
+        }
+        rf_if_unlock();
+    }
+}
+
+/*
+ * \brief Function calibrates the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_calibration_cb(void)
+{
+    /*clear tuned flag to start tuning in rf_receive*/
+    rf_tuned = 0;
+    /*If RF is in default receive state, start calibration*/
+    if(rf_if_read_trx_state() == RX_AACK_ON)
+    {
+        rf_if_lock();
+        /*Set RF in PLL_ON state*/
+        rf_if_change_trx_state(PLL_ON);
+        /*Set RF in TRX_OFF state to start PLL tuning*/
+        rf_if_change_trx_state(TRX_OFF);
+        /*Set RF in RX_ON state to calibrate*/
+        rf_if_change_trx_state(RX_ON);
+        /*Calibrate FTN*/
+        rf_if_calibration();
+        /*RF is tuned now*/
+        rf_tuned = 1;
+        /*Back to default receive state*/
+        rf_flags_clear(RFF_RX);
+        rf_receive();
+        rf_if_unlock();
+    }
+}
+
+/*
+ * \brief Function sets RF_ON flag when radio is powered.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_on(void)
+{
+    /*Set RFF_ON flag*/
+    if(rf_flags_check(RFF_ON) == 0)
+    {
+        rf_if_lock();
+        rf_flags_set(RFF_ON);
+        /*Enable Antenna diversity*/
+        if(rf_use_antenna_diversity)
+            /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/
+            rf_if_enable_ant_div();
+
+        /*Wake up from sleep state*/
+        rf_if_disable_slptr();
+        rf_poll_trx_state_change(TRX_OFF);
+        rf_if_unlock();
+    }
+}
+
+/*
+ * \brief Function handles the received ACK frame.
+ *
+ * \param seq_number Sequence number of received ACK
+ * \param data_pending Pending bit state in received ACK
+ *
+ * \return none
+ */
+static void rf_handle_ack(uint8_t seq_number, uint8_t data_pending)
+{
+    phy_link_tx_status_e phy_status;
+    rf_if_lock();
+    /*Received ACK sequence must be equal with transmitted packet sequence*/
+    if(expected_ack_sequence == seq_number)
+    {
+        rf_ack_wait_timer_stop();
+        expected_ack_sequence = -1;
+        /*When data pending bit in ACK frame is set, inform NET library*/
+        if(data_pending)
+            phy_status = PHY_LINK_TX_DONE_PENDING;
+        else
+            phy_status = PHY_LINK_TX_DONE;
+        /*Call PHY TX Done API*/
+        if(device_driver.phy_tx_done_cb){
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle,phy_status, 0, 0);
+        }
+    }
+    rf_if_unlock();
+}
+
+/*
+ * \brief Function is a call back for RX end interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_rx_end(void)
+{
+    /*Start receiver*/
+    rf_flags_clear(RFF_RX);
+    rf_receive();
+
+    /*Frame received interrupt*/
+    if(!rf_flags_check(RFF_RX)) {
+        return;
+    }
+
+    static uint8_t rf_buffer[RF_MTU];
+    uint8_t rf_lqi, rf_ed;
+    int8_t rf_rssi;
+    bool crc_good;
+
+    /*Read received packet*/
+    uint8_t len = rf_if_read_packet(rf_buffer, &rf_lqi, &rf_ed, &crc_good);
+    if (len < 5 || !crc_good) {
+        return;
+    }
+
+    /* Convert raw ED to dBm value (chip-dependent) */
+    rf_rssi = rf_if_scale_rssi(rf_ed);
+
+    /* Create a virtual LQI using received RSSI, forgetting actual HW LQI */
+    /* (should be done through PHY_EXTENSION_CONVERT_SIGNAL_INFO) */
+    rf_lqi = rf_scale_lqi(rf_rssi);
+
+    /*Handle received ACK*/
+    if((rf_buffer[0] & 0x07) == 0x02 && rf_mode != RF_MODE_SNIFFER)
+    {
+        /*Check if data is pending*/
+        bool pending = (rf_buffer[0] & 0x10);
+
+        /*Send sequence number in ACK handler*/
+        rf_handle_ack(rf_buffer[2], pending);
+    } else {
+        if( device_driver.phy_rx_cb ){
+            device_driver.phy_rx_cb(rf_buffer, len - 2, rf_lqi, rf_rssi, rf_radio_driver_id);
+        }
+    }
+}
+
+/*
+ * \brief Function is called when MAC is shutting down the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_shutdown(void)
+{
+    /*Call RF OFF*/
+    rf_off();
+}
+
+/*
+ * \brief Function is a call back for TX end interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_tx_end(void)
+{
+    rf_rx_mode = 0;
+    /*If ACK is needed for this transmission*/
+    if((rf_tx_data[0] & 0x20) && rf_flags_check(RFF_TX))
+    {
+        expected_ack_sequence = rf_tx_data[2];
+        rf_ack_wait_timer_start(rf_ack_wait_duration);
+        rf_rx_mode = 1;
+    }
+    rf_flags_clear(RFF_RX);
+    /*Start receiver*/
+    rf_receive();
+
+    /*Call PHY TX Done API*/
+    if(device_driver.phy_tx_done_cb){
+        device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 0, 0);
+    }
+}
+
+/*
+ * \brief Function is a call back for CCA ED done interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_cca_ed_done(void)
+{
+    if (!rf_flags_check(RFF_CCA)) {
+        return;
+    }
+    rf_flags_clear(RFF_CCA);
+    /*Check the result of CCA process*/
+    if(rf_if_check_cca())
+    {
+        rf_start_tx();
+    }
+    else
+    {
+        /*Re-enable reception*/
+        rf_disable_static_frame_buffer_protection();
+        /*Send CCA fail notification*/
+        if(device_driver.phy_tx_done_cb){
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 0, 0);
+        }
+    }
+}
+
+/*
+ * \brief Function returns the TX power variable.
+ *
+ * \param none
+ *
+ * \return radio_tx_power TX power variable
+ */
+MBED_UNUSED static uint8_t rf_tx_power_get(void)
+{
+  return radio_tx_power;
+}
+
+/*
+ * \brief Function enables the usage of Antenna diversity.
+ *
+ * \param none
+ *
+ * \return 0 Success
+ */
+MBED_UNUSED static int8_t rf_enable_antenna_diversity(void)
+{
+    int8_t ret_val = 0;
+    rf_use_antenna_diversity = 1;
+    return ret_val;
+}
+
+/*
+ * \brief Function gives the control of RF states to MAC.
+ *
+ * \param new_state RF state
+ * \param rf_channel RF channel
+ *
+ * \return 0 Success
+ */
+static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
+{
+    int8_t ret_val = 0;
+    switch (new_state)
+    {
+        /*Reset PHY driver and set to idle*/
+        case PHY_INTERFACE_RESET:
+            break;
+        /*Disable PHY Interface driver*/
+        case PHY_INTERFACE_DOWN:
+            rf_shutdown();
+            break;
+        /*Enable PHY Interface driver*/
+        case PHY_INTERFACE_UP:
+            rf_mode = RF_MODE_NORMAL;
+            rf_channel_set(rf_channel);
+            rf_receive();
+            rf_if_enable_irq();
+            break;
+        /*Enable wireless interface ED scan mode*/
+        case PHY_INTERFACE_RX_ENERGY_STATE:
+            rf_mode = RF_MODE_ED;
+            rf_channel_set(rf_channel);
+            rf_receive();
+            rf_if_disable_irq();
+            // Read status to clear pending flags.
+            rf_if_read_register(IRQ_STATUS);
+            // Must set interrupt mask to be able to read IRQ status. GPIO interrupt is disabled.
+            rf_if_enable_cca_ed_done_interrupt();
+            // ED can be initiated by writing arbitrary value to PHY_ED_LEVEL
+            rf_if_write_register(PHY_ED_LEVEL, 0xff);
+            break;
+        case PHY_INTERFACE_SNIFFER_STATE:             /**< Enable Sniffer state */
+            rf_mode = RF_MODE_SNIFFER;
+            rf_channel_set(rf_channel);
+            rf_flags_clear(RFF_RX);
+            rf_receive();
+            rf_if_enable_irq();
+            break;
+    }
+    return ret_val;
+}
+
+/*
+ * \brief Function controls the ACK pending, channel setting and energy detection.
+ *
+ * \param extension_type Type of control
+ * \param data_ptr Data from NET library
+ *
+ * \return 0 Success
+ */
+static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
+{
+    switch (extension_type)
+    {
+        /*Control MAC pending bit for Indirect data transmission*/
+        case PHY_EXTENSION_CTRL_PENDING_BIT:
+            if(*data_ptr)
+            {
+                rf_if_ack_pending_ctrl(1);
+            }
+            else
+            {
+                rf_if_ack_pending_ctrl(0);
+            }
+            break;
+        /*Return frame pending status*/
+        case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
+            *data_ptr = rf_if_last_acked_pending();
+            break;
+        /*Set channel*/
+        case PHY_EXTENSION_SET_CHANNEL:
+            break;
+        /*Read energy on the channel*/
+        case PHY_EXTENSION_READ_CHANNEL_ENERGY:
+            // End of the ED measurement is indicated by CCA_ED_DONE
+            while (!(rf_if_read_register(IRQ_STATUS) & CCA_ED_DONE));
+            // RF input power: RSSI base level + 1[db] * PHY_ED_LEVEL
+            *data_ptr = rf_sensitivity + rf_if_read_register(PHY_ED_LEVEL);
+            // Read status to clear pending flags.
+            rf_if_read_register(IRQ_STATUS);
+            // Next ED measurement is started, next PHY_EXTENSION_READ_CHANNEL_ENERGY call will return the result.
+            rf_if_write_register(PHY_ED_LEVEL, 0xff);
+            break;
+        /*Read status of the link*/
+        case PHY_EXTENSION_READ_LINK_STATUS:
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+/*
+ * \brief Function sets the addresses to RF address filters.
+ *
+ * \param address_type Type of address
+ * \param address_ptr Pointer to given address
+ *
+ * \return 0 Success
+ */
+static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
+{
+    int8_t ret_val = 0;
+    switch (address_type)
+    {
+        /*Set 48-bit address*/
+        case PHY_MAC_48BIT:
+            break;
+            /*Set 64-bit address*/
+        case PHY_MAC_64BIT:
+            rf_set_address(address_ptr);
+            break;
+        /*Set 16-bit address*/
+        case PHY_MAC_16BIT:
+            rf_set_short_adr(address_ptr);
+            break;
+        /*Set PAN Id*/
+        case PHY_MAC_PANID:
+            rf_set_pan_id(address_ptr);
+            break;
+    }
+    return ret_val;
+}
+
+/*
+ * \brief Function initialises the ACK wait time and returns the used PHY mode.
+ *
+ * \param none
+ *
+ * \return tmp Used PHY mode
+ */
+static void rf_init_phy_mode(void)
+{
+    uint8_t tmp = 0;
+    uint8_t part = rf_if_read_part_num();
+    /*Read used PHY Mode*/
+    tmp = rf_if_read_register(TRX_CTRL_2);
+    /*Set ACK wait time for used data rate*/
+    if(part == PART_AT86RF212)
+    {
+        if((tmp & 0x1f) == 0x00)
+        {
+            rf_sensitivity = -110;
+            rf_ack_wait_duration = 938;
+            tmp = BPSK_20;
+        }
+        else if((tmp & 0x1f) == 0x04)
+        {
+            rf_sensitivity = -108;
+            rf_ack_wait_duration = 469;
+            tmp = BPSK_40;
+        }
+        else if((tmp & 0x1f) == 0x14)
+        {
+            rf_sensitivity = -108;
+            rf_ack_wait_duration = 469;
+            tmp = BPSK_40_ALT;
+        }
+        else if((tmp & 0x1f) == 0x08)
+        {
+            rf_sensitivity = -101;
+            rf_ack_wait_duration = 50;
+            tmp = OQPSK_SIN_RC_100;
+        }
+        else if((tmp & 0x1f) == 0x09)
+        {
+            rf_sensitivity = -99;
+            rf_ack_wait_duration = 30;
+            tmp = OQPSK_SIN_RC_200;
+        }
+        else if((tmp & 0x1f) == 0x18)
+        {
+            rf_sensitivity = -102;
+            rf_ack_wait_duration = 50;
+            tmp = OQPSK_RC_100;
+        }
+        else if((tmp & 0x1f) == 0x19)
+        {
+            rf_sensitivity = -100;
+            rf_ack_wait_duration = 30;
+            tmp = OQPSK_RC_200;
+        }
+        else if((tmp & 0x1f) == 0x0c)
+        {
+            rf_sensitivity = -100;
+            rf_ack_wait_duration = 20;
+            tmp = OQPSK_SIN_250;
+        }
+        else if((tmp & 0x1f) == 0x0d)
+        {
+            rf_sensitivity = -98;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_SIN_500;
+        }
+        else if((tmp & 0x1f) == 0x0f)
+        {
+            rf_sensitivity = -98;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_SIN_500_ALT;
+        }
+        else if((tmp & 0x1f) == 0x1c)
+        {
+            rf_sensitivity = -101;
+            rf_ack_wait_duration = 20;
+            tmp = OQPSK_RC_250;
+        }
+        else if((tmp & 0x1f) == 0x1d)
+        {
+            rf_sensitivity = -99;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_RC_500;
+        }
+        else if((tmp & 0x1f) == 0x1f)
+        {
+            rf_sensitivity = -99;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_RC_500_ALT;
+        }
+        else if((tmp & 0x3f) == 0x2A)
+        {
+            rf_sensitivity = -91;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_SIN_RC_400_SCR_ON;
+        }
+        else if((tmp & 0x3f) == 0x0A)
+        {
+            rf_sensitivity = -91;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_SIN_RC_400_SCR_OFF;
+        }
+        else if((tmp & 0x3f) == 0x3A)
+        {
+            rf_sensitivity = -97;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_RC_400_SCR_ON;
+        }
+        else if((tmp & 0x3f) == 0x1A)
+        {
+            rf_sensitivity = -97;
+            rf_ack_wait_duration = 25;
+            tmp = OQPSK_RC_400_SCR_OFF;
+        }
+        else if((tmp & 0x3f) == 0x2E)
+        {
+            rf_sensitivity = -93;
+            rf_ack_wait_duration = 13;
+            tmp = OQPSK_SIN_1000_SCR_ON;
+        }
+        else if((tmp & 0x3f) == 0x0E)
+        {
+            rf_sensitivity = -93;
+            rf_ack_wait_duration = 13;
+            tmp = OQPSK_SIN_1000_SCR_OFF;
+        }
+        else if((tmp & 0x3f) == 0x3E)
+        {
+            rf_sensitivity = -95;
+            rf_ack_wait_duration = 13;
+            tmp = OQPSK_RC_1000_SCR_ON;
+        }
+        else if((tmp & 0x3f) == 0x1E)
+        {
+            rf_sensitivity = -95;
+            rf_ack_wait_duration = 13;
+            tmp = OQPSK_RC_1000_SCR_OFF;
+        }
+    }
+    else
+    {
+        rf_sensitivity = -101;
+        rf_ack_wait_duration = 20;
+    }
+    /*Board design might reduces the sensitivity*/
+    //rf_sensitivity += RF_SENSITIVITY_CALIBRATION;
+}
+
+
+static uint8_t rf_scale_lqi(int8_t rssi)
+{
+    uint8_t scaled_lqi;
+
+    /*rssi < RF sensitivity*/
+    if(rssi < rf_sensitivity)
+        scaled_lqi=0;
+    /*-91 dBm < rssi < -81 dBm (AT86RF233 XPro)*/
+    /*-90 dBm < rssi < -80 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 10))
+        scaled_lqi=31;
+    /*-81 dBm < rssi < -71 dBm (AT86RF233 XPro)*/
+    /*-80 dBm < rssi < -70 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 20))
+        scaled_lqi=207;
+    /*-71 dBm < rssi < -61 dBm (AT86RF233 XPro)*/
+    /*-70 dBm < rssi < -60 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 30))
+        scaled_lqi=255;
+    /*-61 dBm < rssi < -51 dBm (AT86RF233 XPro)*/
+    /*-60 dBm < rssi < -50 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 40))
+        scaled_lqi=255;
+    /*-51 dBm < rssi < -41 dBm (AT86RF233 XPro)*/
+    /*-50 dBm < rssi < -40 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 50))
+        scaled_lqi=255;
+    /*-41 dBm < rssi < -31 dBm (AT86RF233 XPro)*/
+    /*-40 dBm < rssi < -30 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 60))
+        scaled_lqi=255;
+    /*-31 dBm < rssi < -21 dBm (AT86RF233 XPro)*/
+    /*-30 dBm < rssi < -20 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 70))
+        scaled_lqi=255;
+    /*rssi > RF saturation*/
+    else if(rssi > (rf_sensitivity + 80))
+        scaled_lqi=111;
+    /*-21 dBm < rssi < -11 dBm (AT86RF233 XPro)*/
+    /*-20 dBm < rssi < -10 dBm (AT86RF212B XPro)*/
+    else
+        scaled_lqi=255;
+
+    return scaled_lqi;
+}
+
+NanostackRfPhyAtmel::NanostackRfPhyAtmel(PinName spi_mosi, PinName spi_miso,
+        PinName spi_sclk, PinName spi_cs,  PinName spi_rst, PinName spi_slp, PinName spi_irq,
+        PinName i2c_sda, PinName i2c_scl)
+    : _mac(i2c_sda, i2c_scl), _mac_addr(), _rf(NULL), _mac_set(false),
+      _spi_mosi(spi_mosi), _spi_miso(spi_miso), _spi_sclk(spi_sclk),
+      _spi_cs(spi_cs), _spi_rst(spi_rst), _spi_slp(spi_slp), _spi_irq(spi_irq)
+{
+    _rf = new RFBits(_spi_mosi, _spi_miso, _spi_sclk, _spi_cs, _spi_rst, _spi_slp, _spi_irq);
+}
+
+NanostackRfPhyAtmel::~NanostackRfPhyAtmel()
+{
+    delete _rf;
+}
+
+int8_t NanostackRfPhyAtmel::rf_register()
+{
+    if (NULL == _rf) {
+        return -1;
+    }
+
+    rf_if_lock();
+
+    if (rf != NULL) {
+        rf_if_unlock();
+        error("Multiple registrations of NanostackRfPhyAtmel not supported");
+        return -1;
+    }
+
+    // Read the mac address if it hasn't been set by a user
+    rf = _rf;
+    if (!_mac_set) {
+        int ret = _mac.read_eui64((void*)_mac_addr);
+        if (ret < 0) {
+            rf = NULL;
+            rf_if_unlock();
+            return -1;
+        }
+    }
+
+    int8_t radio_id = rf_device_register(_mac_addr);
+    if (radio_id < 0) {
+        rf = NULL;
+    }
+
+    rf_if_unlock();
+    return radio_id;
+}
+
+void NanostackRfPhyAtmel::rf_unregister()
+{
+    rf_if_lock();
+
+    if (NULL == rf) {
+        rf_if_unlock();
+        return;
+    }
+
+    rf_device_unregister();
+    rf = NULL;
+
+    rf_if_unlock();
+}
+
+void NanostackRfPhyAtmel::get_mac_address(uint8_t *mac)
+{
+    rf_if_lock();
+
+    if (NULL == rf) {
+        error("NanostackRfPhyAtmel Must be registered to read mac address");
+        rf_if_unlock();
+        return;
+    }
+    memcpy((void*)mac, (void*)_mac_addr, sizeof(_mac_addr));
+
+    rf_if_unlock();
+}
+
+void NanostackRfPhyAtmel::set_mac_address(uint8_t *mac)
+{
+    rf_if_lock();
+
+    if (NULL != rf) {
+        error("NanostackRfPhyAtmel cannot change mac address when running");
+        rf_if_unlock();
+        return;
+    }
+    memcpy((void*)_mac_addr, (void*)mac, sizeof(_mac_addr));
+    _mac_set = true;
+
+    rf_if_unlock();
+}
+
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/source/at24mac.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/source/at24mac.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016-2016 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "at24mac.h"
+
+/* Device addressing */
+#define AT24MAC_EEPROM_ADDRESS		(0x0A<<4)
+#define AT24MAC_RW_PROTECT_ADDRESS	(0x06<<4)
+#define AT24MAC_SERIAL_ADDRESS		(0x0B<<4)
+
+/* Known memory blocks */
+#define AT24MAC_SERIAL_OFFSET	(0x80)
+#define AT24MAC_EUI64_OFFSET	(0x98)
+#define AT24MAC_EUI48_OFFSET	(0x9A)
+
+#define SERIAL_LEN 16
+#define EUI64_LEN 8
+#define EUI48_LEN 6
+
+AT24Mac::I2CReset::I2CReset(PinName sda, PinName scl)
+{
+    mbed::DigitalInOut SDA(sda, PIN_OUTPUT, PullUp, 1);
+    mbed::DigitalInOut SCL(scl, PIN_OUTPUT, PullUp, 0);
+    //generate 9 clocks for worst-case scenario
+    for (int i = 0; i < 10; ++i) {
+        SCL = 1;
+        wait_us(5);
+        SCL = 0;
+        wait_us(5);
+    }
+    //generate a STOP condition
+    SDA = 0;
+    wait_us(5);
+    SCL = 1;
+    wait_us(5);
+    SDA = 1;
+    wait_us(5);
+}
+
+/*I2C needs to be reset before constructing the I2C object (in case I2C is stuck)
+  because they use the same pins, therefore i2c_reset has to be before _i2c
+  in the initializer list*/
+AT24Mac::AT24Mac(PinName sda, PinName scl) : i2c_reset(sda, scl), _i2c(sda, scl)
+{
+    // Do nothing
+}
+
+int AT24Mac::read_serial(void *buf)
+{
+    char offset = AT24MAC_SERIAL_OFFSET;
+    if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true))
+        return -1; //No ACK
+    return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char*)buf, SERIAL_LEN);
+}
+
+int AT24Mac::read_eui64(void *buf)
+{
+    char offset = AT24MAC_EUI64_OFFSET;
+    if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true))
+        return -1; //No ACK
+    return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char*)buf, EUI64_LEN);
+}
+
+int AT24Mac::read_eui48(void *buf)
+{
+    char offset = AT24MAC_EUI48_OFFSET;
+    if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true))
+        return -1; //No ACK
+    return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char*)buf, EUI48_LEN);
+}
diff -r 000000000000 -r 615f90842ce8 atmel-rf-driver/source/at24mac.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atmel-rf-driver/source/at24mac.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef AT24MAC_H
+#define AT24MAC_H
+
+#include "PinNames.h"
+#include "I2C.h"
+#include "drivers/DigitalInOut.h"
+#include "platform/mbed_wait_api.h"
+
+/*
+ * AT24MAC drivers.
+ *
+ * This is a EEPROM chip designed to contain factory programmed read-only EUI-64 or EUI-48,
+ * a 128bit serial number and some user programmable EEPROM.
+ *
+ * AT24MAC602 contains EUI-64, use read_eui64()
+ * AT24MAC402 contains EUI-64, use read_eui48()
+ *
+ * NOTE: You cannot use both EUI-64 and EUI-48. Chip contains only one of those.
+ */
+
+class AT24Mac {
+public:
+    AT24Mac(PinName sda, PinName scl);
+
+    /**
+     * Read unique serial number from chip.
+     * \param buf pointer to write serial number to. Must have space for 16 bytes.
+     * \return zero on success, negative number on failure
+     */
+    int read_serial(void *buf);
+
+    /**
+     * Read EUI-64 from chip.
+     * \param buf pointer to write EUI-64 to. Must have space for 8 bytes.
+     * \return zero on success, negative number on failure
+     */
+    int read_eui64(void *buf);
+
+    /**
+     * Read EUI-48 from chip.
+     * \param buf pointer to write EUI-48 to. Must have space for 6 bytes.
+     * \return zero on success, negative number on failure
+     */
+    int read_eui48(void *buf);
+
+private:
+    /*
+     * Dummy class to allow us to reset I2C before the I2C constructor is called in
+     * the initializer list of AT24Mac's constructor
+     */
+    class I2CReset {
+    public:
+        I2CReset(PinName sda, PinName scl);
+    };
+    I2CReset i2c_reset;
+    mbed::I2C _i2c;
+};
+
+#endif /* AT24MAC_H */
diff -r 000000000000 -r 615f90842ce8 easy-connect.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/easy-connect.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,186 @@
+#ifndef __EASY_CONNECT_H__
+#define __EASY_CONNECT_H__
+
+#include "mbed.h"
+
+#define ETHERNET        1
+#define WIFI_ESP8266    2
+#define MESH_LOWPAN_ND  3
+#define MESH_THREAD     4
+#define WIFI_ODIN       5
+#define WIFI_TYPEYD		6
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
+#include "ESP8266Interface.h"
+
+#ifdef MBED_CONF_APP_ESP8266_DEBUG
+ESP8266Interface wifi(MBED_CONF_APP_ESP8266_TX, MBED_CONF_APP_ESP8266_RX, MBED_CONF_APP_ESP8266_DEBUG);
+#else
+ESP8266Interface wifi(MBED_CONF_APP_ESP8266_TX, MBED_CONF_APP_ESP8266_RX);
+#endif
+
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
+#include "OdinWiFiInterface.h"
+OdinWiFiInterface wifi;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+#include "EthernetInterface.h"
+EthernetInterface eth;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
+#define MESH
+#include "NanostackInterface.h"
+LoWPANNDInterface mesh;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
+#define MESH
+#include "NanostackInterface.h"
+ThreadInterface mesh;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_TYPEYD
+#include "TypeYDPins.h"
+#include "TypeYDInterface.h"
+TypeYDInterface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX, MBED_CONF_APP_WIFI_CTS, MBED_CONF_APP_WIFI_RTS,
+    MBED_CONF_APP_WIFI_RESET, NC, MBED_CONF_APP_WIFI_BAUD);
+#else
+#error "No connectivity method chosen. Please add 'config.network-interfaces.value' to your mbed_app.json (see README.md for more information)."
+#endif
+
+#if defined(MESH)
+#if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
+#include "NanostackRfPhyAtmel.h"
+NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
+                           ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
+#include "NanostackRfPhyMcr20a.h"
+NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == SPIRIT1
+#include "NanostackRfPhySpirit1.h"
+NanostackRfPhySpirit1 rf_phy(SPIRIT1_SPI_MOSI, SPIRIT1_SPI_MISO, SPIRIT1_SPI_SCLK,
+			     SPIRIT1_DEV_IRQ, SPIRIT1_DEV_CS, SPIRIT1_DEV_SDN, SPIRIT1_BRD_LED);
+#endif //MBED_CONF_APP_RADIO_TYPE
+#endif //MESH
+
+#ifndef MESH
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coap://api.connector.mbed.com:5684"
+#else
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
+#endif
+
+#ifdef MBED_CONF_APP_ESP8266_SSID
+#define MBED_CONF_APP_WIFI_SSID MBED_CONF_APP_ESP8266_SSID
+#endif
+
+#ifdef MBED_CONF_APP_ESP8266_PASSWORD
+#define MBED_CONF_APP_WIFI_PASSWORD MBED_CONF_APP_ESP8266_PASSWORD
+#endif
+
+/* \brief print_MAC - print_MAC  - helper function to print out MAC address
+ * in: network_interface - pointer to network i/f
+ *     bool log-messages   print out logs or not
+ * MAC address is print, if it can be acquired & log_messages is true.
+ *
+ */
+void print_MAC(NetworkInterface* network_interface, bool log_messages) {
+    const char *mac_addr = network_interface->get_mac_address();
+    if (mac_addr == NULL) {
+        if (log_messages) {
+            printf("[EasyConnect] ERROR - No MAC address\n");
+        }
+        return;
+    }
+    if (log_messages) {
+        printf("[EasyConnect] MAC address %s\n", mac_addr);
+    }
+}
+
+
+/* \brief easy_connect - easy_connect function to connect the pre-defined network bearer,
+ *                       config done via mbed_app.json (see README.md for details).
+ * IN: bool log_messages  print out diagnostics or not.
+ *
+ */
+NetworkInterface* easy_connect(bool log_messages = false) {
+    NetworkInterface* network_interface = 0;
+    int connect_success = -1;
+    /// This should be removed once mbedOS supports proper dual-stack
+#if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
+    printf("[EasyConnect] IPv6 mode\n");
+#else
+    printf("[EasyConnect] IPv4 mode\n");
+#endif
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
+    if (log_messages) {
+        printf("[EasyConnect] Using WiFi (ESP8266) \n");
+        printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+    }
+    network_interface = &wifi;
+    connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
+    if (log_messages) {
+        printf("[EasyConnect] Using WiFi (ODIN) \n");
+        printf("[EasyConnect] Connecting to WiFi %s\n", MBED_CONF_APP_WIFI_SSID);
+    }
+    network_interface = &wifi;
+    connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+    if (log_messages) {
+        printf("[EasyConnect] Using Ethernet\n");
+    }
+    network_interface = &eth;
+    connect_success = eth.connect();
+#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_TYPEYD
+    if (log_messages) {
+        printf("[EasyConnect] Using Murata Type-YD wifi\n");
+    }
+    if (wifi.init() == 0) {
+        unsigned char *ver = (unsigned char*)malloc(32);
+        if (ver != NULL) {
+            if (wifi.getFWVersion(ver, 32) == 0) {
+                printf("[EasyConnect] Type-YD FW version : %s\n", ver);
+            }
+            else {
+                printf("[EasyConnect] Type-YD FW version : failed\n");
+            }
+        }
+        connect_success = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
+        network_interface = &wifi;
+    }
+    else if(log_messages) {
+        printf("[EasyConnect] Init error\n");
+    }
+#endif
+#ifdef MESH
+    if (log_messages) {
+        printf("[EasyConnect] Using Mesh\n");
+        printf("[EasyConnect] Connecting to Mesh..\n");
+    }
+    network_interface = &mesh;
+    mesh.initialize(&rf_phy);
+    connect_success = mesh.connect();
+#endif
+    if(connect_success == 0) {
+        if (log_messages) {
+            printf("[EasyConnect] Connected to Network successfully\n");
+            print_MAC(network_interface, log_messages);
+        }
+    } else {
+        if (log_messages) {
+            print_MAC(network_interface, log_messages);
+            printf("[EasyConnect] Connection to Network Failed %d!\n", connect_success);
+        }
+        return NULL;
+    }
+    const char *ip_addr  = network_interface->get_ip_address();
+    if (ip_addr == NULL) {
+        if (log_messages) {
+            printf("[EasyConnect] ERROR - No IP address\n");
+        }
+        return NULL;
+    }
+    if (log_messages) {
+        printf("[EasyConnect] IP address %s\n", ip_addr);
+    }
+    return network_interface;
+}
+
+#endif // __EASY_CONNECT_H__
diff -r 000000000000 -r 615f90842ce8 esp8266-driver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/esp8266-driver/#918caa01b4cdd3e798ac593b14687b9a94974074
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+918caa01b4cdd3e798ac593b14687b9a94974074
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/ORIG_HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/ORIG_HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+cac4d0d8f97745fe9a613b705b406646aeacc3e2
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/config	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/ARMmbed/esp8266-driver/
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/description
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/description	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/applypatch-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/applypatch-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/post-update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/post-update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/pre-applypatch.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/pre-applypatch.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/pre-commit.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/pre-commit.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/pre-rebase.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/pre-rebase.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/usr/bin/perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
+
+DOC_END
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/prepare-commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/prepare-commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /usr/bin/perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/hooks/update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/hooks/update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/index
Binary file esp8266-driver/.git/index has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/info/exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/info/exclude	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,26 @@
+.hg
+.git
+.svn
+.CVS
+.cvs
+*.orig
+.build
+.export
+.msub
+.meta
+.ctags*
+*.uvproj
+*.uvopt
+*.project
+*.cproject
+*.launch
+*.ewp
+*.eww
+Makefile
+Debug
+*.htm
+*.settings
+mbed_settings.py
+*.py[cod]
+# subrepo ignores
+ESP8266/ATParser
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/logs/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/logs/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2 @@
+0000000000000000000000000000000000000000 cac4d0d8f97745fe9a613b705b406646aeacc3e2 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209871 +0000	clone: from https://github.com/ARMmbed/esp8266-driver/
+cac4d0d8f97745fe9a613b705b406646aeacc3e2 918caa01b4cdd3e798ac593b14687b9a94974074 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209872 +0000	checkout: moving from master to 918caa01b4cdd3e798ac593b14687b9a94974074
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/logs/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/logs/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 cac4d0d8f97745fe9a613b705b406646aeacc3e2 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209871 +0000	clone: from https://github.com/ARMmbed/esp8266-driver/
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/logs/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/logs/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 cac4d0d8f97745fe9a613b705b406646aeacc3e2 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209871 +0000	clone: from https://github.com/ARMmbed/esp8266-driver/
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.idx
Binary file esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.idx has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.pack
Binary file esp8266-driver/.git/objects/pack/pack-b0666ed22aa27ecc7ede0ad1584fd2c44b4eb885.pack has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/packed-refs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/packed-refs	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,13 @@
+# pack-refs with: peeled 
+4ed87bf7fe37d5ba0de6c4e78868f604a82f8ecb refs/remotes/origin/firmware-0.2
+e47620ee6560c710adba1067e8e52937c4eacf3c refs/remotes/origin/firmware-2.0
+1ae21460e1c87bef97246f6221c104cf663c38d9 refs/remotes/origin/g-connect-retries
+2da720a291eb5b419fa2d569e8a5c056719dccdd refs/remotes/origin/g-remove-quotes
+6081f72409ab93d670d9f7c30e1bdebb39ae8ef5 refs/remotes/origin/g-testing-cleanup
+63cefc73abddc2637cafb0b5785bc2ef4b8ac280 refs/remotes/origin/imsherlock
+cac4d0d8f97745fe9a613b705b406646aeacc3e2 refs/remotes/origin/master
+d48a1b10b59a136a78b10e8625f8b3cff82670c9 refs/remotes/origin/new_at
+a38dbbaf66265199af60050cabc6618c4b530edc refs/remotes/origin/testing
+450cc128865ffb90b5cbfe5af193621644024fa7 refs/tags/v1.0
+29d63ae2ee0a233e2fbd9577cdddc7661bb783d1 refs/tags/v1.1
+4ed87bf7fe37d5ba0de6c4e78868f604a82f8ecb refs/tags/v1.2
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+cac4d0d8f97745fe9a613b705b406646aeacc3e2
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.git/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.git/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/.msub
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/.msub	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ESP8266/ATParser = https://github.com/ARMmbed/ATParser/#1:269f14532b98442669c50383782cbce1c67aced5
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/ATParser/#269f14532b98442669c50383782cbce1c67aced5
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/heads/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/ORIG_HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/ORIG_HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+269f14532b98442669c50383782cbce1c67aced5
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/config	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/ARMmbed/ATParser/
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/description
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/description	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/applypatch-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/applypatch-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/post-update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/post-update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/pre-applypatch.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/pre-applypatch.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/pre-commit.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/pre-commit.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/pre-rebase.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/pre-rebase.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/usr/bin/perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
+
+DOC_END
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/prepare-commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/prepare-commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /usr/bin/perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/hooks/update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/hooks/update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/index
Binary file esp8266-driver/ESP8266/ATParser/.git/index has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/info/exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/info/exclude	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,25 @@
+.hg
+.git
+.svn
+.CVS
+.cvs
+*.orig
+.build
+.export
+.msub
+.meta
+.ctags*
+*.uvproj
+*.uvopt
+*.project
+*.cproject
+*.launch
+*.ewp
+*.eww
+Makefile
+Debug
+*.htm
+*.settings
+mbed_settings.py
+*.py[cod]
+# subrepo ignores
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/logs/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/logs/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 269f14532b98442669c50383782cbce1c67aced5 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209882 +0000	clone: from https://github.com/ARMmbed/ATParser/
+269f14532b98442669c50383782cbce1c67aced5 269f14532b98442669c50383782cbce1c67aced5 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209883 +0000	checkout: moving from master to 269f14532b98442669c50383782cbce1c67aced5
+269f14532b98442669c50383782cbce1c67aced5 269f14532b98442669c50383782cbce1c67aced5 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209883 +0000	checkout: moving from 269f14532b98442669c50383782cbce1c67aced5 to master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/logs/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/logs/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 269f14532b98442669c50383782cbce1c67aced5 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209882 +0000	clone: from https://github.com/ARMmbed/ATParser/
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/logs/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/logs/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 269f14532b98442669c50383782cbce1c67aced5 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209882 +0000	clone: from https://github.com/ARMmbed/ATParser/
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/08/2f11ce298302a41ff877eed55ec226b944c24d
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/08/2f11ce298302a41ff877eed55ec226b944c24d has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/26/9f14532b98442669c50383782cbce1c67aced5
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/26/9f14532b98442669c50383782cbce1c67aced5 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/27/80390d5b3a7ed7a95478fc61b1a8632b843d1b
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/27/80390d5b3a7ed7a95478fc61b1a8632b843d1b has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/3b/fc95eb3c81fe98d7792e82608699e566f97603
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/objects/3b/fc95eb3c81fe98d7792e82608699e566f97603	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+xŽ]
+Â0„}Î)ö–4ÿ=€Ož`³ÝR¡1’¦x}CàÃÀÌÀ7•œ_
”v§V™!IÎ?i½ö¬¬Òœ<Qì6yžäL³f¬üóh¬V)c”s‘¬ÔAû (}‰'+poK©ðĊ<°n\Ž0á†5TòF­r
+ÎÒJ)zÛ/6þ÷u-_ظuÕ®pŸÄMIÔ
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/45/c2c9504f680cc5f6b1624cd262117036a7a774
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/45/c2c9504f680cc5f6b1624cd262117036a7a774 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/4d/677496a85bcdfd5a2d8bd5260f36d92bec09a5
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/4d/677496a85bcdfd5a2d8bd5260f36d92bec09a5 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/52/f9e7d0c92be3026ed8e2d929f5a2f3af5c7216
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/52/f9e7d0c92be3026ed8e2d929f5a2f3af5c7216 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/6c/1e45c98871f7bf381fb2c43262ed9a05ebe1a9
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/6c/1e45c98871f7bf381fb2c43262ed9a05ebe1a9 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/7d/0e42380917cbd4e2b474ba5771a7e15215e74c
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/7d/0e42380917cbd4e2b474ba5771a7e15215e74c has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/80/0d8517da4d091eb52094a1cac0a66903aed59a
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/80/0d8517da4d091eb52094a1cac0a66903aed59a has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/84/0c6747d369737e2523eb7cc9e25b7ed0fcf3ee
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/84/0c6747d369737e2523eb7cc9e25b7ed0fcf3ee has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/85/cf37770993beecac1e4d1b9dd5fcb3d03acee5
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/85/cf37770993beecac1e4d1b9dd5fcb3d03acee5 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/93/e4cb7ebd99ce690370a168ac831cacea4034a9
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/93/e4cb7ebd99ce690370a168ac831cacea4034a9 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/98/76baf6df887b76b6cb5da0a2e9bec41146001b
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/98/76baf6df887b76b6cb5da0a2e9bec41146001b has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/ac/0e4a88ca41a9de0f9d03f1d6b75ac2ba0b4ccc
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/ac/0e4a88ca41a9de0f9d03f1d6b75ac2ba0b4ccc has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/e2/3cc82f00dee6d8a91d5fd2bbdf6f4b548a0ffe
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/e2/3cc82f00dee6d8a91d5fd2bbdf6f4b548a0ffe has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/objects/f3/e3d6d5476b159f82b07d3dec0220e1047bd9b0
Binary file esp8266-driver/ESP8266/ATParser/.git/objects/f3/e3d6d5476b159f82b07d3dec0220e1047bd9b0 has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/packed-refs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/packed-refs	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+# pack-refs with: peeled 
+3bfc95eb3c81fe98d7792e82608699e566f97603 refs/remotes/origin/baud
+269f14532b98442669c50383782cbce1c67aced5 refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+269f14532b98442669c50383782cbce1c67aced5
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/.git/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/.git/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/ATParser.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/ATParser.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,333 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+
+#include "ATParser.h"
+#include "mbed_debug.h"
+
+
+// getc/putc handling with timeouts
+int ATParser::putc(char c)
+{
+    Timer timer;
+    timer.start();
+
+    while (true) {
+        if (_serial->writeable()) {
+            return _serial->putc(c);
+        }
+        if (timer.read_ms() > _timeout) {
+            return -1;
+        }
+    }
+}
+
+int ATParser::getc()
+{
+    Timer timer;
+    timer.start();
+
+    while (true) {
+        if (_serial->readable()) {
+            return _serial->getc();
+        }
+        if (timer.read_ms() > _timeout) {
+            return -1;
+        }
+    }
+}
+
+void ATParser::flush()
+{
+    while (_serial->readable()) {
+        _serial->getc();
+    }
+}
+
+
+// read/write handling with timeouts
+int ATParser::write(const char *data, int size)
+{
+    int i = 0;
+    for ( ; i < size; i++) {
+        if (putc(data[i]) < 0) {
+            return -1;
+        }
+    }
+    return i;
+}
+
+int ATParser::read(char *data, int size)
+{
+    int i = 0;
+    for ( ; i < size; i++) {
+        int c = getc();
+        if (c < 0) {
+            return -1;
+        }
+        data[i] = c;
+    }
+    return i;
+}
+
+
+// printf/scanf handling
+int ATParser::vprintf(const char *format, va_list args)
+{
+    if (vsprintf(_buffer, format, args) < 0) {
+        return false;
+    }
+    int i = 0;
+    for ( ; _buffer[i]; i++) {
+        if (putc(_buffer[i]) < 0) {
+            return -1;
+        }
+    }
+    return i;
+}
+
+int ATParser::vscanf(const char *format, va_list args)
+{
+    // Since format is const, we need to copy it into our buffer to
+    // add the line's null terminator and clobber value-matches with asterisks.
+    //
+    // We just use the beginning of the buffer to avoid unnecessary allocations.
+    int i = 0;
+    int offset = 0;
+
+    while (format[i]) {
+        if (format[i] == '%' && format[i+1] != '%' && format[i+1] != '*') {
+            _buffer[offset++] = '%';
+            _buffer[offset++] = '*';
+            i++;
+        } else {
+            _buffer[offset++] = format[i++];
+        }
+    }
+
+    // Scanf has very poor support for catching errors
+    // fortunately, we can abuse the %n specifier to determine
+    // if the entire string was matched.
+    _buffer[offset++] = '%';
+    _buffer[offset++] = 'n';
+    _buffer[offset++] = 0;
+
+    // To workaround scanf's lack of error reporting, we actually
+    // make two passes. One checks the validity with the modified
+    // format string that only stores the matched characters (%n).
+    // The other reads in the actual matched values.
+    //
+    // We keep trying the match until we succeed or some other error
+    // derails us.
+    int j = 0;
+
+    while (true) {
+        // Ran out of space
+        if (j+1 >= _buffer_size - offset) {
+            return false;
+        }
+        // Recieve next character
+        int c = getc();
+        if (c < 0) {
+            return -1;
+        }
+        _buffer[offset + j++] = c;
+        _buffer[offset + j] = 0;
+
+        // Check for match
+        int count = -1;
+        sscanf(_buffer+offset, _buffer, &count);
+
+        // We only succeed if all characters in the response are matched
+        if (count == j) {
+            // Store the found results
+            vsscanf(_buffer+offset, format, args);
+            return j;
+        }
+    }
+}
+
+
+// Command parsing with line handling
+bool ATParser::vsend(const char *command, va_list args)
+{
+    // Create and send command
+    if (vsprintf(_buffer, command, args) < 0) {
+        return false;
+    }
+    for (int i = 0; _buffer[i]; i++) {
+        if (putc(_buffer[i]) < 0) {
+            return false;
+        }
+    }
+
+    // Finish with newline
+    for (int i = 0; _delimiter[i]; i++) {
+        if (putc(_delimiter[i]) < 0) {
+            return false;
+        }
+    }
+
+    debug_if(dbg_on, "AT> %s\r\n", _buffer);
+    return true;
+}
+
+bool ATParser::vrecv(const char *response, va_list args)
+{
+    // Iterate through each line in the expected response
+    while (response[0]) {
+        // Since response is const, we need to copy it into our buffer to
+        // add the line's null terminator and clobber value-matches with asterisks.
+        //
+        // We just use the beginning of the buffer to avoid unnecessary allocations.
+        int i = 0;
+        int offset = 0;
+
+        while (response[i]) {
+            if (memcmp(&response[i+1-_delim_size], _delimiter, _delim_size) == 0) {
+                i++;
+                break;
+            } else if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') {
+                _buffer[offset++] = '%';
+                _buffer[offset++] = '*';
+                i++;
+            } else {
+                _buffer[offset++] = response[i++];
+            }
+        }
+
+        // Scanf has very poor support for catching errors
+        // fortunately, we can abuse the %n specifier to determine
+        // if the entire string was matched.
+        _buffer[offset++] = '%';
+        _buffer[offset++] = 'n';
+        _buffer[offset++] = 0;
+
+        // To workaround scanf's lack of error reporting, we actually
+        // make two passes. One checks the validity with the modified
+        // format string that only stores the matched characters (%n).
+        // The other reads in the actual matched values.
+        //
+        // We keep trying the match until we succeed or some other error
+        // derails us.
+        int j = 0;
+
+        while (true) {
+            // Recieve next character
+            int c = getc();
+            if (c < 0) {
+                return false;
+            }
+            _buffer[offset + j++] = c;
+            _buffer[offset + j] = 0;
+
+            // Check for oob data
+            for (int k = 0; k < _oobs.size(); k++) {
+                if (j == _oobs[k].len && memcmp(
+                        _oobs[k].prefix, _buffer+offset, _oobs[k].len) == 0) {
+                    debug_if(dbg_on, "AT! %s\r\n", _oobs[k].prefix);
+                    _oobs[k].cb();
+
+                    // oob may have corrupted non-reentrant buffer,
+                    // so we need to set it up again
+                    return vrecv(response, args);
+                }
+            }
+
+            // Check for match
+            int count = -1;
+            sscanf(_buffer+offset, _buffer, &count);
+
+            // We only succeed if all characters in the response are matched
+            if (count == j) {
+                debug_if(dbg_on, "AT= %s\r\n", _buffer+offset);
+                // Reuse the front end of the buffer
+                memcpy(_buffer, response, i);
+                _buffer[i] = 0;
+
+                // Store the found results
+                vsscanf(_buffer+offset, _buffer, args);
+
+                // Jump to next line and continue parsing
+                response += i;
+                break;
+            }
+
+            // Clear the buffer when we hit a newline or ran out of space
+            // running out of space usually means we ran into binary data
+            if (j+1 >= _buffer_size - offset ||
+                strcmp(&_buffer[offset + j-_delim_size], _delimiter) == 0) {
+
+                debug_if(dbg_on, "AT< %s", _buffer+offset);
+                j = 0;
+            }
+        }
+    }
+
+    return true;
+}
+
+
+// Mapping to vararg functions
+int ATParser::printf(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    int res = vprintf(format, args);
+    va_end(args);
+    return res;
+}
+
+int ATParser::scanf(const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    int res = vscanf(format, args);
+    va_end(args);
+    return res;
+}
+
+bool ATParser::send(const char *command, ...)
+{
+    va_list args;
+    va_start(args, command);
+    bool res = vsend(command, args);
+    va_end(args);
+    return res;
+}
+
+bool ATParser::recv(const char *response, ...)
+{
+    va_list args;
+    va_start(args, response);
+    bool res = vrecv(response, args);
+    va_end(args);
+    return res;
+}
+
+
+// oob registration
+void ATParser::oob(const char *prefix, Callback<void()> cb)
+{
+    struct oob oob;
+    oob.len = strlen(prefix);
+    oob.prefix = prefix;
+    oob.cb = cb;
+    _oobs.push_back(oob);
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/ATParser.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/ATParser.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,234 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+#ifndef AT_PARSER_H
+#define AT_PARSER_H
+
+#include "mbed.h"
+#include <cstdarg>
+#include <vector>
+#include "BufferedSerial.h"
+#include "Callback.h"
+
+
+/**
+* Parser class for parsing AT commands
+*
+* Here are some examples:
+* @code
+* ATParser at = ATParser(serial, "\r\n");
+* int value;
+* char buffer[100];
+*
+* at.send("AT") && at.recv("OK");
+* at.send("AT+CWMODE=%d", 3) && at.recv("OK");
+* at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
+* at.recv("+IPD,%d:", &value);
+* at.read(buffer, value);
+* at.recv("OK");
+* @endcode
+*/
+class ATParser
+{
+private:
+    // Serial information
+    BufferedSerial *_serial;
+    int _buffer_size;
+    char *_buffer;
+    int _timeout;
+
+    // Parsing information
+    const char *_delimiter;
+    int _delim_size;
+    bool dbg_on;
+
+    struct oob {
+        unsigned len;
+        const char *prefix;
+        mbed::Callback<void()> cb;
+    };
+    std::vector<oob> _oobs;
+
+public:
+    /**
+    * Constructor
+    *
+    * @param serial serial interface to use for AT commands
+    * @param buffer_size size of internal buffer for transaction
+    * @param timeout timeout of the connection
+    * @param delimiter string of characters to use as line delimiters
+    */
+    ATParser(BufferedSerial &serial, const char *delimiter = "\r\n", int buffer_size = 256, int timeout = 8000, bool debug = false) :
+        _serial(&serial),
+        _buffer_size(buffer_size) {
+        _buffer = new char[buffer_size];
+        setTimeout(timeout);
+        setDelimiter(delimiter);
+        debugOn(debug);
+    }
+
+    /**
+    * Destructor
+    */
+    ~ATParser() {
+        delete [] _buffer;
+    }
+
+    /**
+    * Allows timeout to be changed between commands
+    *
+    * @param timeout timeout of the connection
+    */
+    void setTimeout(int timeout) {
+        _timeout = timeout;
+    }
+
+    /**
+    * Sets string of characters to use as line delimiters
+    *
+    * @param delimiter string of characters to use as line delimiters
+    */
+    void setDelimiter(const char *delimiter) {
+        _delimiter = delimiter;
+        _delim_size = strlen(delimiter);
+    }
+    
+    /**
+    * Allows echo to be on or off
+    *
+    * @param echo 1 for echo and 0 turns it off
+    */
+    void debugOn(uint8_t on) {
+        dbg_on = (on) ? 1 : 0;
+    }
+
+    /**
+    * Sends an AT command
+    *
+    * Sends a formatted command using printf style formatting
+    * @see ::printf
+    *
+    * @param command printf-like format string of command to send which
+    *                is appended with the specified delimiter
+    * @param ... all printf-like arguments to insert into command
+    * @return true only if command is successfully sent
+    */
+    bool send(const char *command, ...);
+    bool vsend(const char *command, va_list args);
+
+    /**
+    * Recieve an AT response
+    *
+    * Recieves a formatted response using scanf style formatting
+    * @see ::scanf
+    *
+    * Responses are parsed line at a time using the specified delimiter.
+    * Any recieved data that does not match the response is ignored until
+    * a timeout occurs.
+    *
+    * @param response scanf-like format string of response to expect
+    * @param ... all scanf-like arguments to extract from response
+    * @return true only if response is successfully matched
+    */
+    bool recv(const char *response, ...);
+    bool vrecv(const char *response, va_list args);
+
+    /**
+    * Write a single byte to the underlying stream
+    *
+    * @param c The byte to write
+    * @return The byte that was written or -1 during a timeout
+    */
+    int putc(char c);
+
+    /**
+    * Get a single byte from the underlying stream
+    *
+    * @return The byte that was read or -1 during a timeout
+    */
+    int getc();
+
+    /**
+    * Write an array of bytes to the underlying stream
+    *
+    * @param data the array of bytes to write
+    * @param size number of bytes to write
+    * @return number of bytes written or -1 on failure
+    */
+    int write(const char *data, int size);
+
+    /**
+    * Read an array of bytes from the underlying stream
+    *
+    * @param data the destination for the read bytes
+    * @param size number of bytes to read
+    * @return number of bytes read or -1 on failure
+    */
+    int read(char *data, int size);
+
+    /**
+    * Direct printf to underlying stream
+    * @see ::printf
+    *
+    * @param format format string to pass to printf
+    * @param ... arguments to printf
+    * @return number of bytes written or -1 on failure
+    */
+    int printf(const char *format, ...);
+    int vprintf(const char *format, va_list args);
+
+    /**
+    * Direct scanf on underlying stream
+    * @see ::scanf
+    *
+    * @param format format string to pass to scanf
+    * @param ... arguments to scanf
+    * @return number of bytes read or -1 on failure
+    */
+    int scanf(const char *format, ...);
+    int vscanf(const char *format, va_list args);
+
+    /**
+    * Attach a callback for out-of-band data
+    * 
+    * @param prefix string on when to initiate callback
+    * @param func callback to call when string is read
+    * @note out-of-band data is only processed during a scanf call
+    */
+    void oob(const char *prefix, mbed::Callback<void()> func);
+
+    /**
+    * Attach a callback for out-of-band data
+    *
+    * @param prefix string on when to initiate callback
+    * @param obj pointer to object to call member function on
+    * @param method callback to call when string is read
+    * @note out-of-band data is only processed during a scanf call
+    */
+    template <typename T, typename M>
+    void oob(const char *prefix, T *obj, M method) {
+        return oob(prefix, mbed::Callback<void()>(obj, method));
+    }
+
+    /**
+    * Flushes the underlying stream
+    */
+    void flush();
+};
+#endif
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,76 @@
+
+/**
+ * @file    Buffer.cpp
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#include "MyBuffer.h"
+
+template <class T>
+MyBuffer<T>::MyBuffer(uint32_t size)
+{
+    _buf = new T [size];
+    _size = size;
+    clear();
+    
+    return;
+}
+
+template <class T>
+MyBuffer<T>::~MyBuffer()
+{
+    delete [] _buf;
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::getSize() 
+{ 
+    return this->_size; 
+}
+
+template <class T>
+void MyBuffer<T>::clear(void)
+{
+    _wloc = 0;
+    _rloc = 0;
+    memset(_buf, 0, _size);
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::peek(char c)
+{
+    return 1;
+}
+
+// make the linker aware of some possible types
+template class MyBuffer<uint8_t>;
+template class MyBuffer<int8_t>;
+template class MyBuffer<uint16_t>;
+template class MyBuffer<int16_t>;
+template class MyBuffer<uint32_t>;
+template class MyBuffer<int32_t>;
+template class MyBuffer<uint64_t>;
+template class MyBuffer<int64_t>;
+template class MyBuffer<char>;
+template class MyBuffer<wchar_t>;
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/BufferedSerial/Buffer/MyBuffer.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,163 @@
+
+/**
+ * @file    Buffer.h
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef MYBUFFER_H
+#define MYBUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+/** A templated software ring buffer
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "MyBuffer.h"
+ *
+ *  MyBuffer <char> buf;
+ *
+ *  int main()
+ *  {
+ *      buf = 'a';
+ *      buf.put('b');
+ *      char *head = buf.head();
+ *      puts(head);
+ *
+ *      char whats_in_there[2] = {0};
+ *      int pos = 0;
+ *
+ *      while(buf.available())
+ *      {   
+ *          whats_in_there[pos++] = buf;
+ *      }
+ *      printf("%c %c\n", whats_in_there[0], whats_in_there[1]);
+ *      buf.clear();
+ *      error("done\n\n\n");
+ *  }
+ * @endcode
+ */
+
+template <typename T>
+class MyBuffer
+{
+private:
+    T   *_buf;
+    volatile uint32_t   _wloc;
+    volatile uint32_t   _rloc;
+    uint32_t            _size;
+
+public:
+    /** Create a Buffer and allocate memory for it
+     *  @param size The size of the buffer
+     */
+    MyBuffer(uint32_t size = 0x100);
+    
+    /** Get the size of the ring buffer
+     * @return the size of the ring buffer
+     */
+     uint32_t getSize();
+    
+    /** Destry a Buffer and release it's allocated memory
+     */
+    ~MyBuffer();
+    
+    /** Add a data element into the buffer
+     *  @param data Something to add to the buffer
+     */
+    void put(T data);
+    
+    /** Remove a data element from the buffer
+     *  @return Pull the oldest element from the buffer
+     */
+    T get(void);
+    
+    /** Get the address to the head of the buffer
+     *  @return The address of element 0 in the buffer
+     */
+    T *head(void);
+    
+    /** Reset the buffer to 0. Useful if using head() to parse packeted data
+     */
+    void clear(void);
+    
+    /** Determine if anything is readable in the buffer
+     *  @return 1 if something can be read, 0 otherwise
+     */
+    uint32_t available(void);
+    
+    /** Overloaded operator for writing to the buffer
+     *  @param data Something to put in the buffer
+     *  @return
+     */
+    MyBuffer &operator= (T data)
+    {
+        put(data);
+        return *this;
+    }
+    
+    /** Overloaded operator for reading from the buffer
+     *  @return Pull the oldest element from the buffer 
+     */  
+    operator int(void)
+    {
+        return get();
+    }
+    
+     uint32_t peek(char c);
+    
+};
+
+template <class T>
+inline void MyBuffer<T>::put(T data)
+{
+    _buf[_wloc++] = data;
+    _wloc %= (_size-1);
+    
+    return;
+}
+
+template <class T>
+inline T MyBuffer<T>::get(void)
+{
+    T data_pos = _buf[_rloc++];
+    _rloc %= (_size-1);
+    
+    return data_pos;
+}
+
+template <class T>
+inline T *MyBuffer<T>::head(void)
+{
+    T *data_pos = &_buf[0];
+    
+    return data_pos;
+}
+
+template <class T>
+inline uint32_t MyBuffer<T>::available(void)
+{
+    return (_wloc == _rloc) ? 0 : 1;
+}
+
+#endif
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedPrint.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedPrint.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mbed_error.h"
+
+size_t BufferedSerialThunk(void *buf_serial, const void *s, size_t length);
+
+int BufferedPrintfC(void *stream, int size, const char* format, va_list arg)
+{
+    int r;
+    char buffer[512];
+    if (size >= 512) {
+        return -1;
+    }
+    memset(buffer, 0, size);
+    r = vsprintf(buffer, format, arg);
+    // this may not hit the heap but should alert the user anyways
+    if(r > (int32_t) size) {
+        error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__, size, r);
+        return 0;
+    }
+    if ( r > 0 ) {
+        BufferedSerialThunk(stream, buffer, r);
+    }
+    return r;
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,166 @@
+/**
+ * @file    BufferedSerial.cpp
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+extern "C" int BufferedPrintfC(void *stream, int size, const char* format, va_list arg);
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+    : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+    RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+    this->_buf_size = buf_size;
+    this->_tx_multiple = tx_multiple;   
+    return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+    RawSerial::attach(NULL, RawSerial::RxIrq);
+    RawSerial::attach(NULL, RawSerial::TxIrq);
+
+    return;
+}
+
+int BufferedSerial::readable(void)
+{
+    return _rxbuf.available();  // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+    return 1;   // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+    return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+    _txbuf = (char)c;
+    BufferedSerial::prime();
+
+    return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+    if (s != NULL) {
+        const char* ptr = s;
+    
+        while(*(ptr) != 0) {
+            _txbuf = *(ptr++);
+        }
+        _txbuf = '\n';  // done per puts definition
+        BufferedSerial::prime();
+    
+        return (ptr - s) + 1;
+    }
+    return 0;
+}
+
+extern "C" size_t BufferedSerialThunk(void *buf_serial, const void *s, size_t length)
+{
+    BufferedSerial *buffered_serial = (BufferedSerial *)buf_serial;
+    return buffered_serial->write(s, length);
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+    va_list arg;
+    va_start(arg, format);
+    int r = BufferedPrintfC((void*)this, this->_buf_size, format, arg);
+    va_end(arg);
+    return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+    if (s != NULL && length > 0) {
+        const char* ptr = (const char*)s;
+        const char* end = ptr + length;
+    
+        while (ptr != end) {
+            _txbuf = *(ptr++);
+        }
+        BufferedSerial::prime();
+    
+        return ptr - (const char*)s;
+    }
+    return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+    // read from the peripheral and make sure something is available
+    if(serial_readable(&_serial)) {
+        _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+        // trigger callback if necessary
+        if (_cbs[RxIrq]) {
+            _cbs[RxIrq]();
+        }
+    }
+
+    return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+    // see if there is room in the hardware fifo and if something is in the software fifo
+    while(serial_writable(&_serial)) {
+        if(_txbuf.available()) {
+            serial_putc(&_serial, (int)_txbuf.get());
+        } else {
+            // disable the TX interrupt when there is nothing left to send
+            RawSerial::attach(NULL, RawSerial::TxIrq);
+            // trigger callback if necessary
+            if (_cbs[TxIrq]) {
+                _cbs[TxIrq]();
+            }
+            break;
+        }
+    }
+
+    return;
+}
+
+void BufferedSerial::prime(void)
+{
+    // if already busy then the irq will pick this up
+    if(serial_writable(&_serial)) {
+        RawSerial::attach(NULL, RawSerial::TxIrq);    // make sure not to cause contention in the irq
+        BufferedSerial::txIrq();                // only write to hardware in one place
+        RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+    }
+
+    return;
+}
+
+void BufferedSerial::attach(Callback<void()> func, IrqType type)
+{
+    _cbs[type] = func;
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/BufferedSerial/BufferedSerial.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,168 @@
+
+/**
+ * @file    BufferedSerial.h
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+ 
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "BufferedSerial.h"
+ *
+ *  BufferedSerial pc(USBTX, USBRX);
+ *
+ *  int main()
+ *  { 
+ *      while(1)
+ *      {
+ *          Timer s;
+ *        
+ *          s.start();
+ *          pc.printf("Hello World - buffered\n");
+ *          int buffered_time = s.read_us();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          s.reset();
+ *          printf("Hello World - blocking\n");
+ *          int polled_time = s.read_us();
+ *          s.stop();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          pc.printf("printf buffered took %d us\n", buffered_time);
+ *          pc.printf("printf blocking took %d us\n", polled_time);
+ *          wait(0.5f);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class BufferedSerial
+ *  @brief Software buffers and interrupt driven tx and rx for Serial
+ */  
+class BufferedSerial : public RawSerial 
+{
+private:
+    MyBuffer <char> _rxbuf;
+    MyBuffer <char> _txbuf;
+    uint32_t      _buf_size;
+    uint32_t      _tx_multiple;
+ 
+    void rxIrq(void);
+    void txIrq(void);
+    void prime(void);
+
+    Callback<void()> _cbs[2];
+    
+public:
+    /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *  @param buf_size printf() buffer size
+     *  @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+     *  @param name optional name
+     *  @note Either tx or rx may be specified as NC if unused
+     */
+    BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+    
+    /** Destroy a BufferedSerial port
+     */
+    virtual ~BufferedSerial(void);
+    
+    /** Check on how many bytes are in the rx buffer
+     *  @return 1 if something exists, 0 otherwise
+     */
+    virtual int readable(void);
+    
+    /** Check to see if the tx buffer has room
+     *  @return 1 always has room and can overwrite previous content if too small / slow
+     */
+    virtual int writeable(void);
+    
+    /** Get a single byte from the BufferedSerial Port.
+     *  Should check readable() before calling this.
+     *  @return A byte that came in on the Serial Port
+     */
+    virtual int getc(void);
+    
+    /** Write a single byte to the BufferedSerial Port.
+     *  @param c The byte to write to the Serial Port
+     *  @return The byte that was written to the Serial Port Buffer
+     */
+    virtual int putc(int c);
+    
+    /** Write a string to the BufferedSerial Port. Must be NULL terminated
+     *  @param s The string to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int puts(const char *s);
+    
+    /** Write a formatted string to the BufferedSerial Port.
+     *  @param format The string + format specifiers to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int printf(const char* format, ...);
+    
+    /** Write data to the Buffered Serial Port
+     *  @param s A pointer to data to send
+     *  @param length The amount of data being pointed to
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual ssize_t write(const void *s, std::size_t length);
+
+    /** Attach a function to call whenever a serial interrupt is generated
+     *  @param func A pointer to a void function, or 0 to set as none
+     *  @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    virtual void attach(Callback<void()> func, IrqType type=RxIrq);
+
+    /** Attach a member function to call whenever a serial interrupt is generated
+     *  @param obj pointer to the object to call the member function on
+     *  @param method pointer to the member function to call
+     *  @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    template <typename T>
+    void attach(T *obj, void (T::*method)(), IrqType type=RxIrq) {
+        attach(Callback<void()>(obj, method), type);
+    }
+
+    /** Attach a member function to call whenever a serial interrupt is generated
+     *  @param obj pointer to the object to call the member function on
+     *  @param method pointer to the member function to call
+     *  @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    template <typename T>
+    void attach(T *obj, void (*method)(T*), IrqType type=RxIrq) {
+        attach(Callback<void()>(obj, method), type);
+    }
+};
+
+#endif
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ATParser/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ATParser/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+# AT Command Parser
+
+An mbed-os compatible AT command parser.
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ESP8266.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ESP8266.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,322 @@
+/* ESP8266 Example
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ESP8266.h"
+
+ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
+    : _serial(tx, rx, 1024), _parser(_serial)
+    , _packets(0), _packets_end(&_packets)
+{
+    _serial.baud(115200);
+    _parser.debugOn(debug);
+}
+
+int ESP8266::get_firmware_version()
+{
+    _parser.send("AT+GMR");
+    int version;
+    if(_parser.recv("SDK version:%d", &version) && _parser.recv("OK")) {
+        return version;
+    } else { 
+        // Older firmware versions do not prefix the version with "SDK version: "
+        return -1;
+    }
+    
+}
+
+bool ESP8266::startup(int mode)
+{
+    //only 3 valid modes
+    if(mode < 1 || mode > 3) {
+        return false;
+    }
+
+    bool success = _parser.send("AT+CWMODE_CUR=%d", mode)
+        && _parser.recv("OK")
+        && _parser.send("AT+CIPMUX=1")
+        && _parser.recv("OK");
+
+    _parser.oob("+IPD", this, &ESP8266::_packet_handler);
+
+    return success;
+}
+
+bool ESP8266::reset(void)
+{
+    for (int i = 0; i < 2; i++) {
+        if (_parser.send("AT+RST")
+            && _parser.recv("OK\r\nready")) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool ESP8266::dhcp(bool enabled, int mode)
+{
+    //only 3 valid modes
+    if(mode < 0 || mode > 2) {
+        return false;
+    }
+
+    return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
+        && _parser.recv("OK");
+}
+
+bool ESP8266::connect(const char *ap, const char *passPhrase)
+{
+    return _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
+        && _parser.recv("OK");
+}
+
+bool ESP8266::disconnect(void)
+{
+    return _parser.send("AT+CWQAP") && _parser.recv("OK");
+}
+
+const char *ESP8266::getIPAddress(void)
+{
+    if (!(_parser.send("AT+CIFSR")
+        && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return _ip_buffer;
+}
+
+const char *ESP8266::getMACAddress(void)
+{
+    if (!(_parser.send("AT+CIFSR")
+        && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return _mac_buffer;
+}
+
+const char *ESP8266::getGateway()
+{
+    if (!(_parser.send("AT+CIPSTA?")
+        && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return _gateway_buffer;
+}
+
+const char *ESP8266::getNetmask()
+{
+    if (!(_parser.send("AT+CIPSTA?")
+        && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return _netmask_buffer;
+}
+
+int8_t ESP8266::getRSSI()
+{
+    int8_t rssi;
+    char bssid[18];
+
+   if (!(_parser.send("AT+CWJAP?")
+        && _parser.recv("+CWJAP:\"%*[^\"]\",\"%17[^\"]\"", bssid)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid)
+        && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return rssi;
+}
+
+bool ESP8266::isConnected(void)
+{
+    return getIPAddress() != 0;
+}
+
+int ESP8266::scan(WiFiAccessPoint *res, unsigned limit)
+{
+    unsigned cnt = 0;
+    nsapi_wifi_ap_t ap;
+
+    if (!_parser.send("AT+CWLAP")) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+
+    while (recv_ap(&ap)) {
+        if (cnt < limit) {
+            res[cnt] = WiFiAccessPoint(ap);
+        }
+
+        cnt++;
+        if (limit != 0 && cnt >= limit) {
+            break;
+        }
+    }
+
+    return cnt;
+}
+
+bool ESP8266::open(const char *type, int id, const char* addr, int port)
+{
+    //IDs only 0-4
+    if(id > 4) {
+        return false;
+    }
+    return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
+        && _parser.recv("OK");
+}
+
+bool ESP8266::dns_lookup(const char* name, char* ip)
+{
+    return _parser.send("AT+CIPDOMAIN=\"%s\"", name) && _parser.recv("+CIPDOMAIN:%s%*[\r]%*[\n]", ip);
+}
+
+bool ESP8266::send(int id, const void *data, uint32_t amount)
+{
+    //May take a second try if device is busy
+    for (unsigned i = 0; i < 2; i++) {
+        if (_parser.send("AT+CIPSEND=%d,%d", id, amount)
+            && _parser.recv(">")
+            && _parser.write((char*)data, (int)amount) >= 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void ESP8266::_packet_handler()
+{
+    int id;
+    uint32_t amount;
+
+    // parse out the packet
+    if (!_parser.recv(",%d,%d:", &id, &amount)) {
+        return;
+    }
+
+    struct packet *packet = (struct packet*)malloc(
+            sizeof(struct packet) + amount);
+    if (!packet) {
+        return;
+    }
+
+    packet->id = id;
+    packet->len = amount;
+    packet->next = 0;
+
+    if (!(_parser.read((char*)(packet + 1), amount))) {
+        free(packet);
+        return;
+    }
+
+    // append to packet list
+    *_packets_end = packet;
+    _packets_end = &packet->next;
+}
+
+int32_t ESP8266::recv(int id, void *data, uint32_t amount)
+{
+    while (true) {
+        // check if any packets are ready for us
+        for (struct packet **p = &_packets; *p; p = &(*p)->next) {
+            if ((*p)->id == id) {
+                struct packet *q = *p;
+
+                if (q->len <= amount) { // Return and remove full packet
+                    memcpy(data, q+1, q->len);
+
+                    if (_packets_end == &(*p)->next) {
+                        _packets_end = p;
+                    }
+                    *p = (*p)->next;
+
+                    uint32_t len = q->len;
+                    free(q);
+                    return len;
+                } else { // return only partial packet
+                    memcpy(data, q+1, amount);
+
+                    q->len -= amount;
+                    memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
+
+                    return amount;
+                }
+            }
+        }
+
+        // Wait for inbound packet
+        if (!_parser.recv("OK")) {
+            return -1;
+        }
+    }
+}
+
+bool ESP8266::close(int id)
+{
+    //May take a second try if device is busy
+    for (unsigned i = 0; i < 2; i++) {
+        if (_parser.send("AT+CIPCLOSE=%d", id)
+            && _parser.recv("OK")) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void ESP8266::setTimeout(uint32_t timeout_ms)
+{
+    _parser.setTimeout(timeout_ms);
+}
+
+bool ESP8266::readable()
+{
+    return _serial.readable();
+}
+
+bool ESP8266::writeable()
+{
+    return _serial.writeable();
+}
+
+void ESP8266::attach(Callback<void()> func)
+{
+    _serial.attach(func);
+}
+
+bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap)
+{
+    int sec;
+    bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%d", &sec, ap->ssid,
+                            &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4],
+                            &ap->bssid[5], &ap->channel);
+
+    ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN;
+
+    return ret;
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266/ESP8266.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266/ESP8266.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,228 @@
+/* ESP8266Interface Example
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ESP8266_H
+#define ESP8266_H
+
+#include "ATParser.h"
+
+/** ESP8266Interface class.
+    This is an interface to a ESP8266 radio.
+ */
+class ESP8266
+{
+public:
+    ESP8266(PinName tx, PinName rx, bool debug=false);
+
+    /**
+    * Check firmware version of ESP8266
+    *
+    * @return integer firmware version or -1 if firmware query command gives outdated response
+    */
+    int get_firmware_version(void);
+    
+    /**
+    * Startup the ESP8266
+    *
+    * @param mode mode of WIFI 1-client, 2-host, 3-both
+    * @return true only if ESP8266 was setup correctly
+    */
+    bool startup(int mode);
+
+    /**
+    * Reset ESP8266
+    *
+    * @return true only if ESP8266 resets successfully
+    */
+    bool reset(void);
+
+    /**
+    * Enable/Disable DHCP
+    *
+    * @param enabled DHCP enabled when true
+    * @param mode mode of DHCP 0-softAP, 1-station, 2-both
+    * @return true only if ESP8266 enables/disables DHCP successfully
+    */
+    bool dhcp(bool enabled, int mode);
+
+    /**
+    * Connect ESP8266 to AP
+    *
+    * @param ap the name of the AP
+    * @param passPhrase the password of AP
+    * @return true only if ESP8266 is connected successfully
+    */
+    bool connect(const char *ap, const char *passPhrase);
+
+    /**
+    * Disconnect ESP8266 from AP
+    *
+    * @return true only if ESP8266 is disconnected successfully
+    */
+    bool disconnect(void);
+
+    /**
+    * Get the IP address of ESP8266
+    *
+    * @return null-teriminated IP address or null if no IP address is assigned
+    */
+    const char *getIPAddress(void);
+
+    /**
+    * Get the MAC address of ESP8266
+    *
+    * @return null-terminated MAC address or null if no MAC address is assigned
+    */
+    const char *getMACAddress(void);
+
+     /** Get the local gateway
+     *
+     *  @return         Null-terminated representation of the local gateway
+     *                  or null if no network mask has been recieved
+     */
+    const char *getGateway();
+
+    /** Get the local network mask
+     *
+     *  @return         Null-terminated representation of the local network mask 
+     *                  or null if no network mask has been recieved
+     */
+    const char *getNetmask();
+
+    /* Return RSSI for active connection
+     *
+     * @return      Measured RSSI
+     */
+    int8_t getRSSI();
+
+    /**
+    * Check if ESP8266 is conenected
+    *
+    * @return true only if the chip has an IP address
+    */
+    bool isConnected(void);
+
+    /** Scan for available networks
+     *
+     * @param  ap    Pointer to allocated array to store discovered AP
+     * @param  limit Size of allocated @a res array, or 0 to only count available AP
+     * @return       Number of entries in @a res, or if @a count was 0 number of available networks, negative on error
+     *               see @a nsapi_error
+     */
+    int scan(WiFiAccessPoint *res, unsigned limit);
+    
+    /**Perform a dns query
+    *
+    * @param name Hostname to resolve
+    * @param ip   Buffer to store IP address
+    * @return 0 true on success, false on failure
+    */
+    bool dns_lookup(const char *name, char *ip);
+
+    /**
+    * Open a socketed connection
+    *
+    * @param type the type of socket to open "UDP" or "TCP"
+    * @param id id to give the new socket, valid 0-4
+    * @param port port to open connection with
+    * @param addr the IP address of the destination
+    * @return true only if socket opened successfully
+    */
+    bool open(const char *type, int id, const char* addr, int port);
+
+    /**
+    * Sends data to an open socket
+    *
+    * @param id id of socket to send to
+    * @param data data to be sent
+    * @param amount amount of data to be sent - max 1024
+    * @return true only if data sent successfully
+    */
+    bool send(int id, const void *data, uint32_t amount);
+
+    /**
+    * Receives data from an open socket
+    *
+    * @param id id to receive from
+    * @param data placeholder for returned information
+    * @param amount number of bytes to be received
+    * @return the number of bytes received
+    */
+    int32_t recv(int id, void *data, uint32_t amount);
+
+    /**
+    * Closes a socket
+    *
+    * @param id id of socket to close, valid only 0-4
+    * @return true only if socket is closed successfully
+    */
+    bool close(int id);
+
+    /**
+    * Allows timeout to be changed between commands
+    *
+    * @param timeout_ms timeout of the connection
+    */
+    void setTimeout(uint32_t timeout_ms);
+
+    /**
+    * Checks if data is available
+    */
+    bool readable();
+
+    /**
+    * Checks if data can be written
+    */
+    bool writeable();
+
+    /**
+    * Attach a function to call whenever network state has changed
+    *
+    * @param func A pointer to a void function, or 0 to set as none
+    */
+    void attach(Callback<void()> func);
+
+    /**
+    * Attach a function to call whenever network state has changed
+    *
+    * @param obj pointer to the object to call the member function on
+    * @param method pointer to the member function to call
+    */
+    template <typename T, typename M>
+    void attach(T *obj, M method) {
+        attach(Callback<void()>(obj, method));
+    }
+
+private:
+    BufferedSerial _serial;
+    ATParser _parser;
+
+    struct packet {
+        struct packet *next;
+        int id;
+        uint32_t len;
+        // data follows
+    } *_packets, **_packets_end;
+    void _packet_handler();
+    bool recv_ap(nsapi_wifi_ap_t *ap);
+
+    char _ip_buffer[16];
+    char _gateway_buffer[16];
+    char _netmask_buffer[16];
+    char _mac_buffer[18];
+};
+
+#endif
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266Interface.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266Interface.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,324 @@
+/* ESP8266 implementation of NetworkInterfaceAPI
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "ESP8266Interface.h"
+#include "mbed_debug.h"
+
+// Various timeouts for different ESP8266 operations
+#define ESP8266_CONNECT_TIMEOUT 15000
+#define ESP8266_SEND_TIMEOUT    500
+#define ESP8266_RECV_TIMEOUT    0
+#define ESP8266_MISC_TIMEOUT    500
+
+// Firmware version
+#define ESP8266_VERSION 2
+
+// ESP8266Interface implementation
+ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug)
+    : _esp(tx, rx, debug)
+{
+    memset(_ids, 0, sizeof(_ids));
+    memset(_cbs, 0, sizeof(_cbs));
+
+    _esp.attach(this, &ESP8266Interface::event);
+}
+
+int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
+                                        uint8_t channel)
+{
+    if (channel != 0) {
+        return NSAPI_ERROR_UNSUPPORTED;
+    }
+
+    set_credentials(ssid, pass, security);
+    return connect();
+}
+
+int ESP8266Interface::connect()
+{
+    _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
+    
+    if (!_esp.reset()) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }   
+ 
+    _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+    
+    if (_esp.get_firmware_version() != ESP8266_VERSION) {
+        debug("ESP8266: ERROR: Firmware incompatible with this driver.\
+               \r\nUpdate to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\r\n",ESP8266_VERSION); 
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+    
+    _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
+
+    if (!_esp.startup(3)) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+
+    if (!_esp.dhcp(true, 1)) {
+        return NSAPI_ERROR_DHCP_FAILURE;
+    }
+
+    if (!_esp.connect(ap_ssid, ap_pass)) {
+        return NSAPI_ERROR_NO_CONNECTION;
+    }
+
+    if (!_esp.getIPAddress()) {
+        return NSAPI_ERROR_DHCP_FAILURE;
+    }
+
+    return NSAPI_ERROR_OK;
+}
+
+nsapi_error_t ESP8266Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
+{
+    if (address->set_ip_address(name)) {
+        if (version != NSAPI_UNSPEC && address->get_ip_version() != version) {
+            return NSAPI_ERROR_DNS_FAILURE;
+        }
+
+        return NSAPI_ERROR_OK;
+    }
+    
+    char *ipbuff = new char[NSAPI_IP_SIZE];
+    int ret = 0;
+    
+    if(!_esp.dns_lookup(name, ipbuff)) {
+        ret = NSAPI_ERROR_DEVICE_ERROR;
+    } else {
+        address->set_ip_address(ipbuff);
+    }
+
+    delete[] ipbuff;
+    return ret;
+}
+
+int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
+{
+    memset(ap_ssid, 0, sizeof(ap_ssid));
+    strncpy(ap_ssid, ssid, sizeof(ap_ssid));
+
+    memset(ap_pass, 0, sizeof(ap_pass));
+    strncpy(ap_pass, pass, sizeof(ap_pass));
+
+    ap_sec = security;
+
+    return 0;
+}
+
+int ESP8266Interface::set_channel(uint8_t channel)
+{
+    return NSAPI_ERROR_UNSUPPORTED;
+}
+
+
+int ESP8266Interface::disconnect()
+{
+    _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+    if (!_esp.disconnect()) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+
+    return NSAPI_ERROR_OK;
+}
+
+const char *ESP8266Interface::get_ip_address()
+{
+    return _esp.getIPAddress();
+}
+
+const char *ESP8266Interface::get_mac_address()
+{
+    return _esp.getMACAddress();
+}
+
+const char *ESP8266Interface::get_gateway()
+{
+    return _esp.getGateway();
+}
+
+const char *ESP8266Interface::get_netmask()
+{
+    return _esp.getNetmask();
+}
+
+int8_t ESP8266Interface::get_rssi()
+{
+    return _esp.getRSSI();
+}
+
+int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
+{
+    return _esp.scan(res, count);
+}
+
+struct esp8266_socket {
+    int id;
+    nsapi_protocol_t proto;
+    bool connected;
+    SocketAddress addr;
+};
+
+int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
+{
+    // Look for an unused socket
+    int id = -1;
+ 
+    for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
+        if (!_ids[i]) {
+            id = i;
+            _ids[i] = true;
+            break;
+        }
+    }
+ 
+    if (id == -1) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    
+    struct esp8266_socket *socket = new struct esp8266_socket;
+    if (!socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    
+    socket->id = id;
+    socket->proto = proto;
+    socket->connected = false;
+    *handle = socket;
+    return 0;
+}
+
+int ESP8266Interface::socket_close(void *handle)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+    int err = 0;
+    _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+ 
+    if (socket->connected && !_esp.close(socket->id)) {
+        err = NSAPI_ERROR_DEVICE_ERROR;
+    }
+
+    socket->connected = false;
+    _ids[socket->id] = false;
+    delete socket;
+    return err;
+}
+
+int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
+{
+    return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_listen(void *handle, int backlog)
+{
+    return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+    _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+
+    const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP";
+    if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+    
+    socket->connected = true;
+    return 0;
+}
+    
+int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
+{
+    return NSAPI_ERROR_UNSUPPORTED;
+}
+
+int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+    _esp.setTimeout(ESP8266_SEND_TIMEOUT);
+ 
+    if (!_esp.send(socket->id, data, size)) {
+        return NSAPI_ERROR_DEVICE_ERROR;
+    }
+ 
+    return size;
+}
+
+int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+    _esp.setTimeout(ESP8266_RECV_TIMEOUT);
+ 
+    int32_t recv = _esp.recv(socket->id, data, size);
+    if (recv < 0) {
+        return NSAPI_ERROR_WOULD_BLOCK;
+    }
+ 
+    return recv;
+}
+
+int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+
+    if (socket->connected && socket->addr != addr) {
+        _esp.setTimeout(ESP8266_MISC_TIMEOUT);
+        if (!_esp.close(socket->id)) {
+            return NSAPI_ERROR_DEVICE_ERROR;
+        }
+        socket->connected = false;
+    }
+
+    if (!socket->connected) {
+        int err = socket_connect(socket, addr);
+        if (err < 0) {
+            return err;
+        }
+        socket->addr = addr;
+    }
+    
+    return socket_send(socket, data, size);
+}
+
+int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;
+    int ret = socket_recv(socket, data, size);
+    if (ret >= 0 && addr) {
+        *addr = socket->addr;
+    }
+
+    return ret;
+}
+
+void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
+{
+    struct esp8266_socket *socket = (struct esp8266_socket *)handle;    
+    _cbs[socket->id].callback = callback;
+    _cbs[socket->id].data = data;
+}
+
+void ESP8266Interface::event() {
+    for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
+        if (_cbs[i].callback) {
+            _cbs[i].callback(_cbs[i].data);
+        }
+    }
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/ESP8266Interface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/ESP8266Interface.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,289 @@
+/* ESP8266 implementation of NetworkInterfaceAPI
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ESP8266_INTERFACE_H
+#define ESP8266_INTERFACE_H
+
+#include "mbed.h"
+#include "ESP8266.h"
+
+
+#define ESP8266_SOCKET_COUNT 5
+
+/** ESP8266Interface class
+ *  Implementation of the NetworkStack for the ESP8266
+ */
+class ESP8266Interface : public NetworkStack, public WiFiInterface
+{
+public:
+    /** ESP8266Interface lifetime
+     * @param tx        TX pin
+     * @param rx        RX pin
+     * @param debug     Enable debugging
+     */
+    ESP8266Interface(PinName tx, PinName rx, bool debug = false);
+
+    /** Start the interface
+     *
+     *  Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
+     *  If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned.
+     *
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual int connect();
+
+    /** Start the interface
+     *
+     *  Attempts to connect to a WiFi network.
+     *
+     *  @param ssid      Name of the network to connect to
+     *  @param pass      Security passphrase to connect to the network
+     *  @param security  Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
+     *  @param channel   This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED
+     *  @return          0 on success, or error code on failure
+     */
+    virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
+                                  uint8_t channel = 0);
+    
+    /** Translates a hostname to an IP address with specific version
+     *
+     *  The hostname may be either a domain name or an IP address. If the
+     *  hostname is an IP address, no network transactions will be performed.
+     *
+     *
+     *  @param host     Hostname to resolve
+     *  @param address  Destination for the host SocketAddress
+     *  @param version  IP version of address to resolve, NSAPI_UNSPEC indicates
+     *                  version is chosen by the stack (defaults to NSAPI_UNSPEC)
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC);
+    
+    /** Set the WiFi network credentials
+     *
+     *  @param ssid      Name of the network to connect to
+     *  @param pass      Security passphrase to connect to the network
+     *  @param security  Type of encryption for connection
+     *                   (defaults to NSAPI_SECURITY_NONE)
+     *  @return          0 on success, or error code on failure
+     */
+    virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE);
+
+    /** Set the WiFi network channel - NOT SUPPORTED
+     *
+     * This function is not supported and will return NSAPI_ERROR_UNSUPPORTED
+     *
+     *  @param channel   Channel on which the connection is to be made, or 0 for any (Default: 0)
+     *  @return          Not supported, returns NSAPI_ERROR_UNSUPPORTED
+     */
+    virtual int set_channel(uint8_t channel);
+
+    /** Stop the interface
+     *  @return             0 on success, negative on failure
+     */
+    virtual int disconnect();
+
+    /** Get the internally stored IP address
+     *  @return             IP address of the interface or null if not yet connected
+     */
+    virtual const char *get_ip_address();
+
+    /** Get the internally stored MAC address
+     *  @return             MAC address of the interface
+     */
+    virtual const char *get_mac_address();
+
+     /** Get the local gateway
+     *
+     *  @return         Null-terminated representation of the local gateway
+     *                  or null if no network mask has been recieved
+     */
+    virtual const char *get_gateway();
+
+    /** Get the local network mask
+     *
+     *  @return         Null-terminated representation of the local network mask
+     *                  or null if no network mask has been recieved
+     */
+    virtual const char *get_netmask();
+
+    /** Gets the current radio signal strength for active connection
+     *
+     * @return          Connection strength in dBm (negative value)
+     */
+    virtual int8_t get_rssi();
+
+    /** Scan for available networks
+     *
+     * This function will block.
+     *
+     * @param  ap       Pointer to allocated array to store discovered AP
+     * @param  count    Size of allocated @a res array, or 0 to only count available AP
+     * @param  timeout  Timeout in milliseconds; 0 for no timeout (Default: 0)
+     * @return          Number of entries in @a, or if @a count was 0 number of available networks, negative on error
+     *                  see @a nsapi_error
+     */
+    virtual int scan(WiFiAccessPoint *res, unsigned count);
+
+    /** Translates a hostname to an IP address with specific version
+     *
+     *  The hostname may be either a domain name or an IP address. If the
+     *  hostname is an IP address, no network transactions will be performed.
+     *
+     *  If no stack-specific DNS resolution is provided, the hostname
+     *  will be resolve using a UDP socket on the stack.
+     *
+     *  @param address  Destination for the host SocketAddress
+     *  @param host     Hostname to resolve
+     *  @param version  IP version of address to resolve, NSAPI_UNSPEC indicates
+     *                  version is chosen by the stack (defaults to NSAPI_UNSPEC)
+     *  @return         0 on success, negative error code on failure
+     */
+    using NetworkInterface::gethostbyname;
+
+    /** Add a domain name server to list of servers to query
+     *
+     *  @param addr     Destination for the host address
+     *  @return         0 on success, negative error code on failure
+     */
+    using NetworkInterface::add_dns_server;
+
+protected:
+    /** Open a socket
+     *  @param handle       Handle in which to store new socket
+     *  @param proto        Type of socket to open, NSAPI_TCP or NSAPI_UDP
+     *  @return             0 on success, negative on failure
+     */
+    virtual int socket_open(void **handle, nsapi_protocol_t proto);
+
+    /** Close the socket
+     *  @param handle       Socket handle
+     *  @return             0 on success, negative on failure
+     *  @note On failure, any memory associated with the socket must still
+     *        be cleaned up
+     */
+    virtual int socket_close(void *handle);
+
+    /** Bind a server socket to a specific port
+     *  @param handle       Socket handle
+     *  @param address      Local address to listen for incoming connections on
+     *  @return             0 on success, negative on failure.
+     */
+    virtual int socket_bind(void *handle, const SocketAddress &address);
+
+    /** Start listening for incoming connections
+     *  @param handle       Socket handle
+     *  @param backlog      Number of pending connections that can be queued up at any
+     *                      one time [Default: 1]
+     *  @return             0 on success, negative on failure
+     */
+    virtual int socket_listen(void *handle, int backlog);
+
+    /** Connects this TCP socket to the server
+     *  @param handle       Socket handle
+     *  @param address      SocketAddress to connect to
+     *  @return             0 on success, negative on failure
+     */
+    virtual int socket_connect(void *handle, const SocketAddress &address);
+
+    /** Accept a new connection.
+     *  @param handle       Handle in which to store new socket
+     *  @param server       Socket handle to server to accept from
+     *  @return             0 on success, negative on failure
+     *  @note This call is not-blocking, if this call would block, must
+     *        immediately return NSAPI_ERROR_WOULD_WAIT
+     */
+    virtual int socket_accept(void *handle, void **socket, SocketAddress *address);
+
+    /** Send data to the remote host
+     *  @param handle       Socket handle
+     *  @param data         The buffer to send to the host
+     *  @param size         The length of the buffer to send
+     *  @return             Number of written bytes on success, negative on failure
+     *  @note This call is not-blocking, if this call would block, must
+     *        immediately return NSAPI_ERROR_WOULD_WAIT
+     */
+    virtual int socket_send(void *handle, const void *data, unsigned size);
+
+    /** Receive data from the remote host
+     *  @param handle       Socket handle
+     *  @param data         The buffer in which to store the data received from the host
+     *  @param size         The maximum length of the buffer
+     *  @return             Number of received bytes on success, negative on failure
+     *  @note This call is not-blocking, if this call would block, must
+     *        immediately return NSAPI_ERROR_WOULD_WAIT
+     */
+    virtual int socket_recv(void *handle, void *data, unsigned size);
+
+    /** Send a packet to a remote endpoint
+     *  @param handle       Socket handle
+     *  @param address      The remote SocketAddress
+     *  @param data         The packet to be sent
+     *  @param size         The length of the packet to be sent
+     *  @return             The number of written bytes on success, negative on failure
+     *  @note This call is not-blocking, if this call would block, must
+     *        immediately return NSAPI_ERROR_WOULD_WAIT
+     */
+    virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
+
+    /** Receive a packet from a remote endpoint
+     *  @param handle       Socket handle
+     *  @param address      Destination for the remote SocketAddress or null
+     *  @param buffer       The buffer for storing the incoming packet data
+     *                      If a packet is too long to fit in the supplied buffer,
+     *                      excess bytes are discarded
+     *  @param size         The length of the buffer
+     *  @return             The number of received bytes on success, negative on failure
+     *  @note This call is not-blocking, if this call would block, must
+     *        immediately return NSAPI_ERROR_WOULD_WAIT
+     */
+    virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
+
+    /** Register a callback on state change of the socket
+     *  @param handle       Socket handle
+     *  @param callback     Function to call on state change
+     *  @param data         Argument to pass to callback
+     *  @note Callback may be called in an interrupt context.
+     */
+    virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
+
+    /** Provide access to the NetworkStack object
+     *
+     *  @return The underlying NetworkStack object
+     */
+    virtual NetworkStack *get_stack()
+    {
+        return this;
+    }
+
+private:
+    ESP8266 _esp;
+    bool _ids[ESP8266_SOCKET_COUNT];
+
+    char ap_ssid[33]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */
+    nsapi_security_t ap_sec;
+    uint8_t ap_ch;
+    char ap_pass[64]; /* The longest allowed passphrase */
+
+    void event();
+
+    struct {
+        void (*callback)(void *);
+        void *data;
+    } _cbs[ESP8266_SOCKET_COUNT];
+};
+
+#endif
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,13 @@
+# The ESP8266 WiFi driver for mbed-os
+The mbed OS driver for the ESP8266 WiFi module
+
+## Firmware version
+ESP8266 modules come in different shapes and forms, but most important difference is which firmware version it is programmed with. To make sure that your module has mbed-os compatible firmware follow update guide: https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update
+
+## Testing
+The ESP8266 library contains the core network tests taken from mbed OS. After installing mbed CLI and importing the mbed OS library, the tests can be ran with the `mbed test` command:
+``` bash
+# Runs the ESP8266 network tests, requires a wifi access point
+mbed test -t <COMPILER HERE> -m <BOARD HERE> -n tests-net* --compile -DMBED_CFG_ESP8266_SSID='"<SSID HERE>"' -DMBED_CFG_ESP8266_PASS='"<PASS HERE>"'
+mbed test -t <COMPILER HERE> -m <BOARD HERE> -n tests-net* --run --verbose
+```
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/.mbedignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/.mbedignore	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+host_tests/*
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/connectivity/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/connectivity/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,82 @@
+#include "mbed.h"
+#include "greentea-client/test_env.h"
+#include "unity.h"
+#include "utest.h"
+
+#include "ESP8266Interface.h"
+
+using namespace utest::v1;
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+// Bringing the network up and down
+template <int COUNT>
+void test_bring_up_down() {
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    net.set_credentials(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+
+    for (int i = 0; i < COUNT; i++) {
+        int err = net.connect();
+        TEST_ASSERT_EQUAL(0, err);
+
+        printf("MBED: IP Address %s\r\n", net.get_ip_address());
+        printf("MBED: Netmask %s\r\n", net.get_netmask());
+        printf("MBED: Gateway %s\r\n", net.get_gateway());
+        TEST_ASSERT(net.get_ip_address());
+        TEST_ASSERT(net.get_netmask());
+        TEST_ASSERT(net.get_gateway());
+
+        UDPSocket udp;
+        err = udp.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+        err = udp.close();
+        TEST_ASSERT_EQUAL(0, err);
+
+        TCPSocket tcp;
+        err = tcp.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+        err = tcp.close();
+        TEST_ASSERT_EQUAL(0, err);
+
+        err = net.disconnect();
+        TEST_ASSERT_EQUAL(0, err);
+    }
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "default_auto", uuid, sizeof(uuid));
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("Bringing the network up and down", test_bring_up_down<1>),
+    Case("Bringing the network up and down twice", test_bring_up_down<2>),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/gethostbyname/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/gethostbyname/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,124 @@
+#include "mbed.h"
+#include "greentea-client/test_env.h"
+#include "unity.h"
+#include "utest.h"
+#include "ESP8266Interface.h"
+
+using namespace utest::v1;
+
+// Hostname for testing against
+// Must have A and AAAA records
+#ifndef MBED_DNS_TEST_HOST
+#define MBED_DNS_TEST_HOST "connector.mbed.com"
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+// Address info from stack
+const char *ip_literal;
+nsapi_version_t ip_pref;
+const char *ip_pref_repr;
+
+// Network setup
+ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+void net_bringup() {
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+    printf("MBED: Connected to network\n");
+    printf("MBED: IP Address: %s\n", net.get_ip_address());
+
+    ip_literal = net.get_ip_address();
+    ip_pref = SocketAddress(ip_literal).get_ip_version();
+    ip_pref_repr = (ip_pref == NSAPI_IPv4) ? "ipv4" :
+                   (ip_pref == NSAPI_IPv6) ? "ipv6" : "unspec";
+}
+
+
+// DNS tests
+void test_dns_query() {
+    SocketAddress addr;
+    int err = net.gethostbyname(MBED_DNS_TEST_HOST, &addr);
+    printf("DNS: query \"%s\" => \"%s\"\n",
+            MBED_DNS_TEST_HOST, addr.get_ip_address());
+
+    TEST_ASSERT_EQUAL(0, err);
+    TEST_ASSERT((bool)addr);
+    TEST_ASSERT(strlen(addr.get_ip_address()) > 1);
+}
+
+void test_dns_query_pref() {
+    SocketAddress addr;
+    int err = net.gethostbyname(MBED_DNS_TEST_HOST, &addr, ip_pref);
+    printf("DNS: query %s \"%s\" => \"%s\"\n",
+            ip_pref_repr, MBED_DNS_TEST_HOST, addr.get_ip_address());
+
+    TEST_ASSERT_EQUAL(0, err);
+    TEST_ASSERT((bool)addr);
+    TEST_ASSERT(strlen(addr.get_ip_address()) > 1);
+    TEST_ASSERT_EQUAL(ip_pref, addr.get_ip_version());
+}
+
+void test_dns_literal() {
+    SocketAddress addr;
+    int err = net.gethostbyname(ip_literal, &addr);
+    printf("DNS: literal \"%s\" => \"%s\"\n",
+            ip_literal, addr.get_ip_address());
+
+    TEST_ASSERT_EQUAL(0, err);
+    TEST_ASSERT((bool)addr);
+    TEST_ASSERT(strlen(addr.get_ip_address()) > 1);
+    TEST_ASSERT(strcmp(ip_literal, addr.get_ip_address()) == 0);
+}
+
+void test_dns_literal_pref() {
+    SocketAddress addr;
+    int err = net.gethostbyname(ip_literal, &addr, ip_pref);
+    printf("DNS: literal %s \"%s\" => \"%s\"\n",
+            ip_pref_repr, ip_literal, addr.get_ip_address());
+
+    TEST_ASSERT_EQUAL(0, err);
+    TEST_ASSERT((bool)addr);
+    TEST_ASSERT(strlen(addr.get_ip_address()) > 1);
+    TEST_ASSERT_EQUAL(ip_pref, addr.get_ip_version());
+    TEST_ASSERT(strcmp(ip_literal, addr.get_ip_address()) == 0);
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "default_auto", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+    net_bringup();
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("DNS query",               test_dns_query),
+    Case("DNS preference query",    test_dns_query_pref),
+    Case("DNS literal",             test_dns_literal),
+    Case("DNS preference literal",  test_dns_literal_pref),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/tcp_echo.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/host_tests/tcp_echo.py	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,195 @@
+# Copyright 2015 ARM Limited, All rights reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import select
+import socket
+import logging
+from threading import Thread
+from sys import stdout
+from SocketServer import BaseRequestHandler, TCPServer
+from mbed_host_tests import BaseHostTest, event_callback
+
+
+class TCPEchoClientHandler(BaseRequestHandler):
+    def handle(self):
+        """
+        Handles a connection. Test starts by client(i.e. mbed) connecting to server.
+        This connection handler receives data and echoes back to the client util
+        {{end}} is received. Then it sits on recv() for client to terminate the
+        connection.
+
+        Note: reason for not echoing data back after receiving {{end}} is that send
+              fails raising a SocketError as client closes connection.
+        """
+        while self.server.isrunning():
+            try:
+                data = self.recv()
+                if not data: break
+            except Exception as e:
+                break
+
+            try:
+                # echo data back to the client
+                self.send(data)
+            except Exception as e:
+                break
+
+    def recv(self):
+        """
+        Try to receive until server is shutdown
+        """
+        while self.server.isrunning():
+            rl, wl, xl = select.select([self.request], [], [], 1)
+            if len(rl):
+                return self.request.recv(1024)
+
+    def send(self, data):
+        """
+        Try to send until server is shutdown
+        """
+        while self.server.isrunning():
+            rl, wl, xl = select.select([], [self.request], [], 1)
+            if len(wl):
+                self.request.sendall(data)
+                break
+
+
+class TCPServerWrapper(TCPServer):
+    """
+    Wrapper over TCP server to implement server initiated shutdown.
+    Adds a flag:= running that a request handler can check and come out of
+    recv loop when shutdown is called.
+    """
+
+    def __init__(self, addr, request_handler):
+        # hmm, TCPServer is not sub-classed from object!
+        if issubclass(TCPServer, object):
+            super(TCPServerWrapper, self).__init__(addr, request_handler)
+        else:
+            TCPServer.__init__(self, addr, request_handler)
+        self.running = False
+
+    def serve_forever(self):
+        self.running = True
+        if issubclass(TCPServer, object):
+            super(TCPServerWrapper, self).serve_forever()
+        else:
+            TCPServer.serve_forever(self)
+
+    def shutdown(self):
+        self.running = False
+        if issubclass(TCPServer, object):
+            super(TCPServerWrapper, self).shutdown()
+        else:
+            TCPServer.shutdown(self)
+
+    def isrunning(self):
+        return self.running
+
+
+class TCPEchoClientTest(BaseHostTest):
+
+    def __init__(self):
+        """
+        Initialise test parameters.
+
+        :return:
+        """
+        BaseHostTest.__init__(self)
+        self.SERVER_IP = None # Will be determined after knowing the target IP
+        self.SERVER_PORT = 0  # Let TCPServer choose an arbitrary port
+        self.server = None
+        self.server_thread = None
+        self.target_ip = None
+
+    @staticmethod
+    def find_interface_to_target_addr(target_ip):
+        """
+        Finds IP address of the interface through which it is connected to the target.
+
+        :return:
+        """
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        try:
+            s.connect((target_ip, 0)) # Target IP, any port
+        except socket.error:
+            s.connect((target_ip, 8000)) # Target IP, 'random' port
+        ip = s.getsockname()[0]
+        s.close()
+        return ip
+
+    def setup_tcp_server(self):
+        """
+        sets up a TCP server for target to connect and send test data.
+
+        :return:
+        """
+        # !NOTE: There should mechanism to assert in the host test
+        if self.SERVER_IP is None:
+            self.log("setup_tcp_server() called before determining server IP!")
+            self.notify_complete(False)
+
+        # Returning none will suppress host test from printing success code
+        self.server = TCPServerWrapper((self.SERVER_IP, self.SERVER_PORT), TCPEchoClientHandler)
+        ip, port = self.server.server_address
+        self.SERVER_PORT = port
+        self.server.allow_reuse_address = True
+        self.log("HOST: Listening for TCP connections: " + self.SERVER_IP + ":" + str(self.SERVER_PORT))
+        self.server_thread = Thread(target=TCPEchoClientTest.server_thread_func, args=(self,))
+        self.server_thread.start()
+
+    @staticmethod
+    def server_thread_func(this):
+        """
+        Thread function to run TCP server forever.
+
+        :param this:
+        :return:
+        """
+        this.server.serve_forever()
+
+    @event_callback("target_ip")
+    def _callback_target_ip(self, key, value, timestamp):
+        """
+        Callback to handle reception of target's IP address.
+
+        :param key:
+        :param value:
+        :param timestamp:
+        :return:
+        """
+        self.target_ip = value
+        self.SERVER_IP = self.find_interface_to_target_addr(self.target_ip)
+        self.setup_tcp_server()
+
+    @event_callback("host_ip")
+    def _callback_host_ip(self, key, value, timestamp):
+        """
+        Callback for request for host IP Addr
+
+        """
+        self.send_kv("host_ip", self.SERVER_IP)
+
+    @event_callback("host_port")
+    def _callback_host_port(self, key, value, timestamp):
+        """
+        Callback for request for host port
+        """
+        self.send_kv("host_port", self.SERVER_PORT)
+
+    def teardown(self):
+        if self.server:
+            self.server.shutdown()
+            self.server_thread.join()
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/tcp_echo.pyc
Binary file esp8266-driver/TESTS/net/host_tests/tcp_echo.pyc has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/udp_echo.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/host_tests/udp_echo.py	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,127 @@
+"""
+mbed SDK
+Copyright (c) 2011-2013 ARM Limited
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import sys
+import socket
+from sys import stdout
+from threading import Thread
+from SocketServer import BaseRequestHandler, UDPServer
+from mbed_host_tests import BaseHostTest, event_callback
+
+
+class UDPEchoClientHandler(BaseRequestHandler):
+    def handle(self):
+        """ UDP packet handler. Echoes data back to sender's address.
+        """
+        data, sock = self.request
+        sock.sendto(data, self.client_address)
+
+
+class UDPEchoClientTest(BaseHostTest):
+
+    def __init__(self):
+        """
+        Initialise test parameters.
+
+        :return:
+        """
+        BaseHostTest.__init__(self)
+        self.SERVER_IP = None # Will be determined after knowing the target IP
+        self.SERVER_PORT = 0  # Let TCPServer choose an arbitrary port
+        self.server = None
+        self.server_thread = None
+        self.target_ip = None
+
+    @staticmethod
+    def find_interface_to_target_addr(target_ip):
+        """
+        Finds IP address of the interface through which it is connected to the target.
+
+        :return:
+        """
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        try:
+            s.connect((target_ip, 0)) # Target IP, any port
+        except socket.error:
+            s.connect((target_ip, 8000)) # Target IP, 'random' port
+        ip = s.getsockname()[0]
+        s.close()
+        return ip
+
+    def setup_udp_server(self):
+        """
+        sets up a UDP server for target to connect and send test data.
+
+        :return:
+        """
+        # !NOTE: There should mechanism to assert in the host test
+        if self.SERVER_IP is None:
+            self.log("setup_udp_server() called before determining server IP!")
+            self.notify_complete(False)
+
+        # Returning none will suppress host test from printing success code
+        self.server = UDPServer((self.SERVER_IP, self.SERVER_PORT), UDPEchoClientHandler)
+        ip, port = self.server.server_address
+        self.SERVER_PORT = port
+        self.server.allow_reuse_address = True
+        self.log("HOST: Listening for UDP packets: " + self.SERVER_IP + ":" + str(self.SERVER_PORT))
+        self.server_thread = Thread(target=UDPEchoClientTest.server_thread_func, args=(self,))
+        self.server_thread.start()
+
+    @staticmethod
+    def server_thread_func(this):
+        """
+        Thread function to run TCP server forever.
+
+        :param this:
+        :return:
+        """
+        this.server.serve_forever()
+
+    @event_callback("target_ip")
+    def _callback_target_ip(self, key, value, timestamp):
+        """
+        Callback to handle reception of target's IP address.
+
+        :param key:
+        :param value:
+        :param timestamp:
+        :return:
+        """
+        self.target_ip = value
+        self.SERVER_IP = self.find_interface_to_target_addr(self.target_ip)
+        self.setup_udp_server()
+
+    @event_callback("host_ip")
+    def _callback_host_ip(self, key, value, timestamp):
+        """
+        Callback for request for host IP Addr
+
+        """
+        self.send_kv("host_ip", self.SERVER_IP)
+
+    @event_callback("host_port")
+    def _callback_host_port(self, key, value, timestamp):
+        """
+        Callback for request for host port
+        """
+        self.send_kv("host_port", self.SERVER_PORT)
+
+    def teardown(self):
+        if self.server:
+            self.server.shutdown()
+            self.server_thread.join()
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/udp_echo.pyc
Binary file esp8266-driver/TESTS/net/host_tests/udp_echo.pyc has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/udp_shotgun.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/host_tests/udp_shotgun.py	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,142 @@
+"""
+mbed SDK
+Copyright (c) 2011-2013 ARM Limited
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import sys
+import socket
+import json
+import random
+import itertools
+import time
+from sys import stdout
+from threading import Thread
+from SocketServer import BaseRequestHandler, UDPServer
+from mbed_host_tests import BaseHostTest, event_callback
+
+
+class UDPEchoClientHandler(BaseRequestHandler):
+    def handle(self):
+        """ UDP packet handler. Responds with multiple simultaneous packets
+        """
+        data, sock = self.request
+        pattern = [ord(d) << 4 for d in data]
+
+        # Each byte in request indicates size of packet to recieve
+        # Each packet size is shifted over by 4 to fit in a byte, which
+        # avoids any issues with endianess or decoding
+        for packet in pattern:
+            data = [random.randint(0, 255) for _ in range(packet-1)]
+            data.append(reduce(lambda a,b: a^b, data))
+            data = ''.join(map(chr, data))
+            sock.sendto(data, self.client_address)
+
+            # Sleep a tiny bit to compensate for local network
+            time.sleep(0.01)
+
+
+class UDPEchoClientTest(BaseHostTest):
+    def __init__(self):
+        """
+        Initialise test parameters.
+
+        :return:
+        """
+        BaseHostTest.__init__(self)
+        self.SERVER_IP = None # Will be determined after knowing the target IP
+        self.SERVER_PORT = 0  # Let TCPServer choose an arbitrary port
+        self.server = None
+        self.server_thread = None
+        self.target_ip = None
+
+    @staticmethod
+    def find_interface_to_target_addr(target_ip):
+        """
+        Finds IP address of the interface through which it is connected to the target.
+
+        :return:
+        """
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        try:
+            s.connect((target_ip, 0)) # Target IP, any port
+        except socket.error:
+            s.connect((target_ip, 8000)) # Target IP, 'random' port
+        ip = s.getsockname()[0]
+        s.close()
+        return ip
+
+    def setup_udp_server(self):
+        """
+        sets up a UDP server for target to connect and send test data.
+
+        :return:
+        """
+        # !NOTE: There should mechanism to assert in the host test
+        if self.SERVER_IP is None:
+            self.log("setup_udp_server() called before determining server IP!")
+            self.notify_complete(False)
+
+        # Returning none will suppress host test from printing success code
+        self.server = UDPServer((self.SERVER_IP, self.SERVER_PORT), UDPEchoClientHandler)
+        ip, port = self.server.server_address
+        self.SERVER_PORT = port
+        self.server.allow_reuse_address = True
+        self.log("HOST: Listening for UDP packets: " + self.SERVER_IP + ":" + str(self.SERVER_PORT))
+        self.server_thread = Thread(target=UDPEchoClientTest.server_thread_func, args=(self,))
+        self.server_thread.start()
+
+    @staticmethod
+    def server_thread_func(this):
+        """
+        Thread function to run TCP server forever.
+
+        :param this:
+        :return:
+        """
+        this.server.serve_forever()
+
+    @event_callback("target_ip")
+    def _callback_target_ip(self, key, value, timestamp):
+        """
+        Callback to handle reception of target's IP address.
+
+        :param key:
+        :param value:
+        :param timestamp:
+        :return:
+        """
+        self.target_ip = value
+        self.SERVER_IP = self.find_interface_to_target_addr(self.target_ip)
+        self.setup_udp_server()
+
+    @event_callback("host_ip")
+    def _callback_host_ip(self, key, value, timestamp):
+        """
+        Callback for request for host IP Addr
+
+        """
+        self.send_kv("host_ip", self.SERVER_IP)
+
+    @event_callback("host_port")
+    def _callback_host_port(self, key, value, timestamp):
+        """
+        Callback for request for host port
+        """
+        self.send_kv("host_port", self.SERVER_PORT)
+
+    def teardown(self):
+        if self.server:
+            self.server.shutdown()
+            self.server_thread.join()
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/host_tests/udp_shotgun.pyc
Binary file esp8266-driver/TESTS/net/host_tests/udp_shotgun.pyc has changed
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/tcp_echo/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/tcp_echo/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,118 @@
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "TCPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE
+#define MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE 256
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+namespace {
+    char tx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
+    char rx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
+    const char ASCII_MAX = '~' - ' ';
+}
+
+void prep_buffer(char *tx_buffer, size_t tx_size) {
+    for (size_t i=0; i<tx_size; ++i) {
+        tx_buffer[i] = (rand() % 10) + '0';
+    }
+}
+
+void test_tcp_echo() {
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+
+    if (err) {
+        printf("MBED: failed to connect with an error of %d\r\n", err);
+        TEST_ASSERT_EQUAL(0, err);
+    }
+
+    printf("MBED: TCPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: TCPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    bool result = false;
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+
+    TCPSocket sock(&net);
+    SocketAddress tcp_addr(ipbuf, port);
+    if (sock.connect(tcp_addr) == 0) {
+        printf("HTTP: Connected to %s:%d\r\n", ipbuf, port);
+        printf("tx_buffer buffer size: %u\r\n", sizeof(tx_buffer));
+        printf("rx_buffer buffer size: %u\r\n", sizeof(rx_buffer));
+
+        prep_buffer(tx_buffer, sizeof(tx_buffer));
+        sock.send(tx_buffer, sizeof(tx_buffer));
+        printf("MBED: Finished sending\r\n");
+        // Server will respond with HTTP GET's success code
+        const int ret = sock.recv(rx_buffer, sizeof(rx_buffer));
+        printf("MBED: Finished receiving\r\n");
+
+        result = !memcmp(tx_buffer, rx_buffer, sizeof(tx_buffer));
+        TEST_ASSERT_EQUAL(ret, sizeof(rx_buffer));
+        TEST_ASSERT_EQUAL(true, result);
+    }
+
+    sock.close();
+    net.disconnect();
+    TEST_ASSERT_EQUAL(true, result);
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "tcp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("TCP echo", test_tcp_echo),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/tcp_echo_parallel/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/tcp_echo_parallel/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,165 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Parallel tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "TCPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE
+#define MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE 64
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_ECHO_THREADS
+#define MBED_CFG_TCP_CLIENT_ECHO_THREADS 3
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+SocketAddress tcp_addr;
+Mutex iomutex;
+
+void prep_buffer(char *tx_buffer, size_t tx_size) {
+    for (size_t i=0; i<tx_size; ++i) {
+        tx_buffer[i] = (rand() % 10) + '0';
+    }
+}
+
+
+// Each echo class is in charge of one parallel transaction
+class Echo {
+private:
+    char tx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE];
+    char rx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE];
+
+    TCPSocket sock;
+    Thread thread;
+
+public:
+    // Limiting stack size to 1k
+    Echo(): thread(osPriorityNormal, 1024) {
+    }
+
+    void start() {
+        osStatus status = thread.start(callback(this, &Echo::echo));
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void join() {
+        osStatus status = thread.join();
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void echo() {
+        int err = sock.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+
+        err = sock.connect(tcp_addr);
+        TEST_ASSERT_EQUAL(0, err);
+
+        iomutex.lock();
+        printf("HTTP: Connected to %s:%d\r\n",
+                tcp_addr.get_ip_address(), tcp_addr.get_port());
+        printf("tx_buffer buffer size: %u\r\n", sizeof(tx_buffer));
+        printf("rx_buffer buffer size: %u\r\n", sizeof(rx_buffer));
+        iomutex.unlock();
+
+        prep_buffer(tx_buffer, sizeof(tx_buffer));
+        sock.send(tx_buffer, sizeof(tx_buffer));
+
+        // Server will respond with HTTP GET's success code
+        const int ret = sock.recv(rx_buffer, sizeof(rx_buffer));
+        bool result = !memcmp(tx_buffer, rx_buffer, sizeof(tx_buffer));
+        TEST_ASSERT_EQUAL(ret, sizeof(rx_buffer));
+        TEST_ASSERT_EQUAL(true, result);
+
+        err = sock.close();
+        TEST_ASSERT_EQUAL(0, err);
+    }
+};
+
+Echo *echoers[MBED_CFG_TCP_CLIENT_ECHO_THREADS];
+
+
+void test_tcp_echo_parallel() {
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: TCPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: TCPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+    tcp_addr.set_ip_address(ipbuf);
+    tcp_addr.set_port(port);
+
+    // Startup echo threads in parallel
+    for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
+        echoers[i] = new Echo;
+        echoers[i]->start();
+    }
+
+    for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
+        echoers[i]->join();
+        delete echoers[i];
+    }
+
+    net.disconnect();
+}
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "tcp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("TCP echo parallel", test_tcp_echo_parallel),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/tcp_hello_world/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/tcp_hello_world/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,120 @@
+#include <algorithm>
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "TCPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+namespace {
+    // Test connection information
+    const char *HTTP_SERVER_NAME = "developer.mbed.org";
+    const char *HTTP_SERVER_FILE_PATH = "/media/uploads/mbed_official/hello.txt";
+    const int HTTP_SERVER_PORT = 80;
+#if defined(TARGET_VK_RZ_A1H)
+    const int RECV_BUFFER_SIZE = 300;
+#else
+    const int RECV_BUFFER_SIZE = 512;
+#endif
+    // Test related data
+    const char *HTTP_OK_STR = "200 OK";
+    const char *HTTP_HELLO_STR = "Hello world!";
+
+    // Test buffers
+    char buffer[RECV_BUFFER_SIZE] = {0};
+}
+
+bool find_substring(const char *first, const char *last, const char *s_first, const char *s_last) {
+    const char *f = std::search(first, last, s_first, s_last);
+    return (f != last);
+}
+
+void test_tcp_hello_world() {
+    bool result = false;
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    printf("TCP client IP Address is %s\r\n", net.get_ip_address());
+
+    TCPSocket sock(&net);
+    printf("HTTP: Connection to %s:%d\r\n", HTTP_SERVER_NAME, HTTP_SERVER_PORT);
+    if (sock.connect(HTTP_SERVER_NAME, HTTP_SERVER_PORT) == 0) {
+        printf("HTTP: OK\r\n");
+
+        // We are constructing GET command like this:
+        // GET http://developer.mbed.org/media/uploads/mbed_official/hello.txt HTTP/1.0\n\n
+        strcpy(buffer, "GET http://");
+        strcat(buffer, HTTP_SERVER_NAME);
+        strcat(buffer, HTTP_SERVER_FILE_PATH);
+        strcat(buffer, " HTTP/1.0\n\n");
+        // Send GET command
+        sock.send(buffer, strlen(buffer));
+
+        // Server will respond with HTTP GET's success code
+        const int ret = sock.recv(buffer, sizeof(buffer) - 1);
+        buffer[ret] = '\0';
+
+        // Find 200 OK HTTP status in reply
+        bool found_200_ok = find_substring(buffer, buffer + ret, HTTP_OK_STR, HTTP_OK_STR + strlen(HTTP_OK_STR));
+        // Find "Hello World!" string in reply
+        bool found_hello = find_substring(buffer, buffer + ret, HTTP_HELLO_STR, HTTP_HELLO_STR + strlen(HTTP_HELLO_STR));
+
+        TEST_ASSERT_TRUE(found_200_ok);
+        TEST_ASSERT_TRUE(found_hello);
+
+        if (found_200_ok && found_hello) result = true;
+
+        printf("HTTP: Received %d chars from server\r\n", ret);
+        printf("HTTP: Received 200 OK status ... %s\r\n", found_200_ok ? "[OK]" : "[FAIL]");
+        printf("HTTP: Received '%s' status ... %s\r\n", HTTP_HELLO_STR, found_hello ? "[OK]" : "[FAIL]");
+        printf("HTTP: Received message:\r\n");
+        printf("%s", buffer);
+        sock.close();
+    } else {
+        printf("HTTP: ERROR\r\n");
+    }
+
+    net.disconnect();
+    TEST_ASSERT_EQUAL(true, result);
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "default_auto", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("TCP hello world", test_tcp_hello_world),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/tcp_packet_pressure/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/tcp_packet_pressure/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,259 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Pressure tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "TCPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN 64
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+// Simple xorshift pseudorandom number generator
+class RandSeq {
+private:
+    uint32_t x;
+    uint32_t y;
+    static const int A = 15;
+    static const int B = 18;
+    static const int C = 11;
+
+public:
+    RandSeq(uint32_t seed=MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED)
+        : x(seed), y(seed) {}
+
+    uint32_t next(void) {
+        x ^= x << A;
+        x ^= x >> B;
+        x ^= y ^ (y >> C);
+        return x + y;
+    }
+
+    void skip(size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            next();
+        }
+    }
+
+    void buffer(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            buffer[i] = lookahead.next() & 0xff;
+        }
+    }
+
+    int cmp(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            int diff = buffer[i] - (lookahead.next() & 0xff);
+            if (diff != 0) {
+                return diff;
+            }
+        }
+        return 0;
+    }
+};
+
+// Shared buffer for network transactions
+uint8_t *buffer;
+size_t buffer_size;
+
+// Tries to get the biggest buffer possible on the device. Exponentially
+// grows a buffer until heap runs out of space, and uses half to leave
+// space for the rest of the program
+void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
+    size_t i = min;
+    while (i < max) {
+        void *b = malloc(i);
+        if (!b) {
+            i /= 4;
+            if (i < min) {
+                i = min;
+            }
+            break;
+        }
+        free(b);
+        i *= 2;
+    }
+
+    *buffer = (uint8_t *)malloc(i);
+    *size = i;
+    TEST_ASSERT(buffer);
+}
+
+
+void test_tcp_packet_pressure() {
+    generate_buffer(&buffer, &buffer_size,
+        MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
+        MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
+    printf("MBED: Generated buffer %d\r\n", buffer_size);
+
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: TCPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: TCPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+
+    TCPSocket sock;
+    SocketAddress tcp_addr(ipbuf, port);
+
+    Timer timer;
+    timer.start();
+
+    // Tests exponentially growing sequences
+    for (size_t size = MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN;
+         size < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX;
+         size *= 2) {
+        err = sock.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+        err = sock.connect(tcp_addr);
+        TEST_ASSERT_EQUAL(0, err);
+        printf("TCP: %s:%d streaming %d bytes\r\n", ipbuf, port, size);
+
+        sock.set_blocking(false);
+
+        // Loop to send/recv all data
+        RandSeq tx_seq;
+        RandSeq rx_seq;
+        size_t rx_count = 0;
+        size_t tx_count = 0;
+        size_t window = buffer_size;
+
+        while (tx_count < size || rx_count < size) {
+            // Send out data
+            if (tx_count < size) {
+                size_t chunk_size = size - tx_count;
+                if (chunk_size > window) {
+                    chunk_size = window;
+                }
+
+                tx_seq.buffer(buffer, chunk_size);
+                int td = sock.send(buffer, chunk_size);
+
+                if (td > 0) {
+                    if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("TCP: tx -> %d\r\n", td);
+                    }
+                    tx_seq.skip(td);
+                    tx_count += td;
+                } else if (td != NSAPI_ERROR_WOULD_BLOCK) {
+                    // We may fail to send because of buffering issues,
+                    // cut buffer in half
+                    if (window > MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) {
+                        window /= 2;
+                    }
+
+                    if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("TCP: Not sent (%d), window = %d\r\n", td, window);
+                    }
+                }
+            }
+
+            // Verify recieved data
+            while (rx_count < size) {
+                int rd = sock.recv(buffer, buffer_size);
+                TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
+                if (rd > 0) {
+                    if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("TCP: rx <- %d\r\n", rd);
+                    }
+                    int diff = rx_seq.cmp(buffer, rd);
+                    TEST_ASSERT_EQUAL(0, diff);
+                    rx_seq.skip(rd);
+                    rx_count += rd;
+                } else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
+                    break;
+                }
+            }
+        }
+
+        err = sock.close();
+        TEST_ASSERT_EQUAL(0, err);
+    }
+
+    timer.stop();
+    printf("MBED: Time taken: %fs\r\n", timer.read());
+    printf("MBED: Speed: %.3fkb/s\r\n",
+            8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX - 
+            MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
+
+    net.disconnect();
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "tcp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("TCP packet pressure", test_tcp_packet_pressure),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/tcp_packet_pressure_parallel/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/tcp_packet_pressure_parallel/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,321 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "TCPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN 64
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS 3
+#endif
+
+#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG
+#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+// Simple xorshift pseudorandom number generator
+class RandSeq {
+private:
+    uint32_t x;
+    uint32_t y;
+    static const int A = 15;
+    static const int B = 18;
+    static const int C = 11;
+
+public:
+    RandSeq(uint32_t seed=MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED)
+        : x(seed), y(seed) {}
+
+    uint32_t next(void) {
+        x ^= x << A;
+        x ^= x >> B;
+        x ^= y ^ (y >> C);
+        return x + y;
+    }
+
+    void skip(size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            next();
+        }
+    }
+
+    void buffer(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            buffer[i] = lookahead.next() & 0xff;
+        }
+    }
+
+    int cmp(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            int diff = buffer[i] - (lookahead.next() & 0xff);
+            if (diff != 0) {
+                return diff;
+            }
+        }
+        return 0;
+    }
+};
+
+
+// Tries to get the biggest buffer possible on the device. Exponentially
+// grows a buffer until heap runs out of space, and uses half to leave
+// space for the rest of the program
+void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
+    size_t i = min;
+    while (i < max) {
+        void *b = malloc(i);
+        if (!b) {
+            i /= 4;
+            if (i < min) {
+                i = min;
+            }
+            break;
+        }
+        free(b);
+        i *= 2;
+    }
+
+    *buffer = (uint8_t *)malloc(i);
+    *size = i;
+    TEST_ASSERT(buffer);
+}
+
+
+// Global variables shared between pressure tests
+ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+SocketAddress tcp_addr;
+Timer timer;
+Mutex iomutex;
+
+// Single instance of a pressure test
+class PressureTest {
+private:
+    uint8_t *buffer;
+    size_t buffer_size;
+
+    TCPSocket sock;
+    Thread thread;
+
+public:
+    PressureTest(uint8_t *buffer, size_t buffer_size)
+        : buffer(buffer), buffer_size(buffer_size) {
+    }
+
+    void start() {
+        osStatus status = thread.start(callback(this, &PressureTest::run));
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void join() {
+        osStatus status = thread.join();
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void run() {
+        // Tests exponentially growing sequences
+        for (size_t size = MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN;
+             size < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX;
+             size *= 2) {
+            int err = sock.open(&net);
+            TEST_ASSERT_EQUAL(0, err);
+            err = sock.connect(tcp_addr);
+            TEST_ASSERT_EQUAL(0, err);
+            iomutex.lock();
+            printf("TCP: %s:%d streaming %d bytes\r\n",
+                tcp_addr.get_ip_address(), tcp_addr.get_port(), size);
+            iomutex.unlock();
+
+            sock.set_blocking(false);
+
+            // Loop to send/recv all data
+            RandSeq tx_seq;
+            RandSeq rx_seq;
+            size_t rx_count = 0;
+            size_t tx_count = 0;
+            size_t window = buffer_size;
+
+            while (tx_count < size || rx_count < size) {
+                // Send out data
+                if (tx_count < size) {
+                    size_t chunk_size = size - tx_count;
+                    if (chunk_size > window) {
+                        chunk_size = window;
+                    }
+
+                    tx_seq.buffer(buffer, chunk_size);
+                    int td = sock.send(buffer, chunk_size);
+
+                    if (td > 0) {
+                        if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("TCP: tx -> %d\r\n", td);
+                            iomutex.unlock();
+                        }
+                        tx_seq.skip(td);
+                        tx_count += td;
+                    } else if (td != NSAPI_ERROR_WOULD_BLOCK) {
+                        // We may fail to send because of buffering issues,
+                        // cut buffer in half
+                        if (window > MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) {
+                            window /= 2;
+                        }
+
+                        if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("TCP: Not sent (%d), window = %d\r\n", td, window);
+                            iomutex.unlock();
+                        }
+                    }
+                }
+
+                // Verify recieved data
+                while (rx_count < size) {
+                    int rd = sock.recv(buffer, buffer_size);
+                    TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
+                    if (rd > 0) {
+                        if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("TCP: rx <- %d\r\n", rd);
+                            iomutex.unlock();
+                        }
+                        int diff = rx_seq.cmp(buffer, rd);
+                        TEST_ASSERT_EQUAL(0, diff);
+                        rx_seq.skip(rd);
+                        rx_count += rd;
+                    } else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
+                        break;
+                    }
+                }
+            }
+
+            err = sock.close();
+            TEST_ASSERT_EQUAL(0, err);
+        }
+    }
+};
+
+PressureTest *pressure_tests[MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS];
+
+
+void test_tcp_packet_pressure_parallel() {
+    uint8_t *buffer;
+    size_t buffer_size;
+    generate_buffer(&buffer, &buffer_size,
+        MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
+        MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
+
+    size_t buffer_subsize = buffer_size / MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS;
+    printf("MBED: Generated buffer %d\r\n", buffer_size);
+    printf("MBED: Split into %d buffers %d\r\n",
+            MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS,
+            buffer_subsize);
+
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: TCPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: TCPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+    tcp_addr.set_ip_address(ipbuf);
+    tcp_addr.set_port(port);
+
+    timer.start();
+
+    // Startup pressure tests in parallel
+    for (int i = 0; i < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
+        pressure_tests[i] = new PressureTest(&buffer[i*buffer_subsize], buffer_subsize);
+        pressure_tests[i]->start();
+    }
+
+    for (int i = 0; i < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
+        pressure_tests[i]->join();
+        delete pressure_tests[i];
+    }
+
+    timer.stop();
+    printf("MBED: Time taken: %fs\r\n", timer.read());
+    printf("MBED: Speed: %.3fkb/s\r\n",
+            MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS*
+            8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX - 
+            MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
+
+    net.disconnect();
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "tcp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("TCP packet pressure parallel", test_tcp_packet_pressure_parallel),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/udp_dtls_handshake/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/udp_dtls_handshake/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,165 @@
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "UDPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE
+#define MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE 512
+#endif
+
+#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_RETRIES
+#define MBED_CFG_UDP_DTLS_HANDSHAKE_RETRIES 16
+#endif
+
+#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_PATTERN
+#define MBED_CFG_UDP_DTLS_HANDSHAKE_PATTERN 112, 384, 200, 219, 25
+#endif
+
+#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT
+#define MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT 1500
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+uint8_t buffer[MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE] = {0};
+int udp_dtls_handshake_pattern[] = {MBED_CFG_UDP_DTLS_HANDSHAKE_PATTERN};
+const int udp_dtls_handshake_count = sizeof(udp_dtls_handshake_pattern) / sizeof(int);
+
+void test_udp_dtls_handshake() {
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: UDPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: UDPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    bool result = false;
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
+
+    // align each size to 4-bits
+    for (int i = 0; i < udp_dtls_handshake_count; i++) {
+        udp_dtls_handshake_pattern[i] = (~0xf & udp_dtls_handshake_pattern[i]) + 0x10;
+    }
+
+    printf("MBED: DTLS pattern [");
+    for (int i = 0; i < udp_dtls_handshake_count; i++) {
+        printf("%d", udp_dtls_handshake_pattern[i]);
+        if (i != udp_dtls_handshake_count-1) {
+            printf(", ");
+        }
+    }
+    printf("]\r\n");
+
+    UDPSocket sock;
+    SocketAddress udp_addr(ipbuf, port);
+    sock.set_timeout(MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT);
+
+    for (int attempt = 0; attempt < MBED_CFG_UDP_DTLS_HANDSHAKE_RETRIES; attempt++) {
+        err = sock.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+
+        for (int i = 0; i < udp_dtls_handshake_count; i++) {
+            buffer[i] = udp_dtls_handshake_pattern[i] >> 4;
+        }
+
+        err = sock.sendto(udp_addr, buffer, udp_dtls_handshake_count);
+        printf("UDP: tx -> %d\r\n", err);
+        TEST_ASSERT_EQUAL(udp_dtls_handshake_count, err);
+
+        int step = 0;
+        while (step < udp_dtls_handshake_count) {
+            err = sock.recvfrom(NULL, buffer, sizeof(buffer));
+            printf("UDP: rx <- %d ", err);
+
+            // check length
+            if (err != udp_dtls_handshake_pattern[step]) {
+                printf("x (expected %d)\r\n", udp_dtls_handshake_pattern[step]);
+                break;
+            }
+
+            // check quick xor of packet
+            uint8_t check = 0;
+            for (int j = 0; j < udp_dtls_handshake_pattern[step]; j++) {
+                check ^= buffer[j];
+            }
+
+            if (check != 0) {
+                printf("x (checksum 0x%02x)\r\n", check);
+                break;
+            }
+
+            // successfully got a packet
+            printf("\r\n");
+            step += 1;
+        }
+
+        err = sock.close();
+        TEST_ASSERT_EQUAL(0, err);
+
+        // got through all steps, test passed
+        if (step == udp_dtls_handshake_count) {
+            result = true;
+            break;
+        }
+    }
+
+    net.disconnect();
+    TEST_ASSERT_EQUAL(true, result);
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "udp_shotgun", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("UDP DTLS handshake", test_udp_dtls_handshake),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/udp_echo/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/udp_echo/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,156 @@
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "UDPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
+#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
+#define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+namespace {
+    char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
+    char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
+    const char ASCII_MAX = '~' - ' ';
+    const int ECHO_LOOPS = 16;
+    char uuid[48] = {0};
+}
+
+void prep_buffer(char *uuid, char *tx_buffer, size_t tx_size) {
+    size_t i = 0;
+
+    memcpy(tx_buffer, uuid, strlen(uuid));
+    i += strlen(uuid);
+
+    tx_buffer[i++] = ' ';
+
+    for (; i<tx_size; ++i) {
+        tx_buffer[i] = (rand() % 10) + '0';
+    }
+}
+
+void test_udp_echo() {
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    if (err) {
+        printf("MBED: failed to connect with an error of %d\r\n", err);
+        TEST_ASSERT_EQUAL(0, err);
+    }
+
+    printf("UDP client IP Address is %s\n", net.get_ip_address());
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    UDPSocket sock;
+    sock.open(&net);
+    sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
+    SocketAddress udp_addr(ipbuf, port);
+
+    int success = 0;
+    for (int i = 0; success < ECHO_LOOPS; i++) {
+        prep_buffer(uuid, tx_buffer, sizeof(tx_buffer));
+        const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
+        if (ret >= 0) {
+            printf("[%02d] sent %d bytes - %.*s  \n", i, ret, ret, tx_buffer);
+        } else {
+            printf("[%02d] Network error %d\n", i, ret);
+            continue;
+        }
+
+        SocketAddress temp_addr;
+        const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
+        if (n >= 0) {
+            printf("[%02d] recv %d bytes - %.*s  \n", i, n, n, tx_buffer);
+        } else {
+            printf("[%02d] Network error %d\n", i, n);
+            continue;
+        }
+
+        if ((temp_addr == udp_addr &&
+             n == sizeof(tx_buffer) &&
+             memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
+            success += 1;
+
+            printf("[%02d] success #%d\n", i, success);
+            continue;
+        }
+
+        // failed, clean out any remaining bad packets
+        sock.set_timeout(0);
+        while (true) {
+            err = sock.recvfrom(NULL, NULL, 0);
+            if (err == NSAPI_ERROR_WOULD_BLOCK) {
+                break;
+            }
+        }
+        sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
+    }
+
+    sock.close();
+    net.disconnect();
+    TEST_ASSERT_EQUAL(ECHO_LOOPS, success);
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    GREENTEA_SETUP_UUID(120, "udp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("UDP echo", test_udp_echo),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/udp_echo_parallel/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/udp_echo_parallel/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,236 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Parallel tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "UDPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
+#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
+#define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_ECHO_THREADS
+#define MBED_CFG_UDP_CLIENT_ECHO_THREADS 3
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+const int ECHO_LOOPS = 16;
+ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+SocketAddress udp_addr;
+Mutex iomutex;
+char uuid[48] = {0};
+
+// NOTE: assuming that "id" stays in the single digits
+void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size) {
+    size_t i = 0;
+
+    tx_buffer[i++] = '0' + id;
+    tx_buffer[i++] = ' ';
+
+    memcpy(tx_buffer+i, uuid, strlen(uuid));
+    i += strlen(uuid);
+
+    tx_buffer[i++] = ' ';
+
+    for (; i<tx_size; ++i) {
+        tx_buffer[i] = (rand() % 10) + '0';
+    }
+}
+
+
+// Each echo class is in charge of one parallel transaction
+class Echo {
+private:
+    char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
+    char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
+
+    UDPSocket sock;
+    Thread thread;
+    bool result;
+    int id;
+    char *uuid;
+
+public:
+    // Limiting stack size to 1k
+    Echo(): thread(osPriorityNormal, 1024), result(false) {
+    }
+
+    void start(int id, char *uuid) {
+        this->id = id;
+        this->uuid = uuid;
+        osStatus status = thread.start(callback(this, &Echo::echo));
+    }
+
+    void join() {
+        osStatus status = thread.join();
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void echo() {
+        int success = 0;
+
+        int err = sock.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+
+        sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
+
+        for (int i = 0; success < ECHO_LOOPS; i++) {
+            prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer));
+            const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
+            if (ret >= 0) {
+                iomutex.lock();
+                printf("[ID:%01d][%02d] sent %d bytes - %.*s  \n", id, i, ret, ret, tx_buffer);
+                iomutex.unlock();
+            } else {
+                iomutex.lock();
+                printf("[ID:%01d][%02d] Network error %d\n", id, i, ret);
+                iomutex.unlock();
+                continue;
+            }
+
+            SocketAddress temp_addr;
+            const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
+            if (n >= 0) {
+                iomutex.lock();
+                printf("[ID:%01d][%02d] recv %d bytes - %.*s  \n", id, i, n, n, tx_buffer);
+                iomutex.unlock();
+            } else {
+                iomutex.lock();
+                printf("[ID:%01d][%02d] Network error %d\n", id, i, n);
+                iomutex.unlock();
+                continue;
+            }
+
+            if ((temp_addr == udp_addr &&
+                 n == sizeof(tx_buffer) &&
+                 memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
+                success += 1;
+                iomutex.lock();
+                printf("[ID:%01d][%02d] success #%d\n", id, i, success);
+                iomutex.unlock();
+                continue;
+            }
+
+            // failed, clean out any remaining bad packets
+            sock.set_timeout(0);
+            while (true) {
+                err = sock.recvfrom(NULL, NULL, 0);
+                if (err == NSAPI_ERROR_WOULD_BLOCK) {
+                    break;
+                }
+            }
+            sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
+        }
+
+        result = success == ECHO_LOOPS;
+
+        err = sock.close();
+        TEST_ASSERT_EQUAL(0, err);
+        if (err) {
+            result = false;
+        }
+    }
+
+    bool get_result() {
+        return result;
+    }
+};
+
+Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
+
+
+void test_udp_echo_parallel() {
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    if (err) {
+        printf("MBED: failed to connect with an error of %d\r\n", err);
+        GREENTEA_TESTSUITE_RESULT(false);
+    } else {
+        printf("UDP client IP Address is %s\n", net.get_ip_address());
+
+        greentea_send_kv("target_ip", net.get_ip_address());
+
+        char recv_key[] = "host_port";
+        char ipbuf[60] = {0};
+        char portbuf[16] = {0};
+        unsigned int port = 0;
+
+        greentea_send_kv("host_ip", " ");
+        greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+        greentea_send_kv("host_port", " ");
+        greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+        sscanf(portbuf, "%u", &port);
+
+        printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
+        udp_addr.set_ip_address(ipbuf);
+        udp_addr.set_port(port);
+
+        // Startup echo threads in parallel
+        for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
+            echoers[i] = new Echo;
+            echoers[i]->start(i, uuid);
+        }
+
+        bool result = true;
+
+        for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
+            echoers[i]->join();
+            result = result && echoers[i]->get_result();
+            delete echoers[i];
+        }
+
+        net.disconnect();
+        TEST_ASSERT_EQUAL(true, result);
+    }
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    GREENTEA_SETUP_UUID(120, "udp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("UDP echo parallel", test_udp_echo_parallel),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/udp_packet_pressure/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/udp_packet_pressure/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,282 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Pressure tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "UDPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN 64
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+// Simple xorshift pseudorandom number generator
+class RandSeq {
+private:
+    uint32_t x;
+    uint32_t y;
+    static const int A = 15;
+    static const int B = 18;
+    static const int C = 11;
+
+public:
+    RandSeq(uint32_t seed=MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED)
+        : x(seed), y(seed) {}
+
+    uint32_t next(void) {
+        x ^= x << A;
+        x ^= x >> B;
+        x ^= y ^ (y >> C);
+        return x + y;
+    }
+
+    void skip(size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            next();
+        }
+    }
+
+    void buffer(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            buffer[i] = lookahead.next() & 0xff;
+        }
+    }
+
+    int cmp(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            int diff = buffer[i] - (lookahead.next() & 0xff);
+            if (diff != 0) {
+                return diff;
+            }
+        }
+        return 0;
+    }
+};
+
+// Shared buffer for network transactions
+uint8_t *buffer;
+size_t buffer_size;
+
+// Tries to get the biggest buffer possible on the device. Exponentially
+// grows a buffer until heap runs out of space, and uses half to leave
+// space for the rest of the program
+void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
+    size_t i = min;
+    while (i < max) {
+        void *b = malloc(i);
+        if (!b) {
+            i /= 4;
+            if (i < min) {
+                i = min;
+            }
+            break;
+        }
+        free(b);
+        i *= 2;
+    }
+
+    *buffer = (uint8_t *)malloc(i);
+    *size = i;
+    TEST_ASSERT(buffer);
+}
+
+void test_udp_packet_pressure() {
+    generate_buffer(&buffer, &buffer_size,
+        MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN,
+        MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX);
+    printf("MBED: Generated buffer %d\r\n", buffer_size);
+
+    ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: UDPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: UDPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+
+    UDPSocket sock;
+    SocketAddress udp_addr(ipbuf, port);
+
+    Timer timer;
+    timer.start();
+
+    // Tests exponentially growing sequences
+    for (size_t size = MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
+         size < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX;
+         size *= 2) {
+        err = sock.open(&net);
+        TEST_ASSERT_EQUAL(0, err);
+        printf("UDP: %s:%d streaming %d bytes\r\n", ipbuf, port, size);
+
+        sock.set_blocking(false);
+
+        // Loop to send/recv all data
+        RandSeq tx_seq;
+        RandSeq rx_seq;
+        size_t rx_count = 0;
+        size_t tx_count = 0;
+        int known_time = timer.read_ms();
+        size_t window = buffer_size;
+
+        while (tx_count < size || rx_count < size) {
+            // Send out packets
+            if (tx_count < size) {
+                size_t chunk_size = size - tx_count;
+                if (chunk_size > window) {
+                    chunk_size = window;
+                }
+
+                tx_seq.buffer(buffer, chunk_size);
+                int td = sock.sendto(udp_addr, buffer, chunk_size);
+
+                if (td > 0) {
+                    if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("UDP: tx -> %d\r\n", td);
+                    }
+                    tx_seq.skip(td);
+                    tx_count += td;
+                } else if (td != NSAPI_ERROR_WOULD_BLOCK) {
+                    // We may fail to send because of buffering issues, revert to
+                    // last good sequence and cut buffer in half
+                    if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
+                        window /= 2;
+                    }
+
+                    if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("UDP: Not sent (%d), window = %d\r\n", td, window);
+                    }
+                }
+            }
+
+            // Prioritize recieving over sending packets to avoid flooding
+            // the network while handling erronous packets
+            while (rx_count < size) {
+                int rd = sock.recvfrom(NULL, buffer, buffer_size);
+                TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
+
+                if (rd > 0) {
+                    if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("UDP: rx <- %d\r\n", rd);
+                    }
+
+                    if (rx_seq.cmp(buffer, rd) == 0) {
+                        rx_seq.skip(rd);
+                        rx_count += rd;
+                        known_time = timer.read_ms();
+                        if (window < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX) {
+                            window += MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
+                        }
+                    }
+                } else if (timer.read_ms() - known_time >
+                        MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
+                    // Dropped packet or out of order, revert to last good sequence
+                    // and cut buffer in half
+                    tx_seq = rx_seq;
+                    tx_count = rx_count;
+                    known_time = timer.read_ms();
+                    if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
+                        window /= 2;
+                    }
+
+                    if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                        printf("UDP: Dropped, window = %d\r\n", window);
+                    }
+                } else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
+                    break;
+                }
+            }
+        }
+
+        err = sock.close();
+        TEST_ASSERT_EQUAL(0, err);
+    }
+
+    timer.stop();
+    printf("MBED: Time taken: %fs\r\n", timer.read());
+    printf("MBED: Speed: %.3fkb/s\r\n",
+            8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX - 
+            MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
+
+    net.disconnect();
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "udp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("UDP packet pressure", test_udp_packet_pressure),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
diff -r 000000000000 -r 615f90842ce8 esp8266-driver/TESTS/net/udp_packet_pressure_parallel/main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp8266-driver/TESTS/net/udp_packet_pressure_parallel/main.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,347 @@
+#ifndef MBED_EXTENDED_TESTS
+    #error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
+#endif
+
+#include "mbed.h"
+#include "ESP8266Interface.h"
+#include "UDPSocket.h"
+#include "greentea-client/test_env.h"
+#include "unity/unity.h"
+#include "utest.h"
+
+using namespace utest::v1;
+
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN 64
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS 3
+#endif
+
+#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG
+#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
+#endif
+
+#ifndef MBED_CFG_ESP8266_TX
+#define MBED_CFG_ESP8266_TX D1
+#endif
+
+#ifndef MBED_CFG_ESP8266_RX
+#define MBED_CFG_ESP8266_RX D0
+#endif
+
+#ifndef MBED_CFG_ESP8266_DEBUG
+#define MBED_CFG_ESP8266_DEBUG false
+#endif
+
+
+// Simple xorshift pseudorandom number generator
+class RandSeq {
+private:
+    uint32_t x;
+    uint32_t y;
+    static const int A = 15;
+    static const int B = 18;
+    static const int C = 11;
+
+public:
+    RandSeq(uint32_t seed=MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED)
+        : x(seed), y(seed) {}
+
+    uint32_t next(void) {
+        x ^= x << A;
+        x ^= x >> B;
+        x ^= y ^ (y >> C);
+        return x + y;
+    }
+
+    void skip(size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            next();
+        }
+    }
+
+    void buffer(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            buffer[i] = lookahead.next() & 0xff;
+        }
+    }
+
+    int cmp(uint8_t *buffer, size_t size) {
+        RandSeq lookahead = *this;
+
+        for (size_t i = 0; i < size; i++) {
+            int diff = buffer[i] - (lookahead.next() & 0xff);
+            if (diff != 0) {
+                return diff;
+            }
+        }
+        return 0;
+    }
+};
+
+// Tries to get the biggest buffer possible on the device. Exponentially
+// grows a buffer until heap runs out of space, and uses half to leave
+// space for the rest of the program
+void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
+    size_t i = min;
+    while (i < max) {
+        void *b = malloc(i);
+        if (!b) {
+            i /= 8;
+            if (i < min) {
+                i = min;
+            }
+            break;
+        }
+        free(b);
+        i *= 2;
+    }
+
+    *buffer = (uint8_t *)malloc(i);
+    *size = i;
+    TEST_ASSERT(buffer);
+}
+
+
+// Global variables shared between pressure tests
+ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
+SocketAddress udp_addr;
+Timer timer;
+Mutex iomutex;
+
+// Single instance of a pressure test
+class PressureTest {
+private:
+    uint8_t *buffer;
+    size_t buffer_size;
+
+    UDPSocket sock;
+    Thread thread;
+
+public:
+    PressureTest(uint8_t *buffer, size_t buffer_size)
+        : buffer(buffer), buffer_size(buffer_size) {
+    }
+
+    void start() {
+        osStatus status = thread.start(callback(this, &PressureTest::run));
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void join() {
+        osStatus status = thread.join();
+        TEST_ASSERT_EQUAL(osOK, status);
+    }
+
+    void run() {
+        // Tests exponentially growing sequences
+        for (size_t size = MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
+             size < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX;
+             size *= 2) {
+            int err = sock.open(&net);
+            TEST_ASSERT_EQUAL(0, err);
+            iomutex.lock();
+            printf("UDP: %s:%d streaming %d bytes\r\n",
+                udp_addr.get_ip_address(), udp_addr.get_port(), size);
+            iomutex.unlock();
+
+            sock.set_blocking(false);
+
+            // Loop to send/recv all data
+            RandSeq tx_seq;
+            RandSeq rx_seq;
+            size_t rx_count = 0;
+            size_t tx_count = 0;
+            int known_time = timer.read_ms();
+            size_t window = buffer_size;
+
+            while (tx_count < size || rx_count < size) {
+                // Send out packets
+                if (tx_count < size) {
+                    size_t chunk_size = size - tx_count;
+                    if (chunk_size > window) {
+                        chunk_size = window;
+                    }
+
+                    tx_seq.buffer(buffer, chunk_size);
+                    int td = sock.sendto(udp_addr, buffer, chunk_size);
+
+                    if (td > 0) {
+                        if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("UDP: tx -> %d\r\n", td);
+                            iomutex.unlock();
+                        }
+                        tx_seq.skip(td);
+                        tx_count += td;
+                    } else if (td != NSAPI_ERROR_WOULD_BLOCK) {
+                        // We may fail to send because of buffering issues, revert to
+                        // last good sequence and cut buffer in half
+                        if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
+                            window /= 2;
+                        }
+
+                        if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("UDP: Not sent (%d), window = %d\r\n", td, window);
+                            iomutex.unlock();
+                        }
+                    }
+                }
+
+                // Prioritize recieving over sending packets to avoid flooding
+                // the network while handling erronous packets
+                while (rx_count < size) {
+                    int rd = sock.recvfrom(NULL, buffer, buffer_size);
+                    TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
+
+                    if (rd > 0) {
+                        if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("UDP: rx <- %d\r\n", rd);
+                            iomutex.unlock();
+                        }
+
+                        if (rx_seq.cmp(buffer, rd) == 0) {
+                            rx_seq.skip(rd);
+                            rx_count += rd;
+                            known_time = timer.read_ms();
+                            if (window < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX) {
+                                window += MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
+                            }
+                        }
+                    } else if (timer.read_ms() - known_time >
+                            MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
+                        // Dropped packet or out of order, revert to last good sequence
+                        // and cut buffer in half
+                        tx_seq = rx_seq;
+                        tx_count = rx_count;
+                        known_time = timer.read_ms();
+                        if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
+                            window /= 2;
+                        }
+
+                        if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
+                            iomutex.lock();
+                            printf("UDP: Dropped, window = %d\r\n", window);
+                            iomutex.unlock();
+                        }
+                    } else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
+                        break;
+                    }
+                }
+            }
+
+            err = sock.close();
+            TEST_ASSERT_EQUAL(0, err);
+        }
+    }
+};
+
+PressureTest *pressure_tests[MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS];
+
+
+void test_udp_packet_pressure_parallel() {
+    uint8_t *buffer;
+    size_t buffer_size;
+    generate_buffer(&buffer, &buffer_size,
+        MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN,
+        MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX);
+
+    size_t buffer_subsize = buffer_size / MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS;
+    printf("MBED: Generated buffer %d\r\n", buffer_size);
+    printf("MBED: Split into %d buffers %d\r\n",
+            MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS,
+            buffer_subsize);
+
+    int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
+    TEST_ASSERT_EQUAL(0, err);
+
+    printf("MBED: UDPClient IP address is '%s'\n", net.get_ip_address());
+    printf("MBED: UDPClient waiting for server IP and port...\n");
+
+    greentea_send_kv("target_ip", net.get_ip_address());
+
+    char recv_key[] = "host_port";
+    char ipbuf[60] = {0};
+    char portbuf[16] = {0};
+    unsigned int port = 0;
+
+    greentea_send_kv("host_ip", " ");
+    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
+
+    greentea_send_kv("host_port", " ");
+    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
+    sscanf(portbuf, "%u", &port);
+
+    printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
+    udp_addr.set_ip_address(ipbuf);
+    udp_addr.set_port(port);
+
+    timer.start();
+
+    // Startup pressure tests in parallel
+    for (int i = 0; i < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
+        pressure_tests[i] = new PressureTest(&buffer[i*buffer_subsize], buffer_subsize);
+        pressure_tests[i]->start();
+    }
+
+    for (int i = 0; i < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
+        pressure_tests[i]->join();
+        delete pressure_tests[i];
+    }
+
+    timer.stop();
+    printf("MBED: Time taken: %fs\r\n", timer.read());
+    printf("MBED: Speed: %.3fkb/s\r\n",
+            MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS*
+            8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX - 
+            MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
+
+    net.disconnect();
+}
+
+
+// Test setup
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+    char uuid[48] = {0};
+    GREENTEA_SETUP_UUID(120, "udp_echo", uuid, 48);
+
+    // create mac address based on uuid
+    uint64_t mac = 0;
+    for (int i = 0; i < sizeof(uuid); i++) {
+        mac += uuid[i];
+    }
+    mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
+
+    return verbose_test_setup_handler(number_of_cases);
+}
+
+Case cases[] = {
+    Case("UDP packet pressure parallel", test_udp_packet_pressure_parallel),
+};
+
+Specification specification(test_setup, cases);
+
+int main() {
+    return !Harness::run(specification);
+}
+
+
diff -r 000000000000 -r 615f90842ce8 mbed_lib.json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_lib.json	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,9 @@
+{
+    "name": "easy-connect",
+    "target_overrides": {
+        "*": {
+            "target.features_add": ["COMMON_PAL"]
+        }
+    }
+}
+
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mcr20a-rf-driver/#d5905fefa54c0de9b757d6f1c87c8ae9ee337543
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/heads/master
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/ORIG_HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/ORIG_HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+d5905fefa54c0de9b757d6f1c87c8ae9ee337543
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/config	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/ARMmbed/mcr20a-rf-driver/
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/description
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/description	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/applypatch-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/applypatch-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/post-update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/post-update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/pre-applypatch.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/pre-applypatch.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/pre-commit.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/pre-commit.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/pre-rebase.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/pre-rebase.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/usr/bin/perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
+
+DOC_END
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/prepare-commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/prepare-commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /usr/bin/perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/hooks/update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/hooks/update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/index
Binary file mcr20a-rf-driver/.git/index has changed
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/info/exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/info/exclude	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,25 @@
+.hg
+.git
+.svn
+.CVS
+.cvs
+*.orig
+.build
+.export
+.msub
+.meta
+.ctags*
+*.uvproj
+*.uvopt
+*.project
+*.cproject
+*.launch
+*.ewp
+*.eww
+Makefile
+Debug
+*.htm
+*.settings
+mbed_settings.py
+*.py[cod]
+# subrepo ignores
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/logs/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/logs/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 d5905fefa54c0de9b757d6f1c87c8ae9ee337543 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209874 +0000	clone: from https://github.com/ARMmbed/mcr20a-rf-driver/
+d5905fefa54c0de9b757d6f1c87c8ae9ee337543 d5905fefa54c0de9b757d6f1c87c8ae9ee337543 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209875 +0000	checkout: moving from master to d5905fefa54c0de9b757d6f1c87c8ae9ee337543
+d5905fefa54c0de9b757d6f1c87c8ae9ee337543 d5905fefa54c0de9b757d6f1c87c8ae9ee337543 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209875 +0000	checkout: moving from d5905fefa54c0de9b757d6f1c87c8ae9ee337543 to master
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/logs/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/logs/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 d5905fefa54c0de9b757d6f1c87c8ae9ee337543 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209874 +0000	clone: from https://github.com/ARMmbed/mcr20a-rf-driver/
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/logs/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/logs/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 d5905fefa54c0de9b757d6f1c87c8ae9ee337543 www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209874 +0000	clone: from https://github.com/ARMmbed/mcr20a-rf-driver/
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.idx
Binary file mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.idx has changed
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.pack
Binary file mcr20a-rf-driver/.git/objects/pack/pack-615d22dee620791d4e3e631a7eecfc10a5e5c76e.pack has changed
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/packed-refs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/packed-refs	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+# pack-refs with: peeled 
+a28948345dfbd89719c60b765a9837ffbd434a2e refs/remotes/origin/fixing_mbed_path
+d5905fefa54c0de9b757d6f1c87c8ae9ee337543 refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+d5905fefa54c0de9b757d6f1c87c8ae9ee337543
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.git/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.git/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/.gitignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/.gitignore	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,6 @@
+*~
+*.swo
+*.swp
+build
+yotta_modules
+yotta_targets
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/LICENSE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/LICENSE	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2 @@
+Unless specifically indicated otherwise in a file, files are licensed
+under the Apache 2.0 license, as can be found in: apache-2.0.txt
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,6 @@
+# Example RF driver for Freescale 802.15.4 transceivers #
+
+Support for:
+ * MCR20A
+
+This driver is used with 6LoWPAN stack.
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/apache-2.0.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/apache-2.0.txt	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,56 @@
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+    You must give any other recipients of the Work or Derivative Works a copy of this License; and
+    You must cause any modified files to carry prominent notices stating that You changed the files; and
+    You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+    If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/mcr20a-rf-driver/NanostackRfPhyMcr20a.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/mcr20a-rf-driver/NanostackRfPhyMcr20a.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NANOSTACK_PHY_MCR20A_H_
+#define NANOSTACK_PHY_MCR20A_H_
+
+#include "mbed.h"
+#include "NanostackRfPhy.h"
+
+// Arduino pin defaults for convenience
+#if !defined(MCR20A_SPI_MOSI)
+#define MCR20A_SPI_MOSI   D11
+#endif
+#if !defined(MCR20A_SPI_MISO)
+#define MCR20A_SPI_MISO   D12
+#endif
+#if !defined(MCR20A_SPI_SCLK)
+#define MCR20A_SPI_SCLK   D13
+#endif
+#if !defined(MCR20A_SPI_CS)
+#define MCR20A_SPI_CS     D10
+#endif
+#if !defined(MCR20A_SPI_RST)
+#define MCR20A_SPI_RST    D5
+#endif
+#if !defined(MCR20A_SPI_IRQ)
+#define MCR20A_SPI_IRQ    D2
+#endif
+
+class NanostackRfPhyMcr20a : public NanostackRfPhy {
+public:
+    NanostackRfPhyMcr20a(PinName spi_mosi, PinName spi_miso,
+                         PinName spi_sclk, PinName spi_cs,  PinName spi_rst,
+                         PinName spi_irq);
+    ~NanostackRfPhyMcr20a();
+    int8_t rf_register();
+    void rf_unregister();
+    void get_mac_address(uint8_t *mac);
+    void set_mac_address(uint8_t *mac);
+
+private:
+    SPI _spi;
+    DigitalOut _rf_cs;
+    DigitalOut _rf_rst;
+    InterruptIn _rf_irq;
+    DigitalIn _rf_irq_pin;
+
+    void _pins_set();
+    void _pins_clear();
+};
+
+#endif /* NANOSTACK_PHY_MCR20A_H_ */
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/module.json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/module.json	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,18 @@
+{
+  "name": "mcr20a-rf-driver",
+  "version": "0.0.1",
+  "description": "RF driver for Freescale MCR20A 2.4GHz 802.15.4 wireless transceiver",
+  "keywords": [
+    "rf",
+    "driver",
+    "802.15.4"
+  ],
+  "author": "Andrei Kovacs <Andrei.Kovacs@freescale.com>",
+  "license": "BSD 3-clause",
+  "dependencies": {
+    "nanostack-libservice": "^3.0.0",
+    "sal-stack-nanostack": "^5.0.0",
+    "mbed-drivers": "^1.0.0"
+  },
+  "targetDependencies": {}
+}
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/MCR20Drv.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/MCR20Drv.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,679 @@
+/*!
+* Copyright (c) 2015, Freescale Semiconductor, Inc.
+* All rights reserved.
+*
+* \file MCR20Drv.c
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* o Redistributions of source code must retain the above copyright notice, this list
+*   of conditions and the following disclaimer.
+*
+* o Redistributions in binary form must reproduce the above copyright notice, this
+*   list of conditions and the following disclaimer in the documentation and/or
+*   other materials provided with the distribution.
+*
+* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+*   contributors may be used to endorse or promote products derived from this
+*   software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/*****************************************************************************
+*                               INCLUDED HEADERS                            *
+*---------------------------------------------------------------------------*
+* Add to this section all the headers that this module needs to include.    *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+
+#include "platform/arm_hal_interrupt.h"
+#include "MCR20Drv.h"
+#include "MCR20Reg.h"
+#include "XcvrSpi.h"
+
+
+/*****************************************************************************
+*                               PRIVATE VARIABLES                           *
+*---------------------------------------------------------------------------*
+* Add to this section all the variables and constants that have local       *
+* (file) scope.                                                             *
+* Each of this declarations shall be preceded by the 'static' keyword.      *
+* These variables / constants cannot be accessed outside this module.       *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+uint32_t mPhyIrqDisableCnt = 1;
+
+/*****************************************************************************
+*                               PUBLIC VARIABLES                            *
+*---------------------------------------------------------------------------*
+* Add to this section all the variables and constants that have global      *
+* (project) scope.                                                          *
+* These variables / constants can be accessed outside this module.          *
+* These variables / constants shall be preceded by the 'extern' keyword in  *
+* the interface header.                                                     *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+
+/*****************************************************************************
+*                           PRIVATE FUNCTIONS PROTOTYPES                    *
+*---------------------------------------------------------------------------*
+* Add to this section all the functions prototypes that have local (file)   *
+* scope.                                                                    *
+* These functions cannot be accessed outside this module.                   *
+* These declarations shall be preceded by the 'static' keyword.             *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+
+/*****************************************************************************
+*                                PRIVATE FUNCTIONS                          *
+*---------------------------------------------------------------------------*
+* Add to this section all the functions that have local (file) scope.       *
+* These functions cannot be accessed outside this module.                   *
+* These definitions shall be preceded by the 'static' keyword.              *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+
+
+/*****************************************************************************
+*                             PUBLIC FUNCTIONS                              *
+*---------------------------------------------------------------------------*
+* Add to this section all the functions that have global (project) scope.   *
+* These functions can be accessed outside this module.                      *
+* These functions shall have their declarations (prototypes) within the     *
+* interface header file and shall be preceded by the 'extern' keyword.      *
+*---------------------------------------------------------------------------*
+*****************************************************************************/
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_Init
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_Init
+(
+void
+)
+{
+    xcvr_spi_init(gXcvrSpiInstance_c);
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrDeassertCS_d();
+    #if !defined(TARGET_KW24D)
+      MCR20Drv_RST_B_Deassert();
+    #endif
+    RF_IRQ_Init();
+    RF_IRQ_Disable();
+    mPhyIrqDisableCnt = 1;
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_DirectAccessSPIWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_DirectAccessSPIWrite
+(
+uint8_t address,
+uint8_t value
+)
+{
+    uint16_t txData;
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData = (address & TransceiverSPI_DirectRegisterAddressMask);
+    txData |= value << 8;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t *)&txData, 0, sizeof(txData));
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_DirectAccessSPIMultiByteWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_DirectAccessSPIMultiByteWrite
+(
+uint8_t startAddress,
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint8_t txData;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData = (startAddress & TransceiverSPI_DirectRegisterAddressMask);
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, byteArray, 0, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_PB_SPIByteWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_PB_SPIByteWrite
+(
+uint8_t address,
+uint8_t value
+)
+{
+    uint32_t txData;
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData  = TransceiverSPI_WriteSelect            |
+        TransceiverSPI_PacketBuffAccessSelect |
+            TransceiverSPI_PacketBuffByteModeSelect;
+    txData |= (address) << 8;
+    txData |= (value)   << 16;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, 3);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_PB_SPIBurstWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_PB_SPIBurstWrite
+(
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint8_t txData;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData = TransceiverSPI_WriteSelect            |
+        TransceiverSPI_PacketBuffAccessSelect |
+            TransceiverSPI_PacketBuffBurstModeSelect;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, 1);
+    xcvr_spi_transfer(gXcvrSpiInstance_c, byteArray, 0, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_DirectAccessSPIRead
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+
+uint8_t MCR20Drv_DirectAccessSPIRead
+(
+uint8_t address
+)
+{
+    uint8_t txData;
+    uint8_t rxData;
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrAssertCS_d();
+
+    txData = (address & TransceiverSPI_DirectRegisterAddressMask) |
+        TransceiverSPI_ReadSelect;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, 0, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, 0, &rxData, sizeof(rxData));
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+
+    return rxData;
+
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_DirectAccessSPIMultyByteRead
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_DirectAccessSPIMultiByteRead
+(
+uint8_t startAddress,
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint8_t  txData;
+    uint8_t  phyIRQSTS1;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return 0;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrAssertCS_d();
+
+    txData = (startAddress & TransceiverSPI_DirectRegisterAddressMask) |
+        TransceiverSPI_ReadSelect;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, &phyIRQSTS1, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+
+    return phyIRQSTS1;
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_PB_SPIBurstRead
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_PB_SPIBurstRead
+(
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint8_t  txData;
+    uint8_t  phyIRQSTS1;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return 0;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrAssertCS_d();
+
+    txData = TransceiverSPI_ReadSelect |
+        TransceiverSPI_PacketBuffAccessSelect |
+            TransceiverSPI_PacketBuffBurstModeSelect;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, &txData, &phyIRQSTS1, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+
+    return phyIRQSTS1;
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IndirectAccessSPIWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIWrite
+(
+uint8_t address,
+uint8_t value
+)
+{
+    uint32_t  txData;
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData = TransceiverSPI_IARIndexReg;
+    txData |= (address) << 8;
+    txData |= (value)   << 16;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, 3);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IndirectAccessSPIMultiByteWrite
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIMultiByteWrite
+(
+uint8_t startAddress,
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint16_t  txData;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 16000000);
+
+    gXcvrAssertCS_d();
+
+    txData = TransceiverSPI_IARIndexReg;
+    txData |= (startAddress)  << 8;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)byteArray, 0, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IndirectAccessSPIRead
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_IndirectAccessSPIRead
+(
+uint8_t address
+)
+{
+    uint16_t  txData;
+    uint8_t   rxData;
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrAssertCS_d();
+
+    txData = TransceiverSPI_IARIndexReg | TransceiverSPI_ReadSelect;
+    txData |= (address) << 8;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, 0, &rxData, sizeof(rxData));
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+
+    return rxData;
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IndirectAccessSPIMultiByteRead
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIMultiByteRead
+(
+uint8_t startAddress,
+uint8_t * byteArray,
+uint8_t numOfBytes
+)
+{
+    uint16_t  txData;
+
+    if( (numOfBytes == 0) || (byteArray == 0) )
+    {
+        return;
+    }
+
+    ProtectFromMCR20Interrupt();
+
+    xcvr_spi_configure_speed(gXcvrSpiInstance_c, 8000000);
+
+    gXcvrAssertCS_d();
+
+    txData = (TransceiverSPI_IARIndexReg | TransceiverSPI_ReadSelect);
+    txData |= (startAddress) << 8;
+
+    xcvr_spi_transfer(gXcvrSpiInstance_c, (uint8_t*)&txData, 0, sizeof(txData));
+    xcvr_spi_transfer(gXcvrSpiInstance_c, 0, byteArray, numOfBytes);
+
+    gXcvrDeassertCS_d();
+    UnprotectFromMCR20Interrupt();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IsIrqPending
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+uint32_t  MCR20Drv_IsIrqPending
+(
+void
+)
+{
+    return RF_isIRQ_Pending();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IRQ_Disable
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_IRQ_Disable
+(
+void
+)
+{
+    platform_enter_critical();
+
+    if( mPhyIrqDisableCnt == 0 )
+    {
+        RF_IRQ_Disable();
+    }
+
+    mPhyIrqDisableCnt++;
+
+    platform_exit_critical();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_IRQ_Enable
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_IRQ_Enable
+(
+void
+)
+{
+    platform_enter_critical();
+
+    if( mPhyIrqDisableCnt )
+    {
+        mPhyIrqDisableCnt--;
+
+        if( mPhyIrqDisableCnt == 0 )
+        {
+            RF_IRQ_Enable();
+        }
+    }
+
+    platform_exit_critical();
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_RST_Assert
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_RST_B_Assert
+(
+void
+)
+{
+    RF_RST_Set(0);
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_RST_Deassert
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_RST_B_Deassert
+(
+void
+)
+{
+    RF_RST_Set(1);
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_SoftRST_Assert
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_SoftRST_Assert
+(
+void
+)
+{
+    MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x80));
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_SoftRST_Deassert
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_SoftRST_Deassert
+(
+void
+)
+{
+    MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x00));
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_Soft_RESET
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_Soft_RESET
+(
+void
+)
+{
+    //assert SOG_RST
+    MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x80));
+
+    //deassert SOG_RST
+    MCR20Drv_IndirectAccessSPIWrite(SOFT_RESET, (0x00));
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_RESET
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_RESET
+(
+void
+)
+{
+  #if !defined(TARGET_KW24D)
+    volatile uint32_t delay = 1000;
+    //assert RST_B
+    MCR20Drv_RST_B_Assert();
+
+    while(delay--);
+
+    //deassert RST_B
+    MCR20Drv_RST_B_Deassert();
+  #endif
+}
+
+/*---------------------------------------------------------------------------
+* Name: MCR20Drv_Set_CLK_OUT_Freq
+* Description: -
+* Parameters: -
+* Return: -
+*---------------------------------------------------------------------------*/
+void MCR20Drv_Set_CLK_OUT_Freq
+(
+uint8_t freqDiv
+)
+{
+    uint8_t clkOutCtrlReg = (freqDiv & cCLK_OUT_DIV_Mask) | cCLK_OUT_EN | cCLK_OUT_EXTEND;
+
+    if(freqDiv == gCLK_OUT_FREQ_DISABLE)
+    {
+        clkOutCtrlReg = (cCLK_OUT_EXTEND | gCLK_OUT_FREQ_4_MHz); //reset value with clock out disabled
+    }
+
+    MCR20Drv_DirectAccessSPIWrite((uint8_t) CLK_OUT_CTRL, clkOutCtrlReg);
+}
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/MCR20Drv.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/MCR20Drv.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,372 @@
+/*!
+* Copyright (c) 2015, Freescale Semiconductor, Inc.
+* All rights reserved.
+*
+* \file MCR20Drv.h
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* o Redistributions of source code must retain the above copyright notice, this list
+*   of conditions and the following disclaimer.
+*
+* o Redistributions in binary form must reproduce the above copyright notice, this
+*   list of conditions and the following disclaimer in the documentation and/or
+*   other materials provided with the distribution.
+*
+* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+*   contributors may be used to endorse or promote products derived from this
+*   software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (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 __MCR20_DRV_H__
+#define __MCR20_DRV_H__
+
+
+/*****************************************************************************
+ *                               INCLUDED HEADERS                            *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the headers that this module needs to include.    *
+ * Note that it is not a good practice to include header files into header   *
+ * files, so use this section only if there is no other better solution.     *
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+
+/*****************************************************************************
+ *                             PRIVATE MACROS                                *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the access macros, registers mappings, bit access *
+ * macros, masks, flags etc ...
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+
+/* Disable XCVR clock output by default, to reduce power consumption */
+#ifndef gMCR20_ClkOutFreq_d 
+#define gMCR20_ClkOutFreq_d gCLK_OUT_FREQ_DISABLE
+#endif
+
+/*****************************************************************************
+ *                            PUBLIC FUNCTIONS                               *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the global functions prototype preceded (as a     *
+ * good practice) by the keyword 'extern'                                    *
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_Init
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+extern void MCR20Drv_Init
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_SPI_DMA_Init
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_SPI_DMA_Init
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_Start_PB_DMA_SPI_Write
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_Start_PB_DMA_SPI_Write
+(
+  uint8_t * srcAddress,
+  uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_Start_PB_DMA_SPI_Read
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_Start_PB_DMA_SPI_Read
+(
+  uint8_t * dstAddress,
+  uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_DirectAccessSPIWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_DirectAccessSPIWrite
+(
+ uint8_t address,
+ uint8_t value
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_DirectAccessSPIMultiByteWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_DirectAccessSPIMultiByteWrite
+(
+ uint8_t startAddress,
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_PB_SPIBurstWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_PB_SPIBurstWrite
+(
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_DirectAccessSPIRead
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_DirectAccessSPIRead
+(
+ uint8_t address
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_DirectAccessSPIMultyByteRead
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+
+uint8_t MCR20Drv_DirectAccessSPIMultiByteRead
+(
+ uint8_t startAddress,
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_PB_SPIByteWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_PB_SPIByteWrite
+(
+ uint8_t address,
+ uint8_t value
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_PB_SPIBurstRead
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_PB_SPIBurstRead
+(
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IndirectAccessSPIWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIWrite
+(
+ uint8_t address,
+ uint8_t value
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IndirectAccessSPIMultiByteWrite
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIMultiByteWrite
+(
+ uint8_t startAddress,
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IndirectAccessSPIRead
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+uint8_t MCR20Drv_IndirectAccessSPIRead
+(
+ uint8_t address
+);
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IndirectAccessSPIMultiByteRead
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_IndirectAccessSPIMultiByteRead
+(
+ uint8_t startAddress,
+ uint8_t * byteArray,
+ uint8_t numOfBytes
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IsIrqPending
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+uint32_t MCR20Drv_IsIrqPending
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IRQ_Disable
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_IRQ_Disable
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_IRQ_Enable
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_IRQ_Enable
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_RST_PortConfig
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_RST_B_PortConfig
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_RST_Assert
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_RST_B_Assert
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_RST_Deassert
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_RST_B_Deassert
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_SoftRST_Assert
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_SoftRST_Assert
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_SoftRST_Deassert
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_SoftRST_Deassert
+(
+  void
+);
+
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_RESET
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_RESET
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_Soft_RESET
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_Soft_RESET
+(
+  void
+);
+
+/*---------------------------------------------------------------------------
+ * Name: MCR20Drv_Set_CLK_OUT_Freq
+ * Description: -
+ * Parameters: -
+ * Return: -
+ *---------------------------------------------------------------------------*/
+void MCR20Drv_Set_CLK_OUT_Freq
+(
+  uint8_t freqDiv
+);
+
+#define ProtectFromMCR20Interrupt()   MCR20Drv_IRQ_Disable()
+#define UnprotectFromMCR20Interrupt() MCR20Drv_IRQ_Enable()
+
+#endif /* __MCR20_DRV_H__ */
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/MCR20Overwrites.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/MCR20Overwrites.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,309 @@
+/*!
+* Copyright (c) 2015, Freescale Semiconductor, Inc.
+* All rights reserved.
+*
+* \file MCR20Overwrites.h
+* Description: Overwrites header file for MCR20 Register values
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* o Redistributions of source code must retain the above copyright notice, this list
+*   of conditions and the following disclaimer.
+*
+* o Redistributions in binary form must reproduce the above copyright notice, this
+*   list of conditions and the following disclaimer in the documentation and/or
+*   other materials provided with the distribution.
+*
+* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+*   contributors may be used to endorse or promote products derived from this
+*   software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (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 OVERWRITES_H_
+#define OVERWRITES_H_
+
+typedef struct overwrites_tag {
+ char address;
+ char data;
+}overwrites_t;
+
+
+/*****************************************************************************************************************/
+//         This file is created exclusively for use with the transceiver 2.0 silicon
+//         and is provided for the world to use. It contains a list of all
+//         known overwrite values. Overwrite values are non-default register
+//         values that configure the transceiver device to a more optimally performing
+//         posture. It is expected that low level software (i.e. PHY) will
+//         consume this file as a #include, and transfer the contents to the
+//         the indicated addresses in the transceiver's memory space. This file has
+//         at least one required entry, that being its own version current version
+//         number, to be stored at transceiver's location 0x3B the
+//         OVERWRITES_VERSION_NUMBER register. The RAM register is provided in
+//         the transceiver address space to assist in future debug efforts. The
+//         analyst may read this location (once device has been booted with
+//         mysterious software) and have a good indication of what register
+//         overwrites were performed (with all versions of the overwrites.h file
+//         being archived forever at the Compass location shown above.
+//
+//     The transceiver has an indirect register (IAR) space. Write access to this space
+//         requires 3 or more writes:
+//         1st) the first write is an index value to the indirect (write Bit7=0, register access Bit 6=0) + 0x3E
+//         2nd) IAR Register #0x00 - 0xFF.
+//     3rd) The data to write
+//         nth) Burst mode additional data if required.
+//
+//     Write access to direct space requires only a single address, data pair.
+
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x0C}, //version 0C: new value for ACKDELAY targeting 198us (23 May, 2013, Larry Roshak)
+{0x23, 0x17}  //PA_PWR new default Power Step is "23"  
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}, //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}, //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}, //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}, //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}, //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}, //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}, //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}, //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}, //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28}, //PA_CAL_DIS=1  Disabled PA calibration 
+{0x52, 0x55}, //AGC_THR1 RSSI tune up 
+{0x53, 0x2D}, //AGC_THR2 RSSI tune up 
+{0x66, 0x5F}, //ATT_RSSI1 tune up     
+{0x67, 0x8F}, //ATT_RSSI2 tune up     
+{0x68, 0x61}, //RSSI_OFFSET 
+{0x78, 0x03}, //CHF_PMAGAIN 
+{0x22, 0x50}, //CCA1_THRESH 
+{0x4D, 0x13}, //CORR_NVAL moved from 0x14 to 0x13 for 0.5 dB improved Rx Sensitivity 
+{0x39, 0x3D}  //ACKDELAY new value targeting a delay of 198us (23 May, 2013, Larry Roshak)
+};
+
+
+/* begin of deprecated versions
+
+==VERSION 1==
+(version 1 is empty)
+
+==VERSION 2==
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}  //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+};
+
+==VERSION 3==
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1: override VCOALC_REF_TX to 3 
+{0x92, 0x07}  //VCO_CTRL2: override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+};
+
+==VERSION 4==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x04}  //version 04 is the current version: update PA_COILTUNING default 
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1: override VCOALC_REF_TX to 3 
+{0x92, 0x07}  //VCO_CTRL2: override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}  //PA_TUNING: override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+};
+
+==VERSION 5==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x05}  //version 05: updates Channel Filter Register set (21 Dec 2012, on behalf of S. Soca)
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}  //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}  //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}  //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}  //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}  //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}  //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}  //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}  //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}  //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}  //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}  //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}  //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}  //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+};
+
+==VERSION 6==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x06}  //version 06: disable PA calibration 
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}  //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}  //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}  //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}  //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}  //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}  //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}  //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}  //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}  //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}  //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}  //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}  //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}  //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28}  //PA_CAL_DIS=1  Disabled PA calibration 
+};
+
+==VERSION 7==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x07}  //version 07: updated registers for ED/RSSI 
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07},  //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71},  //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F},  //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F},  //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24},  //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24},  //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24},  //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24},  //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24},  //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24},  //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}, //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D},  //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D},  //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28},  //PA_CAL_DIS=1  Disabled PA calibration 
+{0x52, 0x73},  //AGC_THR1 RSSI tune up 
+{0x53, 0x2D}, //AGC_THR2 RSSI tune up 
+{0x66, 0x5F}, //ATT_RSSI1 tune up 
+{0x67, 0x8F}, //ATT_RSSI2 tune up 
+{0x68, 0x60}, //RSSI_OFFSET 
+{0x69, 0x65}  //RSSI_SLOPE 
+};
+
+
+==VERSION 8==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x08}  //version 08: updated registers for ED/RSSI 
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}, //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}, //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}, //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}, //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}, //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}, //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}, //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}, //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}, //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28}, //PA_CAL_DIS=1  Disabled PA calibration 
+{0x52, 0x73}, //AGC_THR1 RSSI tune up 
+{0x53, 0x2D}, //AGC_THR2 RSSI tune up 
+{0x66, 0x5F}, //ATT_RSSI1 tune up     
+{0x67, 0x8F}, //ATT_RSSI2 tune up     
+{0x69, 0x65}  //RSSI_SLOPE            
+{0x68, 0x61}, //RSSI_OFFSET 
+{0x78, 0x03}  //CHF_PMAGAIN 
+};
+
+
+==VERSION 9==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x09}  //version 09: updated registers for ED/RSSI and PowerStep 
+{0x23, 0x17}  //PA_PWR new default value                                
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}, //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}, //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}, //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}, //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}, //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}, //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}, //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}, //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}, //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28}, //PA_CAL_DIS=1  Disabled PA calibration 
+{0x52, 0x55}, //AGC_THR1 RSSI tune up 
+{0x53, 0x2D}, //AGC_THR2 RSSI tune up 
+{0x66, 0x5F}, //ATT_RSSI1 tune up     
+{0x67, 0x8F}, //ATT_RSSI2 tune up     
+{0x68, 0x61}, //RSSI_OFFSET 
+{0x78, 0x03}  //CHF_PMAGAIN 
+};
+
+==VERSION A==
+overwrites_t const overwrites_direct[] ={
+{0x3B, 0x0A}  //version 0A: updated registers for CCA 
+{0x23, 0x17}  //PA_PWR new default Power Step is "23"  
+};
+
+overwrites_t const overwrites_indirect[] ={
+{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents) 
+{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3                         
+{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1 
+{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
+{0x79, 0x2F}, //CHF_IBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7A, 0x2F}, //CHF_QBUF  Adjust the gm-C filter gain (+/- 6dB)         (21 Dec, 2012, on behalf of S. Soca)
+{0x7B, 0x24}, //CHF_IRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7C, 0x24}, //CHF_QRIN  Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7D, 0x24}, //CHF_IL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7E, 0x24}, //CHF_QL    Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x7F, 0x32}, //CHF_CC1   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x80, 0x1D}, //CHF_CCL   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x81, 0x2D}, //CHF_CC2   Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
+{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz)      (21 Dec, 2012, on behalf of S. Soca)
+{0x64, 0x28}, //PA_CAL_DIS=1  Disabled PA calibration 
+{0x52, 0x55}, //AGC_THR1 RSSI tune up 
+{0x53, 0x2D}, //AGC_THR2 RSSI tune up 
+{0x66, 0x5F}, //ATT_RSSI1 tune up     
+{0x67, 0x8F}, //ATT_RSSI2 tune up     
+{0x68, 0x61}, //RSSI_OFFSET 
+{0x78, 0x03}  //CHF_PMAGAIN 
+{0x22, 0x50}  //CCA1_THRESH 
+};
+
+end of deprecated versions */
+
+
+#endif  //OVERWRITES_H_
+
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/MCR20Reg.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/MCR20Reg.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,730 @@
+/*!
+* Copyright (c) 2015, Freescale Semiconductor, Inc.
+* All rights reserved.
+*
+* \file MCR20reg.h
+* MCR20 Registers
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* o Redistributions of source code must retain the above copyright notice, this list
+*   of conditions and the following disclaimer.
+*
+* o Redistributions in binary form must reproduce the above copyright notice, this
+*   list of conditions and the following disclaimer in the documentation and/or
+*   other materials provided with the distribution.
+*
+* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+*   contributors may be used to endorse or promote products derived from this
+*   software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (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 __MCR20_REG_H__
+#define __MCR20_REG_H__
+/*****************************************************************************
+ *                               INCLUDED HEADERS                            *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the headers that this module needs to include.    *
+ * Note that it is not a good practice to include header files into header   *
+ * files, so use this section only if there is no other better solution.     *
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+
+/****************************************************************************/
+/* Transceiver SPI Registers */
+/****************************************************************************/
+
+#define TransceiverSPI_IARIndexReg                  (0x3E)
+
+#define TransceiverSPI_ReadSelect                   (1<<7)
+#define TransceiverSPI_WriteSelect                  (0<<7)
+#define TransceiverSPI_RegisterAccessSelect         (0<<6)
+#define TransceiverSPI_PacketBuffAccessSelect       (1<<6)
+#define TransceiverSPI_PacketBuffBurstModeSelect    (0<<5)
+#define TransceiverSPI_PacketBuffByteModeSelect     (1<<5)
+
+#define TransceiverSPI_DirectRegisterAddressMask    (0x3F)
+
+#define IRQSTS1             0x00
+#define IRQSTS2             0x01
+#define IRQSTS3             0x02
+#define PHY_CTRL1           0x03
+#define PHY_CTRL2           0x04
+#define PHY_CTRL3           0x05
+#define RX_FRM_LEN          0x06
+#define PHY_CTRL4           0x07
+#define SRC_CTRL            0x08
+#define SRC_ADDRS_SUM_LSB   0x09
+#define SRC_ADDRS_SUM_MSB   0x0A
+#define CCA1_ED_FNL         0x0B
+#define EVENT_TMR_LSB       0x0C
+#define EVENT_TMR_MSB       0x0D
+#define EVENT_TMR_USB       0x0E
+#define TIMESTAMP_LSB       0x0F
+#define TIMESTAMP_MSB       0x10
+#define TIMESTAMP_USB       0x11
+#define T3CMP_LSB           0x12
+#define T3CMP_MSB           0x13
+#define T3CMP_USB           0x14
+#define T2PRIMECMP_LSB      0x15
+#define T2PRIMECMP_MSB      0x16
+#define T1CMP_LSB           0x17
+#define T1CMP_MSB           0x18
+#define T1CMP_USB           0x19
+#define T2CMP_LSB           0x1A
+#define T2CMP_MSB           0x1B
+#define T2CMP_USB           0x1C
+#define T4CMP_LSB           0x1D
+#define T4CMP_MSB           0x1E
+#define T4CMP_USB           0x1F
+#define PLL_INT0            0x20
+#define PLL_FRAC0_LSB       0x21
+#define PLL_FRAC0_MSB       0x22
+#define PA_PWR              0x23
+#define SEQ_STATE           0x24
+#define LQI_VALUE           0x25
+#define RSSI_CCA_CONT       0x26
+//--------------            0x27
+#define ASM_CTRL1           0x28
+#define ASM_CTRL2           0x29
+#define ASM_DATA_0          0x2A
+#define ASM_DATA_1          0x2B
+#define ASM_DATA_2          0x2C
+#define ASM_DATA_3          0x2D
+#define ASM_DATA_4          0x2E
+#define ASM_DATA_5          0x2F
+#define ASM_DATA_6          0x30
+#define ASM_DATA_7          0x31
+#define ASM_DATA_8          0x32
+#define ASM_DATA_9          0x33
+#define ASM_DATA_A          0x34
+#define ASM_DATA_B          0x35
+#define ASM_DATA_C          0x36
+#define ASM_DATA_D          0x37
+#define ASM_DATA_E          0x38
+#define ASM_DATA_F          0x39
+//-------------------       0x3A
+#define OVERWRITE_VER       0x3B
+#define CLK_OUT_CTRL        0x3C
+#define PWR_MODES           0x3D
+#define IAR_INDEX           0x3E
+#define IAR_DATA            0x3F
+
+
+#define PART_ID             0x00
+#define XTAL_TRIM           0x01
+#define PMC_LP_TRIM         0x02
+#define MACPANID0_LSB       0x03
+#define MACPANID0_MSB       0x04
+#define MACSHORTADDRS0_LSB  0x05
+#define MACSHORTADDRS0_MSB  0x06
+#define MACLONGADDRS0_0     0x07
+#define MACLONGADDRS0_8     0x08
+#define MACLONGADDRS0_16    0x09
+#define MACLONGADDRS0_24    0x0A
+#define MACLONGADDRS0_32    0x0B
+#define MACLONGADDRS0_40    0x0C
+#define MACLONGADDRS0_48    0x0D
+#define MACLONGADDRS0_56    0x0E
+#define RX_FRAME_FILTER     0x0F
+#define PLL_INT1            0x10
+#define PLL_FRAC1_LSB       0x11
+#define PLL_FRAC1_MSB       0x12
+#define MACPANID1_LSB       0x13
+#define MACPANID1_MSB       0x14
+#define MACSHORTADDRS1_LSB  0x15
+#define MACSHORTADDRS1_MSB  0x16
+#define MACLONGADDRS1_0     0x17
+#define MACLONGADDRS1_8     0x18
+#define MACLONGADDRS1_16    0x19
+#define MACLONGADDRS1_24    0x1A
+#define MACLONGADDRS1_32    0x1B
+#define MACLONGADDRS1_40    0x1C
+#define MACLONGADDRS1_48    0x1D
+#define MACLONGADDRS1_56    0x1E
+#define DUAL_PAN_CTRL       0x1F
+#define DUAL_PAN_DWELL      0x20
+#define DUAL_PAN_STS        0x21
+#define CCA1_THRESH         0x22
+#define CCA1_ED_OFFSET_COMP 0x23
+#define LQI_OFFSET_COMP     0x24
+#define CCA_CTRL            0x25
+#define CCA2_CORR_PEAKS     0x26
+#define CCA2_CORR_THRESH    0x27
+#define TMR_PRESCALE        0x28
+//----------------          0x29
+#define GPIO_DATA           0x2A
+#define GPIO_DIR            0x2B
+#define GPIO_PUL_EN         0x2C
+#define GPIO_PUL_SEL        0x2D
+#define GPIO_DS             0x2E
+//--------------            0x2F
+#define ANT_PAD_CTRL        0x30
+#define MISC_PAD_CTRL       0x31
+#define BSM_CTRL            0x32
+//---------------           0x33
+#define _RNG                0x34
+#define RX_BYTE_COUNT       0x35
+#define RX_WTR_MARK         0x36
+#define SOFT_RESET          0x37
+#define TXDELAY             0x38
+#define ACKDELAY            0x39
+#define SEQ_MGR_CTRL        0x3A
+#define SEQ_MGR_STS         0x3B
+#define SEQ_T_STS           0x3C
+#define ABORT_STS           0x3D
+#define CCCA_BUSY_CNT       0x3E
+#define SRC_ADDR_CHECKSUM1  0x3F
+#define SRC_ADDR_CHECKSUM2  0x40
+#define SRC_TBL_VALID1      0x41
+#define SRC_TBL_VALID2      0x42
+#define FILTERFAIL_CODE1    0x43
+#define FILTERFAIL_CODE2    0x44
+#define SLOT_PRELOAD        0x45
+//----------------          0x46
+#define CORR_VT             0x47
+#define SYNC_CTRL           0x48
+#define PN_LSB_0            0x49
+#define PN_LSB_1            0x4A
+#define PN_MSB_0            0x4B
+#define PN_MSB_1            0x4C
+#define CORR_NVAL           0x4D
+#define TX_MODE_CTRL        0x4E
+#define SNF_THR             0x4F
+#define FAD_THR             0x50
+#define ANT_AGC_CTRL        0x51
+#define AGC_THR1            0x52
+#define AGC_THR2            0x53
+#define AGC_HYS             0x54
+#define AFC                 0x55
+//---------------           0x56
+//---------------           0x57
+#define PHY_STS             0x58
+#define RX_MAX_CORR         0x59
+#define RX_MAX_PREAMBLE     0x5A
+#define RSSI                0x5B
+//---------------           0x5C
+//---------------           0x5D
+#define PLL_DIG_CTRL        0x5E
+#define VCO_CAL             0x5F
+#define VCO_BEST_DIFF       0x60
+#define VCO_BIAS            0x61
+#define KMOD_CTRL           0x62
+#define KMOD_CAL            0x63
+#define PA_CAL              0x64
+#define PA_PWRCAL           0x65
+#define ATT_RSSI1           0x66
+#define ATT_RSSI2           0x67
+#define RSSI_OFFSET         0x68
+#define RSSI_SLOPE          0x69
+#define RSSI_CAL1           0x6A
+#define RSSI_CAL2           0x6B
+//---------------           0x6C
+//---------------           0x6D
+#define XTAL_CTRL           0x6E
+#define XTAL_COMP_MIN       0x6F
+#define XTAL_COMP_MAX       0x70
+#define XTAL_GM             0x71
+//---------------           0x72
+//---------------           0x73
+#define LNA_TUNE            0x74
+#define LNA_AGCGAIN         0x75
+//---------------           0x76
+//---------------           0x77
+#define CHF_PMA_GAIN        0x78
+#define CHF_IBUF            0x79
+#define CHF_QBUF            0x7A
+#define CHF_IRIN            0x7B
+#define CHF_QRIN            0x7C
+#define CHF_IL              0x7D
+#define CHF_QL              0x7E
+#define CHF_CC1             0x7F
+#define CHF_CCL             0x80
+#define CHF_CC2             0x81
+#define CHF_IROUT           0x82
+#define CHF_QROUT           0x83
+//---------------           0x84
+//---------------           0x85
+#define RSSI_CTRL           0x86
+//---------------           0x87
+//---------------           0x88
+#define PA_BIAS             0x89
+#define PA_TUNING           0x8A
+//---------------           0x8B
+//---------------           0x8C
+#define PMC_HP_TRIM         0x8D
+#define VREGA_TRIM          0x8E
+//---------------           0x8F
+//---------------           0x90
+#define VCO_CTRL1           0x91
+#define VCO_CTRL2           0x92
+//---------------           0x93
+//---------------           0x94
+#define ANA_SPARE_OUT1      0x95
+#define ANA_SPARE_OUT2      0x96
+#define ANA_SPARE_IN        0x97
+#define MISCELLANEOUS       0x98
+//---------------           0x99
+#define SEQ_MGR_OVRD0       0x9A
+#define SEQ_MGR_OVRD1       0x9B
+#define SEQ_MGR_OVRD2       0x9C
+#define SEQ_MGR_OVRD3       0x9D
+#define SEQ_MGR_OVRD4       0x9E
+#define SEQ_MGR_OVRD5       0x9F
+#define SEQ_MGR_OVRD6       0xA0
+#define SEQ_MGR_OVRD7       0xA1
+//---------------           0xA2
+#define TESTMODE_CTRL       0xA3
+#define DTM_CTRL1           0xA4
+#define DTM_CTRL2           0xA5
+#define ATM_CTRL1           0xA6
+#define ATM_CTRL2           0xA7
+#define ATM_CTRL3           0xA8
+//---------------           0xA9
+#define LIM_FE_TEST_CTRL    0xAA
+#define CHF_TEST_CTRL       0xAB
+#define VCO_TEST_CTRL       0xAC
+#define PLL_TEST_CTRL       0xAD
+#define PA_TEST_CTRL        0xAE
+#define PMC_TEST_CTRL       0xAF
+#define SCAN_DTM_PROTECT_1  0xFE
+#define SCAN_DTM_PROTECT_0  0xFF
+
+// IRQSTS1 bits
+#define cIRQSTS1_RX_FRM_PEND         (1<<7)
+#define cIRQSTS1_PLL_UNLOCK_IRQ      (1<<6)
+#define cIRQSTS1_FILTERFAIL_IRQ      (1<<5)
+#define cIRQSTS1_RXWTRMRKIRQ         (1<<4)
+#define cIRQSTS1_CCAIRQ              (1<<3)
+#define cIRQSTS1_RXIRQ               (1<<2)
+#define cIRQSTS1_TXIRQ               (1<<1)
+#define cIRQSTS1_SEQIRQ              (1<<0)
+
+typedef union regIRQSTS1_tag{
+  uint8_t byte;
+  struct{
+    uint8_t SEQIRQ:1;
+    uint8_t TXIRQ:1;
+    uint8_t RXIRQ:1;
+    uint8_t CCAIRQ:1;
+    uint8_t RXWTRMRKIRQ:1;
+    uint8_t FILTERFAIL_IRQ:1;
+    uint8_t PLL_UNLOCK_IRQ:1;
+    uint8_t RX_FRM_PEND:1;
+  }bit;
+} regIRQSTS1_t;
+
+// IRQSTS2 bits
+#define cIRQSTS2_CRCVALID            (1<<7)
+#define cIRQSTS2_CCA                 (1<<6)
+#define cIRQSTS2_SRCADDR             (1<<5)
+#define cIRQSTS2_PI                  (1<<4)
+#define cIRQSTS2_TMRSTATUS           (1<<3)
+#define cIRQSTS2_ASM_IRQ             (1<<2)
+#define cIRQSTS2_PB_ERR_IRQ          (1<<1)
+#define cIRQSTS2_WAKE_IRQ            (1<<0)
+
+typedef union regIRQSTS2_tag{
+  uint8_t byte;
+  struct{
+    uint8_t WAKE_IRQ:1;
+    uint8_t PB_ERR_IRQ:1;
+    uint8_t ASM_IRQ:1;
+    uint8_t TMRSTATUS:1;
+    uint8_t PI_:1;
+    uint8_t SRCADDR:1;
+    uint8_t CCA:1;
+    uint8_t CRCVALID:1;
+  }bit;
+} regIRQSTS2_t;
+
+// IRQSTS3 bits
+#define cIRQSTS3_TMR4MSK             (1<<7)
+#define cIRQSTS3_TMR3MSK             (1<<6)
+#define cIRQSTS3_TMR2MSK             (1<<5)
+#define cIRQSTS3_TMR1MSK             (1<<4)
+#define cIRQSTS3_TMR4IRQ             (1<<3)
+#define cIRQSTS3_TMR3IRQ             (1<<2)
+#define cIRQSTS3_TMR2IRQ             (1<<1)
+#define cIRQSTS3_TMR1IRQ             (1<<0)
+
+typedef union regIRQSTS3_tag{
+  uint8_t byte;
+  struct{
+    uint8_t TMR1IRQ:1;
+    uint8_t TMR2IRQ:1;
+    uint8_t TMR3IRQ:1;
+    uint8_t TMR4IRQ:1;
+    uint8_t TMR1MSK:1;
+    uint8_t TMR2MSK:1;
+    uint8_t TMR3MSK:1;
+    uint8_t TMR4MSK:1;
+  }bit;
+} regIRQSTS3_t;
+
+// PHY_CTRL1 bits
+#define cPHY_CTRL1_TMRTRIGEN           (1<<7)
+#define cPHY_CTRL1_SLOTTED             (1<<6)
+#define cPHY_CTRL1_CCABFRTX            (1<<5)
+#define cPHY_CTRL1_RXACKRQD            (1<<4)
+#define cPHY_CTRL1_AUTOACK             (1<<3)
+#define cPHY_CTRL1_XCVSEQ              (7<<0)
+
+typedef union regPHY_CTRL1_tag{
+  uint8_t byte;
+  struct{
+    uint8_t XCVSEQ:3;
+    uint8_t AUTOACK:1;
+    uint8_t RXACKRQD:1;
+    uint8_t CCABFRTX:1;
+    uint8_t SLOTTED:1;
+    uint8_t TMRTRIGEN:1;
+  }bit;
+} regPHY_CTRL1_t; 
+
+// PHY_CTRL2 bits
+#define cPHY_CTRL2_CRC_MSK             (1<<7)
+#define cPHY_CTRL2_PLL_UNLOCK_MSK      (1<<6)
+#define cPHY_CTRL2_FILTERFAIL_MSK      (1<<5)
+#define cPHY_CTRL2_RX_WMRK_MSK         (1<<4)
+#define cPHY_CTRL2_CCAMSK              (1<<3)
+#define cPHY_CTRL2_RXMSK               (1<<2)
+#define cPHY_CTRL2_TXMSK               (1<<1)
+#define cPHY_CTRL2_SEQMSK              (1<<0)
+
+typedef union regPHY_CTRL2_tag{
+  uint8_t byte;
+  struct{
+    uint8_t SEQMSK:1;
+    uint8_t TXMSK:1;
+    uint8_t RXMSK:1;
+    uint8_t CCAMSK:1;
+    uint8_t RX_WMRK_MSK:1;
+    uint8_t FILTERFAIL_MSK:1;
+    uint8_t PLL_UNLOCK_MSK:1;
+    uint8_t CRC_MSK:1;
+  }bit;
+} regPHY_CTRL2_t; 
+
+// PHY_CTRL3 bits
+#define cPHY_CTRL3_TMR4CMP_EN          (1<<7)
+#define cPHY_CTRL3_TMR3CMP_EN          (1<<6)
+#define cPHY_CTRL3_TMR2CMP_EN          (1<<5)
+#define cPHY_CTRL3_TMR1CMP_EN          (1<<4)
+#define cPHY_CTRL3_ASM_MSK             (1<<2)
+#define cPHY_CTRL3_PB_ERR_MSK          (1<<1)
+#define cPHY_CTRL3_WAKE_MSK            (1<<0)
+
+typedef union regPHY_CTRL3_tag{
+  uint8_t byte;
+  struct{
+    uint8_t WAKE_MSK:1;
+    uint8_t PB_ERR_MSK:1;
+    uint8_t ASM_MSK:1;
+    uint8_t RESERVED:1;
+    uint8_t TMR1CMP_EN:1;
+    uint8_t TMR2CMP_EN:1;
+    uint8_t TMR3CMP_EN:1;
+    uint8_t TMR4CMP_EN:1;
+  }bit;
+} regPHY_CTRL3_t;
+
+// RX_FRM_LEN bits
+#define cRX_FRAME_LENGTH               (0x7F)
+
+// PHY_CTRL4 bits
+#define cPHY_CTRL4_TRCV_MSK            (1<<7)
+#define cPHY_CTRL4_TC3TMOUT            (1<<6)
+#define cPHY_CTRL4_PANCORDNTR0         (1<<5)
+#define cPHY_CTRL4_CCATYPE             (3<<0)
+#define cPHY_CTRL4_CCATYPE_Shift_c     (3)
+#define cPHY_CTRL4_TMRLOAD             (1<<2)
+#define cPHY_CTRL4_PROMISCUOUS         (1<<1)
+#define cPHY_CTRL4_TC2PRIME_EN         (1<<0)
+
+typedef union regPHY_CTRL4_tag{
+  uint8_t byte;
+  struct{
+    uint8_t TC2PRIME_EN:1;
+    uint8_t PROMISCUOUS:1;
+    uint8_t TMRLOAD:1;
+    uint8_t CCATYPE:2;
+    uint8_t PANCORDNTR0:1;
+    uint8_t TC3TMOUT:1;
+    uint8_t TRCV_MSK:1;
+  }bit;
+} regPHY_CTRL4_t;
+
+// SRC_CTRL bits
+#define cSRC_CTRL_INDEX               (0x0F)
+#define cSRC_CTRL_INDEX_Shift_c       (4)
+#define cSRC_CTRL_ACK_FRM_PND         (1<<3)
+#define cSRC_CTRL_SRCADDR_EN          (1<<2)
+#define cSRC_CTRL_INDEX_EN            (1<<1)
+#define cSRC_CTRL_INDEX_DISABLE       (1<<0)
+
+typedef union regSRC_CTRL_tag{
+  uint8_t byte;
+  struct{
+    uint8_t INDEX_DISABLE:1;
+    uint8_t INDEX_EN:1;
+    uint8_t SRCADDR_EN:1;
+    uint8_t ACK_FRM_PND:1;
+    uint8_t INDEX:4;
+  }bit;
+} regSRC_CTRL_t;
+
+// ASM_CTRL1 bits
+#define cASM_CTRL1_CLEAR               (1<<7)
+#define cASM_CTRL1_START               (1<<6)
+#define cASM_CTRL1_SELFTST             (1<<5)
+#define cASM_CTRL1_CTR                 (1<<4)
+#define cASM_CTRL1_CBC                 (1<<3)
+#define cASM_CTRL1_AES                 (1<<2)
+#define cASM_CTRL1_LOAD_MAC            (1<<1)
+
+// ASM_CTRL2 bits
+#define cASM_CTRL2_DATA_REG_TYPE_SEL          (7)
+#define cASM_CTRL2_DATA_REG_TYPE_SEL_Shift_c  (5)
+#define cASM_CTRL2_TSTPAS                     (1<<1)
+
+// CLK_OUT_CTRL bits
+#define cCLK_OUT_CTRL_EXTEND           (1<<7)
+#define cCLK_OUT_CTRL_HIZ              (1<<6)
+#define cCLK_OUT_CTRL_SR               (1<<5)
+#define cCLK_OUT_CTRL_DS               (1<<4)
+#define cCLK_OUT_CTRL_EN               (1<<3)
+#define cCLK_OUT_CTRL_DIV              (7)
+
+// PWR_MODES bits
+#define cPWR_MODES_XTAL_READY          (1<<5)
+#define cPWR_MODES_XTALEN              (1<<4)
+#define cPWR_MODES_ASM_CLK_EN          (1<<3)
+#define cPWR_MODES_AUTODOZE            (1<<1)
+#define cPWR_MODES_PMC_MODE            (1<<0)
+
+// RX_FRAME_FILTER bits
+#define cRX_FRAME_FLT_FRM_VER             (0xC0)
+#define cRX_FRAME_FLT_FRM_VER_Shift_c     (6)
+#define cRX_FRAME_FLT_ACTIVE_PROMISCUOUS  (1<<5)
+#define cRX_FRAME_FLT_NS_FT               (1<<4)
+#define cRX_FRAME_FLT_CMD_FT              (1<<3)
+#define cRX_FRAME_FLT_ACK_FT              (1<<2)
+#define cRX_FRAME_FLT_DATA_FT             (1<<1)
+#define cRX_FRAME_FLT_BEACON_FT           (1<<0)
+
+typedef union regRX_FRAME_FILTER_tag{
+  uint8_t byte;
+  struct{
+    uint8_t FRAME_FLT_BEACON_FT:1;
+    uint8_t FRAME_FLT_DATA_FT:1;
+    uint8_t FRAME_FLT_ACK_FT:1;
+    uint8_t FRAME_FLT_CMD_FT:1;
+    uint8_t FRAME_FLT_NS_FT:1;
+    uint8_t FRAME_FLT_ACTIVE_PROMISCUOUS:1;
+    uint8_t FRAME_FLT_FRM_VER:2;
+  }bit;
+} regRX_FRAME_FILTER_t; 
+
+// DUAL_PAN_CTRL bits
+#define cDUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_MSK       (0xF0)
+#define cDUAL_PAN_CTRL_DUAL_PAN_SAM_LVL_Shift_c   (4)
+#define cDUAL_PAN_CTRL_CURRENT_NETWORK            (1<<3)
+#define cDUAL_PAN_CTRL_PANCORDNTR1                (1<<2)
+#define cDUAL_PAN_CTRL_DUAL_PAN_AUTO              (1<<1)
+#define cDUAL_PAN_CTRL_ACTIVE_NETWORK             (1<<0)
+
+// DUAL_PAN_STS bits
+#define cDUAL_PAN_STS_RECD_ON_PAN1        (1<<7)
+#define cDUAL_PAN_STS_RECD_ON_PAN0        (1<<6)
+#define cDUAL_PAN_STS_DUAL_PAN_REMAIN     (0x3F)
+
+// CCA_CTRL bits
+#define cCCA_CTRL_AGC_FRZ_EN          (1<<6)
+#define cCCA_CTRL_CONT_RSSI_EN        (1<<5)
+#define cCCA_CTRL_LQI_RSSI_NOT_CORR   (1<<4)
+#define cCCA_CTRL_CCA3_AND_NOT_OR     (1<<3)
+#define cCCA_CTRL_POWER_COMP_EN_LQI   (1<<2)
+#define cCCA_CTRL_POWER_COMP_EN_ED    (1<<1)
+#define cCCA_CTRL_POWER_COMP_EN_CCA1  (1<<0)
+
+// GPIO_DATA bits
+#define cGPIO_DATA_7        (1<<7)
+#define cGPIO_DATA_6        (1<<6)
+#define cGPIO_DATA_5        (1<<5)
+#define cGPIO_DATA_4        (1<<4)
+#define cGPIO_DATA_3        (1<<3)
+#define cGPIO_DATA_2        (1<<2)
+#define cGPIO_DATA_1        (1<<1)
+#define cGPIO_DATA_0        (1<<0)
+
+// GPIO_DIR bits
+#define cGPIO_DIR_7         (1<<7)
+#define cGPIO_DIR_6         (1<<6)
+#define cGPIO_DIR_5         (1<<5)
+#define cGPIO_DIR_4         (1<<4)
+#define cGPIO_DIR_3         (1<<3)
+#define cGPIO_DIR_2         (1<<2)
+#define cGPIO_DIR_1         (1<<1)
+#define cGPIO_DIR_0         (1<<0)
+
+// GPIO_PUL_EN bits
+#define cGPIO_PUL_EN_7      (1<<7)
+#define cGPIO_PUL_EN_6      (1<<6)
+#define cGPIO_PUL_EN_5      (1<<5)
+#define cGPIO_PUL_EN_4      (1<<4)
+#define cGPIO_PUL_EN_3      (1<<3)
+#define cGPIO_PUL_EN_2      (1<<2)
+#define cGPIO_PUL_EN_1      (1<<1)
+#define cGPIO_PUL_EN_0      (1<<0)
+
+// GPIO_PUL_SEL bits
+#define cGPIO_PUL_SEL_7     (1<<7)
+#define cGPIO_PUL_SEL_6     (1<<6)
+#define cGPIO_PUL_SEL_5     (1<<5)
+#define cGPIO_PUL_SEL_4     (1<<4)
+#define cGPIO_PUL_SEL_3     (1<<3)
+#define cGPIO_PUL_SEL_2     (1<<2)
+#define cGPIO_PUL_SEL_1     (1<<1)
+#define cGPIO_PUL_SEL_0     (1<<0)
+
+// GPIO_DS bits
+#define cGPIO_DS_7          (1<<7)
+#define cGPIO_DS_6          (1<<6)
+#define cGPIO_DS_5          (1<<5)
+#define cGPIO_DS_4          (1<<4)
+#define cGPIO_DS_3          (1<<3)
+#define cGPIO_DS_2          (1<<2)
+#define cGPIO_DS_1          (1<<1)
+#define cGPIO_DS_0          (1<<0)
+
+// SPI_CTRL bits
+//#define cSPI_CTRL_MISO_HIZ_EN        (1<<1)
+//#define cSPI_CTRL_PB_PROTECT         (1<<0)
+
+// ANT_PAD_CTRL bits
+#define cANT_PAD_CTRL_ANTX_POL           (0x0F)
+#define cANT_PAD_CTRL_ANTX_POL_Shift_c   (4)
+#define cANT_PAD_CTRL_ANTX_CTRLMODE      (1<<3)
+#define cANT_PAD_CTRL_ANTX_HZ            (1<<2)
+#define cANT_PAD_CTRL_ANTX_EN            (3)
+
+// MISC_PAD_CTRL bits
+#define cMISC_PAD_CTRL_MISO_HIZ_EN        (1<<3)
+#define cMISC_PAD_CTRL_IRQ_B_OD           (1<<2)
+#define cMISC_PAD_CTRL_NON_GPIO_DS        (1<<1)
+#define cMISC_PAD_CTRL_ANTX_CURR          (1<<0)
+
+// ANT_AGC_CTRL bits
+#define cANT_AGC_CTRL_FAD_EN_Shift_c    (0)
+#define cANT_AGC_CTRL_FAD_EN_Mask_c     (1<<cANT_AGC_CTRL_FAD_EN_Shift_c)
+#define cANT_AGC_CTRL_ANTX_Shift_c      (1)
+#define cANT_AGC_CTRL_ANTX_Mask_c       (1<<cANT_AGC_CTRL_ANTX_Shift_c)
+
+// BSM_CTRL bits
+#define cBSM_CTRL_BSM_EN                  (1<<0)
+
+// SOFT_RESET bits
+#define cSOFT_RESET_SOG_RST            (1<<7)
+#define cSOFT_RESET_REGS_RST           (1<<4)
+#define cSOFT_RESET_PLL_RST            (1<<3)
+#define cSOFT_RESET_TX_RST             (1<<2)
+#define cSOFT_RESET_RX_RST             (1<<1)
+#define cSOFT_RESET_SEQ_MGR_RST        (1<<0)
+
+// SEQ_MGR_CTRL bits
+#define cSEQ_MGR_CTRL_SEQ_STATE_CTRL          (3)
+#define cSEQ_MGR_CTRL_SEQ_STATE_CTRL_Shift_c  (6)
+#define cSEQ_MGR_CTRL_NO_RX_RECYCLE           (1<<5)
+#define cSEQ_MGR_CTRL_LATCH_PREAMBLE          (1<<4)
+#define cSEQ_MGR_CTRL_EVENT_TMR_DO_NOT_LATCH  (1<<3)
+#define cSEQ_MGR_CTRL_CLR_NEW_SEQ_INHIBIT     (1<<2)
+#define cSEQ_MGR_CTRL_PSM_LOCK_DIS            (1<<1)
+#define cSEQ_MGR_CTRL_PLL_ABORT_OVRD          (1<<0)
+
+// SEQ_MGR_STS bits
+#define cSEQ_MGR_STS_TMR2_SEQ_TRIG_ARMED (1<<7)
+#define cSEQ_MGR_STS_RX_MODE             (1<<6)
+#define cSEQ_MGR_STS_RX_TIMEOUT_PENDING  (1<<5)
+#define cSEQ_MGR_STS_NEW_SEQ_INHIBIT     (1<<4)
+#define cSEQ_MGR_STS_SEQ_IDLE            (1<<3)
+#define cSEQ_MGR_STS_XCVSEQ_ACTUAL       (7)
+
+// ABORT_STS bits
+#define cABORT_STS_PLL_ABORTED        (1<<2)
+#define cABORT_STS_TC3_ABORTED        (1<<1)
+#define cABORT_STS_SW_ABORTED         (1<<0)
+
+// FILTERFAIL_CODE2 bits
+#define cFILTERFAIL_CODE2_PAN_SEL  (1<<7)
+#define cFILTERFAIL_CODE2_9_8      (3)
+
+// PHY_STS bits
+#define cPHY_STS_PLL_UNLOCK  (1<<7)
+#define cPHY_STS_PLL_LOCK_ERR        (1<<6)
+#define cPHY_STS_PLL_LOCK            (1<<5)
+#define cPHY_STS_CRCVALID            (1<<3)
+#define cPHY_STS_FILTERFAIL_FLAG_SEL (1<<2)
+#define cPHY_STS_SFD_DET             (1<<1)
+#define cPHY_STS_PREAMBLE_DET        (1<<0)
+
+// TESTMODE_CTRL bits
+#define cTEST_MODE_CTRL_HOT_ANT            (1<<4)
+#define cTEST_MODE_CTRL_IDEAL_RSSI_EN      (1<<3)
+#define cTEST_MODE_CTRL_IDEAL_PFC_EN       (1<<2)
+#define cTEST_MODE_CTRL_CONTINUOUS_EN      (1<<1)
+#define cTEST_MODE_CTRL_FPGA_EN            (1<<0)
+
+// DTM_CTRL1 bits
+#define cDTM_CTRL1_ATM_LOCKED  (1<<7)
+#define cDTM_CTRL1_DTM_EN      (1<<6)
+#define cDTM_CTRL1_PAGE5       (1<<5)
+#define cDTM_CTRL1_PAGE4       (1<<4)
+#define cDTM_CTRL1_PAGE3       (1<<3)
+#define cDTM_CTRL1_PAGE2       (1<<2)
+#define cDTM_CTRL1_PAGE1       (1<<1)
+#define cDTM_CTRL1_PAGE0       (1<<0)
+
+// TX_MODE_CTRL
+#define cTX_MODE_CTRL_TX_INV   (1<<4)
+#define cTX_MODE_CTRL_BT_EN    (1<<3)
+#define cTX_MODE_CTRL_DTS2     (1<<2)
+#define cTX_MODE_CTRL_DTS1     (1<<1)
+#define cTX_MODE_CTRL_DTS0     (1<<0)
+
+#define cTX_MODE_CTRL_DTS_MASK (7)
+
+// CLK_OUT_CTRL bits
+#define cCLK_OUT_EXTEND        (1<<7)
+#define cCLK_OUT_HIZ           (1<<6)
+#define cCLK_OUT_SR            (1<<5)
+#define cCLK_OUT_DS            (1<<4)
+#define cCLK_OUT_EN            (1<<3)
+#define cCLK_OUT_DIV_Mask      (7<<0)
+
+#define gCLK_OUT_FREQ_32_MHz      (0)
+#define gCLK_OUT_FREQ_16_MHz      (1)
+#define gCLK_OUT_FREQ_8_MHz       (2)
+#define gCLK_OUT_FREQ_4_MHz       (3)
+#define gCLK_OUT_FREQ_1_MHz       (4)
+#define gCLK_OUT_FREQ_250_KHz     (5)
+#define gCLK_OUT_FREQ_62_5_KHz    (6)
+#define gCLK_OUT_FREQ_32_78_KHz   (7)
+#define gCLK_OUT_FREQ_DISABLE     (8)
+
+
+
+
+#endif /* __MCR20_REG_H__ */
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/NanostackRfPhyMcr20a.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/NanostackRfPhyMcr20a.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1813 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NanostackRfPhyMcr20a.h"
+#include "ns_types.h"
+#include "platform/arm_hal_interrupt.h"
+#include "nanostack/platform/arm_hal_phy.h"
+#include <string.h>
+#include "rtos.h"
+
+/* Freescale headers which are for C files */
+extern "C" {
+#include "MCR20Drv.h"
+#include "MCR20Reg.h"
+#include "MCR20Overwrites.h"
+}
+
+
+#define RF_BUFFER_SIZE 128
+
+/*Radio RX and TX state definitions*/
+#define RFF_ON 0x01
+#define RFF_RX 0x02
+#define RFF_TX 0x04
+#define RFF_CCA 0x08
+
+#define RF_MODE_NORMAL  0
+#define RF_MODE_SNIFFER 1
+
+#define RF_CCA_THRESHOLD 75 /* -75 dBm */
+
+#define RF_TX_POWER_MAX 0
+
+/* PHY constants in symbols */
+#define gPhyWarmUpTime_c       9
+#define gPhySHRDuration_c     10
+#define gPhySymbolsPerOctet_c  2
+#define gPhyAckWaitDuration_c 54
+
+#define gCcaED_c               0
+#define gCcaCCA_MODE1_c        1
+
+#define gXcvrRunState_d       gXcvrPwrAutodoze_c
+#if !defined(TARGET_KW24D)
+  #define gXcvrLowPowerState_d  gXcvrPwrHibernate_c
+#else 
+  #define gXcvrLowPowerState_d  gXcvrPwrAutodoze_c
+#endif
+
+/* MCR20A XCVR states */
+typedef enum xcvrState_tag{
+  gIdle_c,
+  gRX_c,
+  gTX_c,
+  gCCA_c,
+  gTR_c,
+  gCCCA_c,
+}xcvrState_t;
+
+/* MCR20A XCVR low power states */
+typedef enum xcvrPwrMode_tag{
+    gXcvrPwrIdle_c,
+    gXcvrPwrAutodoze_c,
+    gXcvrPwrDoze_c,
+    gXcvrPwrHibernate_c
+}xcvrPwrMode_t;
+
+
+/*RF Part Type*/
+typedef enum
+{
+    FREESCALE_UNKNOW_DEV = 0,
+    FREESCALE_MCR20A
+}rf_trx_part_e;
+
+/*Atmel RF states*/
+typedef enum
+{
+    NOP = 0x00,
+    BUSY_RX = 0x01,
+    RF_TX_START = 0x02,
+    FORCE_TRX_OFF = 0x03,
+    FORCE_PLL_ON = 0x04,
+    RX_ON = 0x06,
+    TRX_OFF = 0x08,
+    PLL_ON = 0x09,
+    BUSY_RX_AACK = 0x11,
+    SLEEP = 0x0F,
+    RX_AACK_ON = 0x16,
+    TX_ARET_ON = 0x19
+}rf_trx_states_t;
+
+/*RF receive buffer*/
+static uint8_t rf_buffer[RF_BUFFER_SIZE];
+
+/* TX info */
+static uint8_t  radio_tx_power = 0x17; /* 0 dBm */
+static uint8_t  mac_tx_handle = 0;
+static uint8_t  need_ack = 0;
+static uint16_t tx_len = 0;
+
+/* RF driver data */
+static xcvrState_t mPhySeqState;
+static xcvrPwrMode_t mPwrState;
+static phy_device_driver_s device_driver;
+static uint8_t mStatusAndControlRegs[8];
+static uint8_t rf_rnd = 0;
+static int8_t  rf_radio_driver_id = -1;
+static uint8_t MAC_address[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+/* Driver instance handle and hardware */
+static NanostackRfPhyMcr20a *rf = NULL;
+static SPI *spi = NULL;
+static DigitalOut *cs = NULL;
+static DigitalOut *rst = NULL;
+static InterruptIn *irq = NULL;
+static DigitalIn *irq_pin = NULL;
+static Thread irq_thread(osPriorityRealtime, 1024);
+
+/* Channel info */                 /* 2405    2410    2415    2420    2425    2430    2435    2440    2445    2450    2455    2460    2465    2470    2475    2480 */
+static const uint8_t  pll_int[16] =  {0x0B,   0x0B,   0x0B,   0x0B,   0x0B,   0x0B,   0x0C,   0x0C,   0x0C,   0x0C,   0x0C,   0x0C,   0x0D,   0x0D,   0x0D,   0x0D};
+static const uint16_t pll_frac[16] = {0x2800, 0x5000, 0x7800, 0xA000, 0xC800, 0xF000, 0x1800, 0x4000, 0x6800, 0x9000, 0xB800, 0xE000, 0x0800, 0x3000, 0x5800, 0x8000};
+static uint8_t rf_phy_channel = 0;
+
+/* Channel configurations for 2.4 */
+static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK};
+
+static const phy_device_channel_page_s phy_channel_pages[] = {
+        { CHANNEL_PAGE_0, &phy_24ghz},
+        { CHANNEL_PAGE_0, NULL}
+};
+
+
+static rf_trx_part_e rf_radio_type_read(void);
+
+MBED_UNUSED static void rf_ack_wait_timer_start(uint16_t slots);
+MBED_UNUSED static void rf_ack_wait_timer_stop(void);
+MBED_UNUSED static void rf_handle_cca_ed_done(void);
+MBED_UNUSED static void rf_handle_tx_end(void);
+MBED_UNUSED static void rf_handle_rx_end(void);
+MBED_UNUSED static void rf_on(void);
+MBED_UNUSED static void rf_receive(void);
+MBED_UNUSED static void rf_poll_trx_state_change(rf_trx_states_t trx_state);
+MBED_UNUSED static void rf_init(void);
+MBED_UNUSED static void rf_set_mac_address(const uint8_t *ptr);
+MBED_UNUSED static int8_t rf_device_register(void);
+MBED_UNUSED static void rf_device_unregister(void);
+MBED_UNUSED static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol );
+MBED_UNUSED static void rf_cca_abort(void);
+MBED_UNUSED static void rf_read_mac_address(uint8_t *ptr);
+MBED_UNUSED static int8_t rf_read_random(void);
+MBED_UNUSED static void rf_calibration_cb(void);
+MBED_UNUSED static void rf_init_phy_mode(void);
+MBED_UNUSED static void rf_ack_wait_timer_interrupt(void);
+MBED_UNUSED static void rf_calibration_timer_interrupt(void);
+MBED_UNUSED static void rf_calibration_timer_start(uint32_t slots);
+MBED_UNUSED static void rf_cca_timer_interrupt(void);
+MBED_UNUSED static void rf_cca_timer_start(uint32_t slots);
+MBED_UNUSED static uint16_t rf_get_phy_mtu_size(void);
+MBED_UNUSED static uint8_t rf_scale_lqi(int8_t rssi);
+
+/**
+ *  RF output power write
+ *
+ * \brief TX power has to be set before network start.
+ *
+ * \param power
+ *              See datasheet for TX power settings
+ *
+ * \return 0, Supported Value
+ * \return -1, Not Supported Value
+ */
+MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power);
+MBED_UNUSED static uint8_t rf_tx_power_get(void);
+MBED_UNUSED static int8_t rf_enable_antenna_diversity(void);
+
+/* Private functions */
+MBED_UNUSED static void    rf_abort(void);
+MBED_UNUSED static void    rf_promiscuous(uint8_t mode);
+MBED_UNUSED static void    rf_get_timestamp(uint32_t *pRetClk);
+MBED_UNUSED static void    rf_set_timeout(uint32_t *pEndTime);
+MBED_UNUSED static void    rf_set_power_state(xcvrPwrMode_t newState);
+MBED_UNUSED static uint8_t rf_if_read_rnd(void);
+MBED_UNUSED static uint8_t rf_convert_LQI(uint8_t hwLqi);
+MBED_UNUSED static uint8_t rf_get_channel_energy(void);
+MBED_UNUSED static uint8_t rf_convert_energy_level(uint8_t energyLevel);
+MBED_UNUSED static int8_t  rf_convert_LQI_to_RSSI(uint8_t lqi);
+MBED_UNUSED static int8_t  rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel);
+MBED_UNUSED static int8_t  rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr);
+MBED_UNUSED static int8_t  rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr);
+MBED_UNUSED static void rf_mac64_read(uint8_t *address);
+static void PHY_InterruptThread(void);
+static void handle_interrupt(void);
+
+
+/*
+ * \brief Read connected radio part.
+ *
+ * This function only return valid information when rf_init() is called
+ *
+ * \return
+ */
+static rf_trx_part_e rf_radio_type_read(void)
+{
+    return FREESCALE_MCR20A;
+}
+
+/*
+ * \brief Function initialises and registers the RF driver.
+ *
+ * \param none
+ *
+ * \return rf_radio_driver_id Driver ID given by NET library
+ */
+static int8_t rf_device_register(void)
+{
+    rf_trx_part_e radio_type;
+
+    rf_init();
+
+
+
+    radio_type = rf_radio_type_read();
+    if(radio_type == FREESCALE_MCR20A)
+    {
+        /*Set pointer to MAC address*/
+        device_driver.PHY_MAC = MAC_address;
+        device_driver.driver_description = (char*)"FREESCALE_MAC";
+
+        //Create setup Used Radio chips
+        /*Type of RF PHY is SubGHz*/
+        device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE;
+
+        device_driver.phy_channel_pages = phy_channel_pages;
+        /*Maximum size of payload is 127*/
+        device_driver.phy_MTU = 127;
+        /*No header in PHY*/
+        device_driver.phy_header_length = 0;
+        /*No tail in PHY*/
+        device_driver.phy_tail_length = 0;
+        /*Set address write function*/
+        device_driver.address_write = &rf_address_write;
+        /*Set RF extension function*/
+        device_driver.extension = &rf_extension;
+        /*Set RF state control function*/
+        device_driver.state_control = &rf_interface_state_control;
+        /*Set transmit function*/
+        device_driver.tx = &rf_start_cca;
+        /*Upper layer callbacks init to NULL*/
+        device_driver.phy_rx_cb = NULL;
+        device_driver.phy_tx_done_cb = NULL;
+        /*Virtual upper data callback init to NULL*/
+        device_driver.arm_net_virtual_rx_cb = NULL;
+        device_driver.arm_net_virtual_tx_cb = NULL;
+
+        /*Register device driver*/
+        rf_radio_driver_id = arm_net_phy_register(&device_driver);
+    }
+
+    return rf_radio_driver_id;
+}
+
+/*
+ * \brief Function unregisters the RF driver.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_device_unregister(void)
+{
+    arm_net_phy_unregister(rf_radio_driver_id);
+}
+
+/*
+ * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator.
+ *
+ * \param none
+ *
+ * \return random value
+ */
+static int8_t rf_read_random(void)
+{
+    return rf_rnd;
+}
+
+/*
+ * \brief Function is a call back for ACK wait timeout.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_interrupt(void)
+{
+    /* The packet was transmitted successfully, but no ACK was received */
+    if (device_driver.phy_tx_done_cb) {
+        device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
+    }
+    rf_receive();
+}
+
+/*
+ * \brief Function is a call back for calibration interval timer.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_calibration_timer_interrupt(void)
+{
+}
+
+/*
+ * \brief Function is a call back for cca interval timer.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_cca_timer_interrupt(void)
+{
+    /* CCA time-out handled by Hardware */
+}
+
+
+/*
+ * \brief Function starts the ACK wait time-out.
+ *
+ * \param slots The ACK wait time-out in [symbols]
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_start(uint16_t time)
+{
+    uint32_t timeout;
+
+    rf_get_timestamp(&timeout);
+    timeout += time;
+    rf_set_timeout(&timeout);
+}
+
+/*
+ * \brief Function starts the calibration interval.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_calibration_timer_start(uint32_t slots)
+{
+    (void)slots;
+}
+
+/*
+ * \brief Function starts the CCA timout.
+ *
+ * \param slots Given slots, resolution 50us
+ *
+ * \return none
+ */
+static void rf_cca_timer_start(uint32_t slots)
+{
+    (void)slots;
+}
+
+/*
+ * \brief Function stops the ACK wait timeout.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_ack_wait_timer_stop(void)
+{
+}
+
+/*
+ * \brief Function reads the MAC address array.
+ *
+ * \param ptr Pointer to read array
+ *
+ * \return none
+ */
+static void rf_read_mac_address(uint8_t *ptr)
+{
+    memcpy(ptr, MAC_address, 8);
+}
+
+/*
+ * \brief Function sets the MAC address array.
+ *
+ * \param ptr Pointer to given MAC address array
+ *
+ * \return none
+ */
+static void rf_set_mac_address(const uint8_t *ptr)
+{
+    memcpy(MAC_address, ptr, 8);
+}
+
+static uint16_t rf_get_phy_mtu_size(void)
+{
+    return device_driver.phy_MTU;
+}
+
+/*
+ * \brief Function writes 16-bit address in RF address filter.
+ *
+ * \param short_address Given short address
+ *
+ * \return none
+ */
+static void rf_set_short_adr(uint8_t * short_address)
+{
+    /* Write one register at a time to be accessible from hibernate mode */
+    MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_MSB, short_address[0]);
+    MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_LSB, short_address[1]);
+}
+
+/*
+ * \brief Function writes PAN Id in RF PAN Id filter.
+ *
+ * \param pan_id Given PAN Id
+ *
+ * \return none
+ */
+static void rf_set_pan_id(uint8_t *pan_id)
+{
+    /* Write one register at a time to be accessible from hibernate mode */
+    MCR20Drv_IndirectAccessSPIWrite(MACPANID0_MSB, pan_id[0]);
+    MCR20Drv_IndirectAccessSPIWrite(MACPANID0_LSB, pan_id[1]);
+}
+
+/*
+ * \brief Function writes 64-bit address in RF address filter.
+ *
+ * \param address Given 64-bit address
+ *
+ * \return none
+ */
+static void rf_set_address(uint8_t *address)
+{
+    /* Write one register at a time to be accessible from hibernate mode */
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_0,  address[7]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_8,  address[6]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_16, address[5]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_24, address[4]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_32, address[3]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_40, address[2]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_48, address[1]);
+    MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_56, address[0]);
+}
+
+/*
+ * \brief Function sets the RF channel.
+ *
+ * \param ch New channel
+ *
+ * \return none
+ */
+static void rf_channel_set(uint8_t channel)
+{
+    rf_phy_channel = channel;
+    MCR20Drv_DirectAccessSPIWrite(PLL_INT0, pll_int[channel - 11]);
+    MCR20Drv_DirectAccessSPIMultiByteWrite(PLL_FRAC0_LSB, (uint8_t *) &pll_frac[channel - 11], 2);
+}
+
+
+/*
+ * \brief Function initialises the radio driver and resets the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_init(void)
+{
+    uint32_t index;
+    mPhySeqState = gIdle_c;
+    mPwrState = gXcvrPwrIdle_c;
+    /*Reset RF module*/
+    MCR20Drv_RESET();
+    /* Initialize the transceiver SPI driver */
+    MCR20Drv_Init();
+    /* Disable Tristate on MISO for SPI reads */
+    MCR20Drv_IndirectAccessSPIWrite(MISC_PAD_CTRL, 0x02);
+    /* Set XCVR clock output settings */
+    #if !defined(TARGET_KW24D)
+      MCR20Drv_Set_CLK_OUT_Freq(gMCR20_ClkOutFreq_d);
+    #endif
+    /* Set default XCVR power state */
+    rf_set_power_state(gXcvrRunState_d);
+
+    /* PHY_CTRL1 default HW settings  + AUTOACK enabled */
+    mStatusAndControlRegs[PHY_CTRL1] = cPHY_CTRL1_AUTOACK;
+    /* PHY_CTRL2 : mask all PP interrupts */
+    mStatusAndControlRegs[PHY_CTRL2] = cPHY_CTRL2_CRC_MSK | \
+                                       cPHY_CTRL2_PLL_UNLOCK_MSK | \
+                                       /*cPHY_CTRL2_FILTERFAIL_MSK | */ \
+                                       cPHY_CTRL2_RX_WMRK_MSK | \
+                                       cPHY_CTRL2_CCAMSK | \
+                                       cPHY_CTRL2_RXMSK | \
+                                       cPHY_CTRL2_TXMSK | \
+                                       cPHY_CTRL2_SEQMSK;
+    /* PHY_CTRL3 : enable timer 3 and disable remaining interrupts */
+    mStatusAndControlRegs[PHY_CTRL3] = cPHY_CTRL3_ASM_MSK    | \
+                                       cPHY_CTRL3_PB_ERR_MSK | \
+                                       cPHY_CTRL3_WAKE_MSK   | \
+                                       cPHY_CTRL3_TMR3CMP_EN;
+    /* PHY_CTRL4 unmask global TRX interrupts, enable 16 bit mode for TC2 - TC2 prime EN */
+    mStatusAndControlRegs[PHY_CTRL4] = cPHY_CTRL4_TC2PRIME_EN | (gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c);
+    /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after initialization */
+    mStatusAndControlRegs[IRQSTS1] = cIRQSTS1_PLL_UNLOCK_IRQ | \
+                                     cIRQSTS1_FILTERFAIL_IRQ | \
+                                     cIRQSTS1_RXWTRMRKIRQ | \
+                                     cIRQSTS1_CCAIRQ | \
+                                     cIRQSTS1_RXIRQ | \
+                                     cIRQSTS1_TXIRQ | \
+                                     cIRQSTS1_SEQIRQ;
+    
+    mStatusAndControlRegs[IRQSTS2] = cIRQSTS2_ASM_IRQ | cIRQSTS2_PB_ERR_IRQ | cIRQSTS2_WAKE_IRQ;
+    /* Mask and clear all TMR IRQs */
+    mStatusAndControlRegs[IRQSTS3] = cIRQSTS3_TMR4MSK | cIRQSTS3_TMR3MSK | cIRQSTS3_TMR2MSK | cIRQSTS3_TMR1MSK | \
+                                     cIRQSTS3_TMR4IRQ | cIRQSTS3_TMR3IRQ | cIRQSTS3_TMR2IRQ | cIRQSTS3_TMR1IRQ;
+    /* Write settings to XCVR */
+    MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 5);
+    /* Clear all interrupts */
+    MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, &mStatusAndControlRegs[IRQSTS1], 3);
+    
+    /*  RX_FRAME_FILTER. Accept FrameVersion 0 and 1 packets, reject all others */
+    MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, (cRX_FRAME_FLT_FRM_VER | \
+                                                      cRX_FRAME_FLT_BEACON_FT | \
+                                                      cRX_FRAME_FLT_DATA_FT | \
+                                                      cRX_FRAME_FLT_CMD_FT ));
+    /* Direct register overwrites */
+    for (index = 0; index < sizeof(overwrites_direct)/sizeof(overwrites_t); index++)
+        MCR20Drv_DirectAccessSPIWrite(overwrites_direct[index].address, overwrites_direct[index].data);
+    /* Indirect register overwrites */
+    for (index = 0; index < sizeof(overwrites_indirect)/sizeof(overwrites_t); index++)
+        MCR20Drv_IndirectAccessSPIWrite(overwrites_indirect[index].address, overwrites_indirect[index].data);
+
+    /* Set the CCA energy threshold value */
+    MCR20Drv_IndirectAccessSPIWrite(CCA1_THRESH, RF_CCA_THRESHOLD);
+    /* Set prescaller to obtain 1 symbol (16us) timebase */
+    MCR20Drv_IndirectAccessSPIWrite(TMR_PRESCALE, 0x05);
+
+    MCR20Drv_IRQ_Enable();
+
+    /*Read random variable. This will be used when seeding pseudo-random generator*/
+    rf_rnd = rf_if_read_rnd();
+    /*Read eui64*/
+    rf_mac64_read(MAC_address);
+    /*set default channel to 11*/
+    rf_channel_set(11);
+    /*Start receiver*/
+    rf_receive();
+}
+
+/**
+ * \brief Function gets called when MAC is setting radio off.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_off(void)
+{
+    /* Abort any ongoing sequences */
+    rf_abort();
+    /* Set XCVR in a low power state */
+    rf_set_power_state(gXcvrLowPowerState_d);
+}
+
+/*
+ * \brief Function polls the RF state until it has changed to desired state.
+ *
+ * \param trx_state RF state
+ *
+ * \return none
+ */
+static void rf_poll_trx_state_change(rf_trx_states_t trx_state)
+{
+    (void)trx_state;
+}
+
+/*
+ * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO.
+ *
+ * \param data_ptr Pointer to TX data
+ * \param data_length Length of the TX data
+ * \param tx_handle Handle to transmission
+ * \return 0 Success
+ * \return -1 Busy
+ */
+static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol )
+{
+    uint8_t ccaMode;
+
+    /* Parameter validation */
+    if( !data_ptr || (data_length > 125) || (PHY_LAYER_PAYLOAD != data_protocol) )
+    {
+        return -1;
+    }
+
+    if( mPhySeqState == gRX_c )
+    {
+        uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F;
+        /* Check for an Rx in progress. */
+        if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16))
+        {
+            if (device_driver.phy_tx_done_cb) {
+                device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
+            }
+            return -1;
+        }
+        rf_abort();
+    }
+
+    /*Check if transmitter is busy*/
+    if( mPhySeqState != gIdle_c )
+    {
+        /*Return busy*/
+        return -1;
+    }
+
+    /*Store TX handle*/
+    mac_tx_handle = tx_handle;
+    /*Check if transmitted data needs to be acked*/
+    need_ack = (*data_ptr & 0x20) == 0x20;
+
+    /* Set XCVR power state in run mode */
+    rf_set_power_state(gXcvrRunState_d);
+    /* Load data into XCVR */
+    tx_len = data_length + 2;
+    MCR20Drv_PB_SPIBurstWrite(data_ptr - 1, data_length + 1);
+    MCR20Drv_PB_SPIByteWrite(0,tx_len);
+    
+    /* Set CCA mode 1 */
+    ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE;
+    if( ccaMode != gCcaCCA_MODE1_c )
+    {
+        mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c);
+        mStatusAndControlRegs[PHY_CTRL4] |= gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c;
+        MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]);
+    }
+
+    /* Read XCVR registers */
+    mStatusAndControlRegs[0] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[1], 4);
+    mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+    mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c;
+    mPhySeqState = gCCA_c;
+
+    /* Ensure that no spurious interrupts are raised */
+    mStatusAndControlRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */
+    mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ);
+    MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
+
+    /* Write XCVR settings */
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+    
+    /* Unmask SEQ interrupt */
+    mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]);
+
+    /*Return success*/
+    return 0;
+}
+
+/*
+ * \brief Function aborts CCA process.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_cca_abort(void)
+{
+    rf_abort();
+}
+
+/*
+ * \brief Function starts the transmission of the frame. Called from ISR context!
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_start_tx(void)
+{
+    /* Perform TxRxAck sequence if required by phyTxMode */
+    if( need_ack )
+    {
+        mStatusAndControlRegs[PHY_CTRL1] |= cPHY_CTRL1_RXACKRQD;
+        mPhySeqState = gTR_c;
+    }
+    else
+    {
+        mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_RXACKRQD);
+        mPhySeqState = gTX_c;
+    }
+
+    mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+    mStatusAndControlRegs[PHY_CTRL1] |= mPhySeqState;
+    
+    /* Unmask SEQ interrupt */
+    mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
+
+    /* Start the sequence immediately */
+    MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 2);
+
+    if( need_ack )
+    {
+        rf_ack_wait_timer_start(gPhyWarmUpTime_c + gPhySHRDuration_c + tx_len * gPhySymbolsPerOctet_c + gPhyAckWaitDuration_c);
+    }
+}
+
+/*
+ * \brief Function sets the RF in RX state. Called from ISR context!
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_receive(void)
+{
+    uint8_t phyRegs[5];
+
+    /* RX can start only from Idle state */
+    if( mPhySeqState != gIdle_c )
+    {
+        return;
+    }
+
+    /* Set XCVR power state in run mode */
+    rf_set_power_state(gXcvrRunState_d);
+    /* read XVCR settings */
+    phyRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &phyRegs[IRQSTS2], 4);
+    /* unmask SEQ interrupt */
+    phyRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK);
+    /* set XcvrSeq to RX */
+    phyRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+    phyRegs[PHY_CTRL1] |=  gRX_c;
+    mPhySeqState = gRX_c;
+    /* Ensure that no spurious interrupts are raised */
+    phyRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */
+    phyRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ;
+    /* sync settings with XCVR */
+    MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, phyRegs, 5);
+}
+
+/*
+ * \brief Function calibrates the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_calibration_cb(void)
+{
+}
+
+/*
+ * \brief Function sets RF_ON flag when radio is powered.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_on(void)
+{
+}
+
+/*
+ * \brief Function is a call back for RX end interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_rx_end(void)
+{
+    uint8_t rf_lqi = MCR20Drv_DirectAccessSPIRead(LQI_VALUE);
+    int8_t rf_rssi = 0;
+    uint8_t len = mStatusAndControlRegs[RX_FRM_LEN] - 2;
+    
+
+    /*Start receiver*/
+    rf_receive();
+
+    /*Check the length is valid*/
+    if(len > 1 && len < RF_BUFFER_SIZE)
+    {
+        rf_lqi  = rf_convert_LQI(rf_lqi);
+        rf_rssi = rf_convert_LQI_to_RSSI(rf_lqi);
+        /*gcararu: Scale LQI using received RSSI, to match the LQI reported by the ATMEL radio */
+        rf_lqi  = rf_scale_lqi(rf_rssi);
+
+        /*Read received packet*/
+        MCR20Drv_PB_SPIBurstRead(rf_buffer, len);
+        if (device_driver.phy_rx_cb) {
+            device_driver.phy_rx_cb(rf_buffer, len, rf_lqi, rf_rssi, rf_radio_driver_id);
+        }
+    }
+}
+
+/*
+ * \brief Function is called when MAC is shutting down the radio.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_shutdown(void)
+{
+    /*Call RF OFF*/
+    rf_off();
+}
+
+/*
+ * \brief Function is a call back for TX end interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_tx_end(void)
+{
+    uint8_t rx_frame_pending = mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_RX_FRM_PEND;
+
+    /*Start receiver*/
+    rf_receive();
+
+    if (!device_driver.phy_tx_done_cb) {
+        return;
+    }
+
+    /*Call PHY TX Done API*/
+    if( need_ack )
+    {
+        if( rx_frame_pending )
+        {
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1);
+        }
+        else
+        {
+            // arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
+            device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1);
+        }
+    }
+    else
+    {
+        device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1);
+    }
+}
+
+/*
+ * \brief Function is a call back for CCA ED done interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_handle_cca_ed_done(void)
+{
+    /*Check the result of CCA process*/
+    if( !(mStatusAndControlRegs[IRQSTS2] & cIRQSTS2_CCA) ) 
+    {
+        rf_start_tx();
+    }
+    else if (device_driver.phy_tx_done_cb)
+    {
+        /*Send CCA fail notification*/
+        device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
+    }
+}
+
+/*
+ * \brief Function sets the TX power variable.
+ *
+ * \param power TX power setting
+ *
+ * \return 0 Success
+ * \return -1 Fail
+ */
+static int8_t rf_tx_power_set(uint8_t power)
+{
+    /* gcapraru: Map MCR20A Tx power levels over ATMEL values */
+    static uint8_t pwrLevelMapping[16] = {25,25,25,24,24,24,23,23,22,22,21,20,19,18,17,14};
+
+    if( power > 15 )
+    {
+        return -1;
+    }
+
+    radio_tx_power = power;
+    MCR20Drv_DirectAccessSPIWrite(PA_PWR, pwrLevelMapping[power]);
+    return 0;
+}
+
+/*
+ * \brief Function returns the TX power variable.
+ *
+ * \param none
+ *
+ * \return radio_tx_power TX power variable
+ */
+static uint8_t rf_tx_power_get(void)
+{
+    return radio_tx_power;
+}
+
+/*
+ * \brief Function enables the usage of Antenna diversity.
+ *
+ * \param none
+ *
+ * \return 0 Success
+ */
+static int8_t rf_enable_antenna_diversity(void)
+{
+    uint8_t phyReg;
+
+    phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_AGC_CTRL);
+    phyReg |= cANT_AGC_CTRL_FAD_EN_Mask_c;
+    MCR20Drv_IndirectAccessSPIWrite(ANT_AGC_CTRL, phyReg);
+
+    phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_PAD_CTRL);
+    phyReg |= 0x02;
+    MCR20Drv_IndirectAccessSPIWrite(ANT_PAD_CTRL, phyReg);
+    
+    return 0;
+}
+
+/*
+ * \brief Function gives the control of RF states to MAC.
+ *
+ * \param new_state RF state
+ * \param rf_channel RF channel
+ *
+ * \return 0 Success
+ */
+static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
+{
+    int8_t ret_val = 0;
+    switch (new_state)
+    {
+        /*Reset PHY driver and set to idle*/
+        case PHY_INTERFACE_RESET:
+            break;
+        /*Disable PHY Interface driver*/
+        case PHY_INTERFACE_DOWN:
+            rf_shutdown();
+            break;
+        /*Enable PHY Interface driver*/
+        case PHY_INTERFACE_UP:
+            rf_channel_set(rf_channel);
+            rf_receive();
+            break;
+        /*Enable wireless interface ED scan mode*/
+        case PHY_INTERFACE_RX_ENERGY_STATE:
+            rf_abort();
+            rf_channel_set(rf_channel);
+            break;
+        case PHY_INTERFACE_SNIFFER_STATE:             /**< Enable Sniffer state */
+            rf_promiscuous(1);
+            rf_channel_set(rf_channel);
+            rf_receive();
+            break;
+    }
+    return ret_val;
+}
+
+/*
+ * \brief Function controls the ACK pending, channel setting and energy detection.
+ *
+ * \param extension_type Type of control
+ * \param data_ptr Data from NET library
+ *
+ * \return 0 Success
+ */
+static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
+{
+    switch (extension_type)
+    {
+        /*Control MAC pending bit for Indirect data transmission*/
+        case PHY_EXTENSION_CTRL_PENDING_BIT:
+        {
+            uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL);
+
+            if(*data_ptr)
+            {
+                reg |= cSRC_CTRL_ACK_FRM_PND;
+            }
+            else
+            {
+                reg &= ~cSRC_CTRL_ACK_FRM_PND;
+            }
+            
+            MCR20Drv_DirectAccessSPIWrite(SRC_CTRL, reg);
+            break;
+            
+        }
+        /*Return frame Auto Ack frame pending status*/
+        case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: {
+            uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL);
+            if (reg & cSRC_CTRL_ACK_FRM_PND) {
+                *data_ptr = 1;
+            } else {
+                *data_ptr  = 0;
+            }
+            break;
+        }
+        /*Set channel*/
+        case PHY_EXTENSION_SET_CHANNEL:
+            break;
+        /*Read energy on the channel*/
+        case PHY_EXTENSION_READ_CHANNEL_ENERGY:
+            *data_ptr = rf_get_channel_energy();
+            break;
+        /*Read status of the link*/
+        case PHY_EXTENSION_READ_LINK_STATUS:
+            break;
+        case PHY_EXTENSION_CONVERT_SIGNAL_INFO:
+            break;
+    }
+    return 0;
+}
+
+/*
+ * \brief Function sets the addresses to RF address filters.
+ *
+ * \param address_type Type of address
+ * \param address_ptr Pointer to given address
+ *
+ * \return 0 Success
+ */
+static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
+{
+    int8_t ret_val = 0;
+    switch (address_type)
+    {
+        /*Set 48-bit address*/
+        case PHY_MAC_48BIT:
+            break;
+            /*Set 64-bit address*/
+        case PHY_MAC_64BIT:
+            rf_set_address(address_ptr);
+            break;
+        /*Set 16-bit address*/
+        case PHY_MAC_16BIT:
+            rf_set_short_adr(address_ptr);
+            break;
+        /*Set PAN Id*/
+        case PHY_MAC_PANID:
+            rf_set_pan_id(address_ptr);
+            break;
+    }
+    return ret_val;
+}
+
+static void rf_mac64_read(uint8_t *address)
+{
+    /* Write one register at a time to be accessible from hibernate mode */
+    address[7] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_0);
+    address[6] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_8);
+    address[5] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_16);
+    address[4] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_24);
+    address[3] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_32);
+    address[2] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_40);
+    address[1] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_48);
+    address[0] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_56);
+
+}
+
+/*
+ * \brief Function initialises the ACK wait time and returns the used PHY mode.
+ *
+ * \param none
+ *
+ * \return tmp Used PHY mode
+ */
+static void rf_init_phy_mode(void)
+{
+}
+
+/*
+ * \brief Function is a RF interrupt vector. End of frame in RX and TX are handled here as well as CCA process interrupt.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void PHY_InterruptHandler(void)
+{
+    /* Disable and clear transceiver(IRQ_B) interrupt */
+    MCR20Drv_IRQ_Disable();
+    irq_thread.signal_set(1);
+}
+
+static void PHY_InterruptThread(void)
+{
+    for (;;) {
+        osEvent event = irq_thread.signal_wait(0);
+        if (event.status != osEventSignal) {
+            continue;
+        }
+        handle_interrupt();
+    }
+}
+
+static void handle_interrupt(void)
+{
+    uint8_t xcvseqCopy;
+
+    //MCR20Drv_IRQ_Clear();
+
+    /* Read transceiver interrupt status and control registers */
+    mStatusAndControlRegs[IRQSTS1] =
+        MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 7);
+
+    xcvseqCopy = mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ;
+    
+    /* Flter Fail IRQ */
+    if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_FILTERFAIL_IRQ) &&
+       !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_FILTERFAIL_MSK) )
+    {
+        if( xcvseqCopy == gRX_c )
+        {
+            /* Abort current SEQ */
+            mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+            MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+            /* Wait for Sequence Idle */
+            while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0);
+            /* Clear IRQ flags: */
+            MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ);
+            /* Restart Rx asap */
+            mStatusAndControlRegs[PHY_CTRL1] |= gRX_c;
+            MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+        }
+    }
+    
+    /* TMR3 IRQ: ACK wait time-out */
+    if( (mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3IRQ) &&
+       !(mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3MSK) )
+    {
+        /* Disable TMR3 IRQ */
+        mStatusAndControlRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK;
+
+        if( xcvseqCopy == gTR_c )
+        {
+            /* Set XCVR to Idle */
+            mPhySeqState = gIdle_c;
+            mStatusAndControlRegs[PHY_CTRL1] &=  ~( cPHY_CTRL1_XCVSEQ );
+            /* Mask interrupts */
+            mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK;
+            /* Sync settings with XCVR */
+            MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5);
+            
+            rf_ack_wait_timer_interrupt();
+            MCR20Drv_IRQ_Enable();
+            return;
+        }
+    }
+
+    /* Sequencer interrupt, the autosequence has completed */
+    if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_SEQIRQ) && 
+       !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_SEQMSK) )
+    {
+        /* Set XCVR to Idle */
+        mPhySeqState = gIdle_c;
+        mStatusAndControlRegs[PHY_CTRL1] &=  ~( cPHY_CTRL1_XCVSEQ );
+        /* Mask interrupts */
+        mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK;
+        /* Sync settings with XCVR */
+        MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5);
+                                                               
+        /* PLL unlock, the autosequence has been aborted due to PLL unlock */
+        if( mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_PLL_UNLOCK_IRQ )
+        {
+            if(xcvseqCopy == gRX_c)
+            {
+                rf_receive();
+            }
+            MCR20Drv_IRQ_Enable();
+            return;
+        }
+
+        switch(xcvseqCopy)
+        {
+        case gTX_c:
+        case gTR_c:
+            rf_handle_tx_end();
+            break;
+
+        case gRX_c:
+            rf_handle_rx_end();
+            break;
+
+        case gCCA_c:
+            rf_handle_cca_ed_done();
+            break;
+
+        default:
+            break;
+        }
+        
+        MCR20Drv_IRQ_Enable();
+        return;
+    }
+    /* Other IRQ. Clear XCVR interrupt flags */
+    MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
+    MCR20Drv_IRQ_Enable();
+}
+
+/*
+ * \brief Function forces the XCVR to Idle state.
+ *
+ * \param none
+ *
+ * \return none
+ */
+static void rf_abort(void)
+{
+    /* Mask XCVR irq */
+    MCR20Drv_IRQ_Disable();
+
+    mPhySeqState = gIdle_c;
+
+    mStatusAndControlRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 5);
+    
+    /* Mask SEQ interrupt */
+    mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_SEQMSK;
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]);
+
+    if( (mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ) != gIdle_c )
+    {
+        /* Abort current SEQ */
+        mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+        MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+        
+        /* Wait for Sequence Idle (if not already) */
+        while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0);
+        //while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ));
+        mStatusAndControlRegs[IRQSTS1] |= cIRQSTS1_SEQIRQ;
+    }
+
+    /* Clear all PP IRQ bits to avoid unexpected interrupts and mask TMR3 interrupt.
+       Do not change TMR IRQ status. */
+    mStatusAndControlRegs[IRQSTS3] &= 0xF0;
+    mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ);
+    MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3);
+
+    /* Unmask XCVR irq */
+    MCR20Drv_IRQ_Enable();
+}
+
+/*
+ * \brief Function reads a time-stamp value from XCVR [symbols]
+ *
+ * \param pEndTime pointer to location where time-stamp will be stored
+ *
+ * \return none
+ */
+static void rf_get_timestamp(uint32_t *pRetClk)
+{
+    if(NULL == pRetClk)
+    {
+        return;
+    }
+
+    platform_enter_critical();
+
+    *pRetClk = 0;
+    MCR20Drv_DirectAccessSPIMultiByteRead(EVENT_TMR_LSB, (uint8_t *) pRetClk, 3);
+
+    platform_exit_critical();
+}
+
+/*
+ * \brief Function set a time-out to an XCVR sequence.
+ *
+ * \param pEndTime pointer to the sequence time-out value [symbols]
+ *
+ * \return none
+ */
+static void rf_set_timeout(uint32_t *pEndTime)
+{
+    uint8_t phyReg;
+    
+    if(NULL == pEndTime)
+    {
+        return;
+    }
+    
+    platform_enter_critical();
+    
+    phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3);
+    phyReg &= 0xF0;                    /* do not change IRQ status */
+    phyReg |= (cIRQSTS3_TMR3MSK);      /* mask TMR3 interrupt */
+    MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg);
+    
+    MCR20Drv_DirectAccessSPIMultiByteWrite(T3CMP_LSB, (uint8_t *) pEndTime, 3);
+    
+    phyReg &= ~(cIRQSTS3_TMR3MSK);      /* unmask TMR3 interrupt */
+    phyReg |= (cIRQSTS3_TMR3IRQ);       /* aknowledge TMR3 IRQ */
+    MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg);
+    
+    platform_exit_critical();
+}
+
+/*
+ * \brief Function reads a random number from RF.
+ *
+ * \param none 
+ *
+ * \return 8-bit random number
+ */
+static uint8_t rf_if_read_rnd(void)
+{
+    uint8_t phyReg;
+
+    MCR20Drv_IRQ_Disable();
+    /* Check if XCVR is idle */
+    phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1);
+
+    if( (phyReg & cPHY_CTRL1_XCVSEQ) == gIdle_c )
+    {
+        /* Program a new sequence */
+        MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, phyReg | gCCA_c);
+        /* Wait for sequence to finish */
+        while( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ) );
+        /* Clear interrupt flag */
+        MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ);
+    }
+
+    MCR20Drv_IRQ_Enable();
+
+    return MCR20Drv_IndirectAccessSPIRead(_RNG);
+}
+
+/*
+ * \brief Function converts LQI into RSSI.
+ *
+ * \param LQI 
+ *
+ * \return RSSI
+ */
+static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi)
+{
+    int32_t rssi = (50*lqi - 16820) / 163;
+    return (int8_t)rssi;
+}
+
+/*
+ * \brief Function scale the LQI value reported by RF into a 0-255 value.
+ *
+ * \param hwLqi - the LQI value reported by RF
+ *
+ * \return scaled LQI
+ */
+static uint8_t rf_convert_LQI(uint8_t hwLqi)
+{
+    uint32_t tmpLQI;
+
+    /* LQI Saturation Level */
+    if (hwLqi >= 230)
+    {
+        return 0xFF;
+    }
+    else if (hwLqi <= 9)
+    {
+        return 0;
+    }
+    else
+    {
+        /* Rescale the LQI values from min to saturation to the 0x00 - 0xFF range */
+        /* The LQI value mst be multiplied by ~1.1087 */
+        /* tmpLQI =  hwLqi * 7123 ~= hwLqi * 65536 * 0.1087 = hwLqi * 2^16 * 0.1087*/
+        tmpLQI = ((uint32_t)hwLqi * (uint32_t)7123 );
+        /* tmpLQI =  (tmpLQI / 2^16) + hwLqi */
+        tmpLQI = (uint32_t)(tmpLQI >> 16) + (uint32_t)hwLqi;
+
+        return (uint8_t)tmpLQI;
+    }
+}
+
+/*
+ * \brief Function enables/disables Rx promiscuous mode.
+ *
+ * \param state of XCVR promiscuous mode
+ *
+ * \return none
+ */
+static void rf_promiscuous(uint8_t state)
+{
+    uint8_t rxFrameFltReg, phyCtrl4Reg;
+
+    rxFrameFltReg = MCR20Drv_IndirectAccessSPIRead(RX_FRAME_FILTER);
+    phyCtrl4Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4);
+
+    if( state )
+    {
+        /* FRM_VER[1:0] = b00. 00: Any FrameVersion accepted (0,1,2 & 3) */
+        /* All frame types accepted*/
+        phyCtrl4Reg   |= cPHY_CTRL4_PROMISCUOUS;
+        rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER);
+        rxFrameFltReg |=  (cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT);
+    }
+    else
+    {
+        phyCtrl4Reg   &= ~cPHY_CTRL4_PROMISCUOUS;
+        /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets, reject all others */
+        /* Beacon, Data and MAC command frame types accepted */
+        rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER);
+        rxFrameFltReg |= (0x03 << cRX_FRAME_FLT_FRM_VER_Shift_c);
+        rxFrameFltReg &= ~(cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT);
+    }
+
+    MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, rxFrameFltReg);
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, phyCtrl4Reg);
+}
+
+/*
+ * \brief Function used to switch XCVR power state.
+ *
+ * \param state The XCVR power mode
+ *
+ * \return none
+ */
+static void rf_set_power_state(xcvrPwrMode_t newState)
+{
+    uint8_t pwrMode;
+    uint8_t xtalState;
+
+    if( mPwrState == newState )
+    {
+        return;
+    }
+
+    /* Read power settings from RF */
+    pwrMode = MCR20Drv_DirectAccessSPIRead(PWR_MODES);
+    xtalState = pwrMode & cPWR_MODES_XTALEN;
+    
+    switch( newState )
+    {
+    case gXcvrPwrIdle_c:
+        pwrMode &= ~(cPWR_MODES_AUTODOZE);
+        pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_PMC_MODE);
+        break;
+    case gXcvrPwrAutodoze_c:
+        pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
+        break;
+    case gXcvrPwrDoze_c:
+        pwrMode &= ~(cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
+        pwrMode |= cPWR_MODES_XTALEN;
+        break;
+    case gXcvrPwrHibernate_c:
+        pwrMode &= ~(cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE);
+        break;
+    default:
+        return;
+    }
+    
+    mPwrState = newState;
+    MCR20Drv_DirectAccessSPIWrite(PWR_MODES, pwrMode);
+    
+    if( !xtalState && (pwrMode & cPWR_MODES_XTALEN))
+    {
+        /* wait for crystal oscillator to complet its warmup */
+        while( ( MCR20Drv_DirectAccessSPIRead(PWR_MODES) & cPWR_MODES_XTAL_READY ) != cPWR_MODES_XTAL_READY);
+        /* wait for radio wakeup from hibernate interrupt */
+        while( ( MCR20Drv_DirectAccessSPIRead(IRQSTS2) & (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) ) != (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) );
+
+        MCR20Drv_DirectAccessSPIWrite(IRQSTS2, cIRQSTS2_WAKE_IRQ);
+    }
+}
+
+/*
+ * \brief Function reads the energy level on the preselected channel.
+ *
+ * \return energy level
+ */
+static uint8_t rf_get_channel_energy(void)
+{
+    uint8_t ccaMode;
+
+    MCR20Drv_IRQ_Disable();
+    /* RX can start only from Idle state */
+    if( mPhySeqState != gIdle_c )
+    {
+        MCR20Drv_IRQ_Enable();
+        return 0;
+    }
+
+    /* Set XCVR power state in run mode */
+    rf_set_power_state(gXcvrRunState_d);
+
+    /* Switch to ED mode */
+    ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE;
+    if( ccaMode != gCcaED_c )
+    {
+        mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c);
+        mStatusAndControlRegs[PHY_CTRL4] |= gCcaED_c << cPHY_CTRL4_CCATYPE_Shift_c;
+        MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]);
+    }
+    
+    /* Start ED sequence */
+    mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c;
+    MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ);
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+    /* Wait for sequence to finish */
+    while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ));
+    /* Set XCVR to Idle */
+    mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ);
+    MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]);
+    MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ);
+    
+    MCR20Drv_IRQ_Enable();
+    
+    return rf_convert_energy_level(MCR20Drv_DirectAccessSPIRead(CCA1_ED_FNL));
+}
+
+/*
+ * \brief Function converts the energy level from dBm to a 0-255 value.
+ *
+ * \param energyLevel in dBm
+ *
+ * \return energy level (0-255)
+ */
+static uint8_t rf_convert_energy_level(uint8_t energyLevel)
+{
+    if(energyLevel >= 90)
+    {
+        /* ED value is below minimum. Return 0x00. */
+        energyLevel = 0x00;
+    }
+    else if(energyLevel <= 26)
+    {
+        /* ED value is above maximum. Return 0xFF. */
+        energyLevel = 0xFF;
+    }
+    else
+    {
+        /* Energy level (-90 dBm to -26 dBm ) --> varies form 0 to 64 */
+        energyLevel = (90 - energyLevel);
+        /* Rescale the energy level values to the 0x00-0xff range (0 to 64 translates in 0 to 255) */
+        /* energyLevel * 3.9844 ~= 4 */
+        /* Multiply with 4=2^2 by shifting left.
+        The multiplication will not overflow beacause energyLevel has values between 0 and 63 */
+        energyLevel <<= 2;
+    }
+
+    return energyLevel;
+}
+
+static uint8_t rf_scale_lqi(int8_t rssi)
+{
+    uint8_t scaled_lqi;
+    /*Worst case sensitivity*/
+    const int8_t rf_sensitivity = -98;
+
+    /*rssi < RF sensitivity*/
+    if(rssi < rf_sensitivity)
+        scaled_lqi=0;
+    /*-91 dBm < rssi < -81 dBm (AT86RF233 XPro)*/
+    /*-90 dBm < rssi < -80 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 10))
+        scaled_lqi=31;
+    /*-81 dBm < rssi < -71 dBm (AT86RF233 XPro)*/
+    /*-80 dBm < rssi < -70 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 20))
+        scaled_lqi=207;
+    /*-71 dBm < rssi < -61 dBm (AT86RF233 XPro)*/
+    /*-70 dBm < rssi < -60 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 30))
+        scaled_lqi=255;
+    /*-61 dBm < rssi < -51 dBm (AT86RF233 XPro)*/
+    /*-60 dBm < rssi < -50 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 40))
+        scaled_lqi=255;
+    /*-51 dBm < rssi < -41 dBm (AT86RF233 XPro)*/
+    /*-50 dBm < rssi < -40 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 50))
+        scaled_lqi=255;
+    /*-41 dBm < rssi < -31 dBm (AT86RF233 XPro)*/
+    /*-40 dBm < rssi < -30 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 60))
+        scaled_lqi=255;
+    /*-31 dBm < rssi < -21 dBm (AT86RF233 XPro)*/
+    /*-30 dBm < rssi < -20 dBm (AT86RF212B XPro)*/
+    else if(rssi < (rf_sensitivity + 70))
+        scaled_lqi=255;
+    /*rssi > RF saturation*/
+    else if(rssi > (rf_sensitivity + 80))
+        scaled_lqi=111;
+    /*-21 dBm < rssi < -11 dBm (AT86RF233 XPro)*/
+    /*-20 dBm < rssi < -10 dBm (AT86RF212B XPro)*/
+    else
+        scaled_lqi=255;
+
+    return scaled_lqi;
+}
+
+
+/*****************************************************************************/
+/*              Layer porting to the Freescale driver                        */
+/*****************************************************************************/
+extern "C" void xcvr_spi_init(uint32_t instance)
+{
+    (void)instance;
+}
+
+extern "C" void RF_IRQ_Init(void) {
+    MBED_ASSERT(irq != NULL);
+    irq->mode(PullUp);
+    irq->fall(&PHY_InterruptHandler);
+}
+
+extern "C" void RF_IRQ_Enable(void) {
+    MBED_ASSERT(irq != NULL);
+    irq->enable_irq();
+}
+
+extern "C" void RF_IRQ_Disable(void) {
+    MBED_ASSERT(irq != NULL);
+    irq->disable_irq();
+}
+
+extern "C" uint8_t RF_isIRQ_Pending(void) {
+    MBED_ASSERT(rf != NULL);
+    return !irq_pin->read();
+}
+
+extern "C" void RF_RST_Set(int state) {
+    MBED_ASSERT(rst != NULL);
+    *rst = state;
+}
+
+extern "C" void gXcvrAssertCS_d(void)
+{
+    MBED_ASSERT(cs != NULL);
+    *cs = 0;
+}
+
+extern "C" void gXcvrDeassertCS_d(void)
+{
+    MBED_ASSERT(cs != NULL);
+    *cs = 1;
+}
+
+extern "C" void xcvr_spi_configure_speed(uint32_t instance, uint32_t freq)
+{
+    MBED_ASSERT(spi != NULL);
+    (void)instance;
+    spi->frequency(freq);
+}
+
+extern "C" void xcvr_spi_transfer(uint32_t instance,
+                         uint8_t * sendBuffer,
+                         uint8_t * receiveBuffer,
+                         size_t transferByteCount)
+{
+    MBED_ASSERT(spi != NULL);
+    (void)instance;
+    volatile uint8_t dummy;
+
+    if( !transferByteCount )
+        return;
+
+    if( !sendBuffer && !receiveBuffer )
+        return;
+
+    while( transferByteCount-- )
+    {
+        if( sendBuffer )
+        {
+            dummy = *sendBuffer;
+            sendBuffer++;
+        }
+        else
+        {
+            dummy = 0xFF;
+        }
+
+        dummy = spi->write(dummy);
+
+        if( receiveBuffer )
+        {
+            *receiveBuffer = dummy;
+            receiveBuffer++;
+        }
+    }
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+static void rf_if_lock(void)
+{
+    platform_enter_critical();
+}
+
+static void rf_if_unlock(void)
+{
+    platform_exit_critical();
+}
+
+NanostackRfPhyMcr20a::NanostackRfPhyMcr20a(PinName spi_mosi, PinName spi_miso,
+        PinName spi_sclk, PinName spi_cs,  PinName spi_rst, PinName spi_irq)
+    : _spi(spi_mosi, spi_miso, spi_sclk), _rf_cs(spi_cs), _rf_rst(spi_rst, 1),
+      _rf_irq(spi_irq), _rf_irq_pin(spi_irq)
+{
+    // Do nothing
+}
+
+NanostackRfPhyMcr20a::~NanostackRfPhyMcr20a()
+{
+    // Do nothing
+}
+
+int8_t NanostackRfPhyMcr20a::rf_register()
+{
+
+    rf_if_lock();
+
+    if (rf != NULL) {
+        rf_if_unlock();
+        error("Multiple registrations of NanostackRfPhyMcr20a not supported");
+        return -1;
+    }
+
+    irq_thread.start(mbed::callback(PHY_InterruptThread));
+
+    _pins_set();
+    int8_t radio_id = rf_device_register();
+    if (radio_id < 0) {
+        _pins_clear();
+        rf = NULL;
+    }
+
+    rf_if_unlock();
+    return radio_id;
+}
+
+void NanostackRfPhyMcr20a::rf_unregister()
+{
+    rf_if_lock();
+
+    if (rf != this) {
+        rf_if_unlock();
+        return;
+    }
+
+    rf_device_unregister();
+    rf = NULL;
+    _pins_clear();
+
+    rf_if_unlock();
+}
+
+void NanostackRfPhyMcr20a::get_mac_address(uint8_t *mac)
+{
+    rf_if_lock();
+
+    memcpy((void*)mac, (void*)MAC_address, sizeof(MAC_address));
+
+    rf_if_unlock();
+}
+
+void NanostackRfPhyMcr20a::set_mac_address(uint8_t *mac)
+{
+    rf_if_lock();
+
+    if (NULL != rf) {
+        error("NanostackRfPhyAtmel cannot change mac address when running");
+        rf_if_unlock();
+        return;
+    }
+    memcpy((void*)MAC_address, (void*)mac, sizeof(MAC_address));
+
+    rf_if_unlock();
+}
+
+void NanostackRfPhyMcr20a::_pins_set()
+{
+    spi = &_spi;
+    cs = &_rf_cs;
+    rst = &_rf_rst;
+    irq = &_rf_irq;
+    irq_pin = &_rf_irq_pin;
+}
+
+void NanostackRfPhyMcr20a::_pins_clear()
+{
+    spi = NULL;
+    cs = NULL;
+    rst = NULL;
+    irq = NULL;
+    irq_pin = NULL;
+}
diff -r 000000000000 -r 615f90842ce8 mcr20a-rf-driver/source/XcvrSpi.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcr20a-rf-driver/source/XcvrSpi.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,89 @@
+/*!
+* Copyright (c) 2015, Freescale Semiconductor, Inc.
+* All rights reserved.
+*
+* \file XcvrSpi.h
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* o Redistributions of source code must retain the above copyright notice, this list
+*   of conditions and the following disclaimer.
+*
+* o Redistributions in binary form must reproduce the above copyright notice, this
+*   list of conditions and the following disclaimer in the documentation and/or
+*   other materials provided with the distribution.
+*
+* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+*   contributors may be used to endorse or promote products derived from this
+*   software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (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 __XCVR_SPI_H__
+#define __XCVR_SPI_H__
+
+
+/*****************************************************************************
+ *                               INCLUDED HEADERS                            *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the headers that this module needs to include.    *
+ * Note that it is not a good practice to include header files into header   *
+ * files, so use this section only if there is no other better solution.     *
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+ 
+
+/*****************************************************************************
+ *                             PUBLIC MACROS                                 *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the access macros, registers mappings, bit access *
+ * macros, masks, flags etc ...
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+#define gXcvrSpiInstance_c              0
+
+/*****************************************************************************
+ *                            PUBLIC FUNCTIONS                               *
+ *---------------------------------------------------------------------------*
+ * Add to this section all the global functions prototype preceded (as a     *
+ * good practice) by the keyword 'extern'                                    *
+ *---------------------------------------------------------------------------*
+ *****************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+void RF_RST_Set(int state);
+void RF_CS_Set(int state);
+void RF_IRQ_Init(void);
+void RF_IRQ_Disable(void);
+void RF_IRQ_Enable(void);
+uint8_t RF_isIRQ_Pending(void);
+
+void gXcvrAssertCS_d(void);
+void gXcvrDeassertCS_d(void);
+
+void xcvr_spi_init(uint32_t instance);
+void xcvr_spi_configure_speed(uint32_t instance, uint32_t freq);
+void xcvr_spi_transfer(uint32_t instance,
+                         uint8_t * sendBuffer,
+                         uint8_t * receiveBuffer,
+                         uint32_t transferByteCount);
+                         
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+#endif /* __XCVR_SPI_H__ */
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/stm-spirit1-rf-driver/#09e4b9664de110d986ea4d8212748a53c26f447f
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/heads/master
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/ORIG_HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/ORIG_HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+09e4b9664de110d986ea4d8212748a53c26f447f
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/config
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/config	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/ARMmbed/stm-spirit1-rf-driver/
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/description
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/description	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/applypatch-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/applypatch-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/post-update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/post-update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/pre-applypatch.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/pre-applypatch.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/pre-commit.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/pre-commit.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/pre-rebase.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/pre-rebase.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/usr/bin/perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+<<\DOC_END
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
+
+DOC_END
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/prepare-commit-msg.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/prepare-commit-msg.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /usr/bin/perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/hooks/update.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/hooks/update.sample	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/index
Binary file stm-spirit1-rf-driver/.git/index has changed
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/info/exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/info/exclude	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,25 @@
+.hg
+.git
+.svn
+.CVS
+.cvs
+*.orig
+.build
+.export
+.msub
+.meta
+.ctags*
+*.uvproj
+*.uvopt
+*.project
+*.cproject
+*.launch
+*.ewp
+*.eww
+Makefile
+Debug
+*.htm
+*.settings
+mbed_settings.py
+*.py[cod]
+# subrepo ignores
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/logs/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/logs/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 09e4b9664de110d986ea4d8212748a53c26f447f www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209877 +0000	clone: from https://github.com/ARMmbed/stm-spirit1-rf-driver/
+09e4b9664de110d986ea4d8212748a53c26f447f 09e4b9664de110d986ea4d8212748a53c26f447f www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209878 +0000	checkout: moving from master to 09e4b9664de110d986ea4d8212748a53c26f447f
+09e4b9664de110d986ea4d8212748a53c26f447f 09e4b9664de110d986ea4d8212748a53c26f447f www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209879 +0000	checkout: moving from 09e4b9664de110d986ea4d8212748a53c26f447f to master
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/logs/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/logs/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 09e4b9664de110d986ea4d8212748a53c26f447f www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209877 +0000	clone: from https://github.com/ARMmbed/stm-spirit1-rf-driver/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/logs/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/logs/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+0000000000000000000000000000000000000000 09e4b9664de110d986ea4d8212748a53c26f447f www-data <www-data@developer-sjc-cyan-compiler.local.mbed.org> 1498209877 +0000	clone: from https://github.com/ARMmbed/stm-spirit1-rf-driver/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.idx
Binary file stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.idx has changed
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.pack
Binary file stm-spirit1-rf-driver/.git/objects/pack/pack-dc7fe8035150b4623ac4ac1a2bd72c1125708327.pack has changed
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/packed-refs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/packed-refs	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+09e4b9664de110d986ea4d8212748a53c26f447f refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/refs/heads/master
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/refs/heads/master	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+09e4b9664de110d986ea4d8212748a53c26f447f
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.git/refs/remotes/origin/HEAD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.git/refs/remotes/origin/HEAD	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+ref: refs/remotes/origin/master
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.gitignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.gitignore	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,6 @@
+BUILD
+.mbed
+projectfiles
+*.py*
+RCS
+atmel-rf-driver
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/.meta
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/.meta	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<root>
+  <node _type="integer" _key="update">1</node>
+</root>
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,12 @@
+# Prototype RF Driver for STM Sub-1 GHz RF Expansion Boards based on the SPSGRF-868 Module for STM32 Nucleo #
+
+Currently supported boards:
+ * [X-NUCLEO-IDS01A4](http://www.st.com/content/st_com/en/products/ecosystems/stm32-open-development-environment/stm32-nucleo-expansion-boards/stm32-ode-connect-hw/x-nucleo-ids01a4.html)
+
+**Note**, in order to use expansion board `X-NUCLEO-IDS01A4` in mbed you need to perform the following HW modifications on the board:
+ * **Un**mount resistor `R4`
+ * **Mount** resistor `R7`
+ 
+Furthermore, on some Nucleo development boards (e.g. the [NUCLEO_F429ZI](https://developer.mbed.org/platforms/ST-Nucleo-F429ZI/)), in order to be able to use Ethernet together with these Sub-1 GHz RF expansion boards, you need to compile this driver with macro `SPIRIT1_SPI_MOSI=PB_5` defined, while the development board typically requires some HW modification as e.g. described [here](https://github.com/ARMmbed/sal-nanostack-driver-stm32-eth)! 
+
+This driver can be used together with the 6LoWPAN stack (*a.k.a.* Nanostack).
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/mbed_lib.json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/mbed_lib.json	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,7 @@
+{
+    "name": "spirit1",
+    "config": {
+	"mac-address": "{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}"
+    },
+    "macros": ["USE_STM32F4XX_NUCLEO", "X_NUCLEO_IDS01A4", "SPIRIT_USE_FULL_ASSERT"]
+}
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/NanostackRfPhySpirit1.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/NanostackRfPhySpirit1.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,810 @@
+#if MBED_CONF_RTOS_PRESENT
+
+#include "NanostackRfPhySpirit1.h"
+#include "SimpleSpirit1.h"
+#include "nanostack/platform/arm_hal_phy.h"
+#include "platform/arm_hal_interrupt.h"
+
+#include "mbed_trace.h"
+#define TRACE_GROUP  "SPIRIT"
+
+/* Define beyond macro if you want to perform heavy debug tracing (includes tracing in IRQ context) */
+// #define HEAVY_TRACING
+
+static phy_device_driver_s device_driver;
+static int8_t rf_radio_driver_id = -1;
+
+const phy_rf_channel_configuration_s phy_subghz = {868000000, 1000000, 250000, 11, M_GFSK};
+
+static phy_device_channel_page_s phy_channel_pages[] = {
+    {CHANNEL_PAGE_2, &phy_subghz},
+    {CHANNEL_PAGE_0, NULL}
+};
+
+static uint8_t tx_sequence = 0xff;
+static uint8_t mac_tx_handle = 0;
+
+static SimpleSpirit1 *rf_device = NULL;
+static uint8_t rf_rx_buf[MAX_PACKET_LEN];
+
+static uint16_t stored_short_adr;
+static uint16_t stored_pan_id;
+static uint8_t stored_mac_address[8] = MBED_CONF_SPIRIT1_MAC_ADDRESS;
+
+#define RF_SIG_ACK_NEEDED (1<<0)
+#define RF_SIG_CB_TX_DONE (1<<1)
+#define RF_SIG_CB_RX_RCVD (1<<2)
+static Thread rf_ack_sender(osPriorityRealtime);
+static volatile uint8_t rf_rx_sequence;
+static volatile bool rf_ack_sent = false;
+
+/* MAC frame helper macros */
+#define MAC_FCF_FRAME_TYPE_MASK         0x0007
+#define MAC_FCF_FRAME_TYPE_SHIFT        0
+#define MAC_FCF_SECURITY_BIT_MASK       0x0008
+#define MAC_FCF_SECURITY_BIT_SHIFT      3
+#define MAC_FCF_PENDING_BIT_MASK        0x0010
+#define MAC_FCF_PENDING_BIT_SHIFT       4
+#define MAC_FCF_ACK_REQ_BIT_MASK        0x0020
+#define MAC_FCF_ACK_REQ_BIT_SHIFT       5
+#define MAC_FCF_INTRA_PANID_MASK        0x0040
+#define MAC_FCF_INTRA_PANID_SHIFT       6
+#define MAC_FCF_DST_ADDR_MASK           0x0c00
+#define MAC_FCF_DST_ADDR_SHIFT          10
+#define MAC_FCF_VERSION_MASK            0x3000
+#define MAC_FCF_VERSION_SHIFT           12
+#define MAC_FCF_SRC_ADDR_MASK           0xc000
+#define MAC_FCF_SRC_ADDR_SHIFT          14
+
+/* MAC supported frame types */
+#define FC_BEACON_FRAME         0x00
+#define FC_DATA_FRAME           0x01
+#define FC_ACK_FRAME            0x02
+#define FC_CMD_FRAME            0x03
+
+static void rf_if_lock(void)
+{
+    platform_enter_critical();
+}
+
+static void rf_if_unlock(void)
+{
+    platform_exit_critical();
+}
+
+static inline uint16_t rf_read_16_bit(uint8_t *data_ptr) { // little-endian
+    uint16_t ret;
+
+    ret = ((uint16_t)data_ptr[0]) + (((uint16_t)data_ptr[1]) << 8);
+    return ret;
+}
+
+static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
+{
+#ifndef NDEBUG
+    debug_if(!(data_length >= 3), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+    /* Give 'rf_ack_sender' a better chance to run */
+    Thread::yield();
+
+    /* Get Lock */
+    rf_if_lock();
+
+    /*Check if transmitter is busy*/
+    if(rf_device->is_receiving()) { /* betzw - WAS: (rf_device->channel_clear() != 0)), do NOT use this but rather study and enable automatic CCA */
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	
+	/* Release Lock */
+	rf_if_unlock();
+
+	/*Return busy*/
+	return -1;
+    } else {
+#ifdef HEAVY_TRACING
+	uint16_t fcf = rf_read_16_bit(data_ptr);
+	uint16_t need_ack;
+
+	/*Check if transmitted data needs to be acked*/
+	if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
+	    need_ack = 1;
+	else
+	    need_ack = 0;
+#endif
+
+	/*Store the sequence number for ACK handling*/
+	tx_sequence = *(data_ptr + 2);
+
+	/*Store TX handle*/
+	mac_tx_handle = tx_handle;
+
+#ifdef HEAVY_TRACING
+	tr_info("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, need_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
+		data_length, tx_handle, tx_sequence, need_ack,
+		data_ptr[3], data_ptr[4], data_ptr[5], data_ptr[6],
+		data_ptr[7], data_ptr[8], data_ptr[9], data_ptr[10]);
+#endif
+
+	/*Send the packet*/
+	rf_device->send(data_ptr, data_length);
+
+	/* Release Lock */
+	rf_if_unlock();
+    }
+
+    /*Return success*/
+    return 0;
+}
+
+static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
+{
+    int8_t ret_val = 0;
+    switch (new_state)
+    {
+	/*Reset PHY driver and set to idle*/
+    case PHY_INTERFACE_RESET:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	rf_device->reset_board();
+	break;
+	/*Disable PHY Interface driver*/
+    case PHY_INTERFACE_DOWN:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	ret_val = rf_device->off();
+	if(ret_val != 0) ret_val = -1;
+	break;
+	/*Enable PHY Interface driver*/
+    case PHY_INTERFACE_UP:
+	ret_val = rf_device->on();
+	if(ret_val != 0) {
+	    tr_debug("%s (%d)", __func__, __LINE__);
+	    ret_val = -1;
+	    break;
+	}
+	tr_debug("%s (%d) - channel: %d", __func__, __LINE__, (int)rf_channel);
+	rf_device->set_channel(rf_channel);
+	break;
+	/*Enable wireless interface ED scan mode*/
+    case PHY_INTERFACE_RX_ENERGY_STATE:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	break;
+	/*Enable Sniffer state*/
+    case PHY_INTERFACE_SNIFFER_STATE:
+	// TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel);
+	tr_debug("%s (%d)", __func__, __LINE__);
+	ret_val = -1;
+	break;
+    default:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	break;
+    }
+    return ret_val;
+}
+
+static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
+{
+    switch (extension_type)
+    {
+	/*Control MAC pending bit for Indirect data transmission*/
+    case PHY_EXTENSION_CTRL_PENDING_BIT:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	break;
+
+	/*Return frame pending status*/
+    case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	*data_ptr = 0;
+	break;
+
+	/*Set channel, used for setting channel for energy scan*/
+    case PHY_EXTENSION_SET_CHANNEL:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	break;
+
+	/*Read energy on the channel*/
+    case PHY_EXTENSION_READ_CHANNEL_ENERGY:
+	// TODO: *data_ptr = rf_get_channel_energy();
+	tr_debug("%s (%d)", __func__, __LINE__);
+	*data_ptr = (int8_t)rf_device->get_last_rssi_dbm();
+	break;
+
+	/*Read status of the link*/
+    case PHY_EXTENSION_READ_LINK_STATUS:
+	// TODO: *data_ptr = rf_get_link_status();
+	tr_debug("%s (%d)", __func__, __LINE__);
+	*data_ptr = rf_device->get_last_sqi(); // use SQI as link quality
+	break;
+
+    default:
+	tr_debug("%s (%d)", __func__, __LINE__);
+	break;
+    }
+    return 0;
+}
+
+static inline void rf_set_mac_address(uint8_t *ptr) {
+    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
+	     __func__, __LINE__,
+	     ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
+    for(int i = 0; i < 8; i++) {
+	stored_mac_address[i] = ptr[i];
+    }
+}
+
+static inline void rf_get_mac_address(uint8_t *ptr) {
+    for(int i = 0; i < 8; i++) {
+	ptr[i] = stored_mac_address[i];
+    }
+    tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
+	     __func__, __LINE__,
+	     ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
+}
+
+static inline void rf_set_short_adr(uint8_t *ptr) {
+    stored_short_adr = (ptr[0] << 8) + ptr[1]; // big-endian
+    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
+	     __func__, __LINE__,
+	     ptr[0], ptr[1], stored_short_adr);
+}
+
+static inline void rf_set_pan_id(uint8_t *ptr) {
+    stored_pan_id = (ptr[0] << 8) + ptr[1]; // big-endian
+    tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
+	     __func__, __LINE__,
+	     ptr[0], ptr[1], stored_pan_id);
+}
+
+static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
+{
+    switch (address_type)
+    {
+	/*Set 48-bit address*/
+    case PHY_MAC_48BIT:
+	/* Not used in this example */
+	// betzw - WAS: rf_set_mac_48bit(address_ptr);
+	break;
+	/*Set 64-bit address*/
+    case PHY_MAC_64BIT:
+	rf_set_mac_address(address_ptr);
+	break;
+	/*Set 16-bit address*/
+    case PHY_MAC_16BIT:
+	rf_set_short_adr(address_ptr);
+	break;
+	/*Set PAN Id*/
+    case PHY_MAC_PANID:
+	rf_set_pan_id(address_ptr);
+	break;
+    }
+
+    return 0;
+}
+
+/* Note: we are in IRQ context */
+static inline void rf_send_signal(int32_t signal) {
+#ifdef HEAVY_TRACING
+	tr_info("%s (%d): %d", __func__, __LINE__, signal);
+#endif
+    rf_ack_sender.signal_set(signal);
+}
+
+static phy_link_tx_status_e phy_status;
+/* Note: we are in IRQ context */
+static void rf_handle_ack(uint8_t seq_number)
+{
+    /*Received ACK sequence must be equal with transmitted packet sequence*/
+    if(tx_sequence == seq_number)
+    {
+#ifdef HEAVY_TRACING
+	tr_info("%s (%d)", __func__, __LINE__);
+#endif
+
+	/*Call PHY TX Done API*/
+	if(device_driver.phy_tx_done_cb){
+	    phy_status = PHY_LINK_TX_DONE;
+	    rf_send_signal(RF_SIG_CB_TX_DONE);
+	}
+    } else {
+#ifdef HEAVY_TRACING
+	tr_info("%s (%d)", __func__, __LINE__);
+#endif
+    }
+}
+
+/* Note: we are in IRQ context */
+static inline bool rf_check_mac_address(uint8_t *dest) {
+    for(int i = 0; i < 8; i++) {
+	if(dest[i] != stored_mac_address[7-i]) return false;
+    }
+    return true;
+}
+
+/* Note: we are in IRQ context */
+/* Returns true if packet should be accepted */
+static bool rf_check_destination(int len, uint8_t *ack_requested) {
+    uint8_t frame_type;
+    uint16_t dst_pan_id;
+    uint16_t dst_short_adr;
+    uint8_t dst_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
+    uint8_t src_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
+    uint8_t min_size = 3; // FCF & SeqNr
+    bool ret = false;
+#if defined(HEAVY_TRACING)
+    bool panid_compr = false;
+#endif
+
+    if(len < 3) {
+	tr_debug("%s (%d)", __func__, __LINE__);
+	return false;
+    }
+
+    uint16_t fcf = rf_read_16_bit(rf_rx_buf);
+    frame_type = ((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT);
+    (*ack_requested) = ((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT);
+    dst_addr_mode = ((fcf & MAC_FCF_DST_ADDR_MASK) >> MAC_FCF_DST_ADDR_SHIFT);
+    src_addr_mode = ((fcf & MAC_FCF_SRC_ADDR_MASK) >> MAC_FCF_SRC_ADDR_SHIFT);
+#if defined(HEAVY_TRACING)
+    panid_compr = ((fcf & MAC_FCF_INTRA_PANID_MASK) >> MAC_FCF_INTRA_PANID_SHIFT);
+#endif
+
+#ifdef HEAVY_TRACING
+    tr_info("%s (%d): len=%d, ftype=%x, snr=%x, ack=%d, dst=%x, src=%x, intra=%d", __func__, __LINE__, len, frame_type,
+	    rf_rx_buf[2], (*ack_requested), dst_addr_mode, src_addr_mode, panid_compr);
+#endif
+
+    if(frame_type == FC_ACK_FRAME) { // betzw: we support up to two different forms of ACK frames!
+	if((len == 3) && (dst_addr_mode == 0x0) && (src_addr_mode == 0x0)) {
+	    ret = true;
+	}
+
+#ifdef HEAVY_TRACING
+	tr_info("%s (%d): ret=%d", __func__, __LINE__, ret);
+#endif
+	(*ack_requested) = 0;  // Never acknowledge ACK frames
+	return ret;
+    }
+
+    switch(dst_addr_mode) {
+    case 0x00:
+	ret = true; // no check possible;
+	break;
+    case 0x02:
+	min_size += 4; // pan id + short dest adr
+
+	if(len < 5) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    return false;
+	}
+
+	dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
+	if(dst_pan_id == 0xFFFF) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    ret = true;
+	    break;
+	}
+
+	if(dst_pan_id == stored_pan_id) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    ret = true;
+	    break;
+	} else {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_pan_id, stored_pan_id);
+#endif
+	}
+
+	if(len < 7) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    return false;
+	}
+
+	dst_short_adr = rf_read_16_bit(&rf_rx_buf[5]);
+	if(dst_short_adr == stored_short_adr) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    ret = true;
+	    break;
+	} else {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_short_adr, stored_short_adr);
+#endif
+	}
+	break;
+    case 0x03:
+	min_size += 10; // pan id + dest mac addr
+
+	if(len < 5) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    return false;
+	}
+
+	dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
+	if(dst_pan_id == 0xFFFF) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    ret = true;
+	    break;
+	}
+
+	if(dst_pan_id == stored_pan_id) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    ret = true;
+	    break;
+	}
+
+	if(len < 13) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    return false;
+	}
+
+	ret = rf_check_mac_address(&rf_rx_buf[5]);
+	break;
+    default:
+	/* not supported */
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	return false;
+    }
+
+    if(ret && (*ack_requested)) {
+	rf_rx_sequence = rf_rx_buf[2];
+    }
+
+#ifdef HEAVY_TRACING
+    tr_info("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
+#endif
+    return ret;
+}
+
+static uint16_t rf_buffer_len = 0;
+static uint8_t rf_sqi;
+static int8_t rf_rssi;
+/* Note: we are in IRQ context */
+static inline void rf_handle_rx_end(void)
+{
+    uint8_t ack_requested = 0;
+
+    /* Get received data */
+    rf_buffer_len = rf_device->read(rf_rx_buf, MAX_PACKET_LEN);
+    if(!rf_buffer_len)
+	return;
+
+#ifdef HEAVY_TRACING
+    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+    /* Check if packet should be accepted */
+    if(!rf_check_destination(rf_buffer_len, &ack_requested)) {
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	return;
+    }
+
+    /* If waiting for ACK, check here if the packet is an ACK to a message previously sent */
+    uint16_t fcf = rf_read_16_bit(rf_rx_buf);
+    if(((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT) == FC_ACK_FRAME) {
+	/*Send sequence number in ACK handler*/
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
+#endif
+	rf_handle_ack(rf_rx_buf[2]);
+	return;
+    }
+
+    /* Kick off ACK sending */
+    if(ack_requested) {
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
+#endif
+	rf_send_signal(RF_SIG_ACK_NEEDED);
+    }
+
+    /* Get link information */
+    rf_rssi = (int8_t)rf_device->get_last_rssi_dbm();
+    rf_sqi = (uint8_t)rf_device->get_last_sqi(); // use SQI as link quality
+
+    /* Note: Checksum of the packet must be checked and removed before entering here */
+    /* TODO - betzw: what to do? */
+
+#ifdef HEAVY_TRACING
+    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+    /* Send received data and link information to the network stack */
+    if( device_driver.phy_rx_cb ){
+	rf_send_signal(RF_SIG_CB_RX_RCVD);
+    }
+}
+
+/* Note: we are in IRQ context */
+static inline void rf_handle_tx_end(void)
+{
+    /* Check if this is an ACK sending which is still pending */
+    if(rf_ack_sent) {
+	rf_ack_sent = false;
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	return; // no need to inform stack
+    }
+
+    /*Call PHY TX Done API*/
+    if(device_driver.phy_tx_done_cb){
+	phy_status = PHY_LINK_TX_SUCCESS;
+	rf_send_signal(RF_SIG_CB_TX_DONE);
+    }
+}
+
+/* Note: we are in IRQ context */
+static inline void rf_handle_tx_err(void) {
+    /*Call PHY TX Done API*/
+    if(device_driver.phy_tx_done_cb){
+	phy_status = PHY_LINK_TX_FAIL;
+	rf_send_signal(RF_SIG_CB_TX_DONE);
+    }
+}
+
+/* Note: we are in IRQ context */
+static void rf_callback_func(int event) {
+    switch(event) {
+    case SimpleSpirit1::RX_DONE:
+	rf_handle_rx_end();
+	break;
+    case SimpleSpirit1::TX_DONE:
+	rf_handle_tx_end();
+	break;
+    case SimpleSpirit1::TX_ERR:
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d): TX_ERR!!!", __func__, __LINE__);
+#endif
+	rf_handle_tx_err();
+	break;
+    }
+}
+
+static void rf_ack_loop(void) {
+    static uint16_t buffer[2] = {
+	(FC_ACK_FRAME << MAC_FCF_FRAME_TYPE_SHIFT),
+	0x0
+    };
+
+    tr_debug("%s (%d)", __func__, __LINE__);
+
+    do {
+	/* Wait for signal */
+	osEvent event = rf_ack_sender.signal_wait(0);
+
+	if(event.status != osEventSignal) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	    continue;
+	}
+
+	int32_t signals = event.value.signals;
+
+#ifdef HEAVY_TRACING
+    	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+    	/* Get Lock */
+	rf_if_lock();
+
+	if(signals & RF_SIG_ACK_NEEDED) {
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+
+	    /* Prepare payload */
+	    uint8_t *ptr = (uint8_t*)&buffer[1];
+	    ptr[0] = rf_rx_sequence;   // Sequence number
+
+	    /* Wait for device not receiving */
+	    while(rf_device->is_receiving()) {
+#ifdef HEAVY_TRACING
+		tr_info("%s (%d)", __func__, __LINE__);
+#endif
+		wait_us(10);
+	    }
+
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
+#endif
+
+	    /* Set information that we have sent an ACK */
+	    rf_ack_sent = true;
+
+	    /*Send the packet*/
+	    rf_device->send((uint8_t*)buffer, 3);
+
+#ifdef HEAVY_TRACING
+	    tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
+#endif
+	}
+
+	if(signals & RF_SIG_CB_TX_DONE) {
+	    device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 0, 0);
+#ifdef HEAVY_TRACING
+    	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	}
+
+	if(signals & RF_SIG_CB_RX_RCVD) {
+	    device_driver.phy_rx_cb(rf_rx_buf, rf_buffer_len, rf_sqi, rf_rssi, rf_radio_driver_id);
+#ifdef HEAVY_TRACING
+    	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+	}
+
+	/* Release Lock */
+	rf_if_unlock();
+
+#ifdef HEAVY_TRACING
+	tr_debug("%s (%d)", __func__, __LINE__);
+#endif
+    } while(true);
+}
+
+void NanostackRfPhySpirit1::rf_init(void) {
+#ifndef NDEBUG
+    osStatus ret;
+#endif
+
+    if(rf_device == NULL) {
+	rf_device = &SimpleSpirit1::CreateInstance(_spi_mosi, _spi_miso, _spi_sclk, _dev_irq, _dev_cs, _dev_sdn, _brd_led);
+	rf_device->attach_irq_callback(rf_callback_func);
+
+#ifndef NDEBUG
+	ret =
+#endif
+	    rf_ack_sender.start(rf_ack_loop);
+
+#ifndef NDEBUG
+	debug_if(!(ret == osOK), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+    }
+}
+
+NanostackRfPhySpirit1::NanostackRfPhySpirit1(PinName spi_mosi, PinName spi_miso, PinName spi_sclk,
+					     PinName dev_irq,  PinName dev_cs, PinName dev_sdn, PinName brd_led) :
+    _spi_mosi(spi_mosi),
+    _spi_miso(spi_miso),
+    _spi_sclk(spi_sclk),
+    _dev_irq(dev_irq),
+    _dev_cs(dev_cs),
+    _dev_sdn(dev_sdn),
+    _brd_led(brd_led)
+{
+    /* Nothing to do */
+    tr_debug("%s (%d)", __func__, __LINE__);
+}
+
+NanostackRfPhySpirit1::~NanostackRfPhySpirit1()
+{
+    /* Nothing to do */
+    tr_debug("%s (%d)", __func__, __LINE__);
+}
+
+int8_t NanostackRfPhySpirit1::rf_register()
+{
+    tr_debug("%s (%d)", __func__, __LINE__);
+
+    /* Get Lock */
+    rf_if_lock();
+
+    /* Do some initialization */
+    rf_init();
+
+    /* Set pointer to MAC address */
+    device_driver.PHY_MAC = stored_mac_address;
+
+    /* Set driver Name */
+    device_driver.driver_description = (char*)"Spirit1 Sub-GHz RF";
+
+    /*Type of RF PHY is SubGHz*/
+    device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
+
+    /*Maximum size of payload*/
+    device_driver.phy_MTU = MAX_PACKET_LEN;
+
+    /*No header in PHY*/
+    device_driver.phy_header_length = 0;
+
+    /*No tail in PHY*/
+    device_driver.phy_tail_length = 0;
+
+    /*Set up driver functions*/
+    device_driver.address_write = &rf_address_write;
+    device_driver.extension = &rf_extension;
+    device_driver.state_control = &rf_interface_state_control;
+    device_driver.tx = &rf_trigger_send;
+
+    /*Set supported channel pages*/
+    device_driver.phy_channel_pages = phy_channel_pages;
+
+    //Nullify rx/tx callbacks
+    device_driver.phy_rx_cb = NULL;
+    device_driver.phy_tx_done_cb = NULL;
+    device_driver.arm_net_virtual_rx_cb = NULL;
+    device_driver.arm_net_virtual_tx_cb = NULL;
+
+    /*Register device driver*/
+    rf_radio_driver_id = arm_net_phy_register(&device_driver);
+
+    /* Release Lock */
+    rf_if_unlock();
+
+    tr_debug("%s (%d)", __func__, __LINE__);
+    return rf_radio_driver_id;
+}
+
+void NanostackRfPhySpirit1::rf_unregister()
+{
+    tr_debug("%s (%d)", __func__, __LINE__);
+
+    /* Get Lock */
+    rf_if_lock();
+
+    if (rf_radio_driver_id >= 0) {
+        arm_net_phy_unregister(rf_radio_driver_id);
+        rf_radio_driver_id = -1;
+    }
+
+    /* Release Lock */
+    rf_if_unlock();
+}
+
+void NanostackRfPhySpirit1::get_mac_address(uint8_t *mac)
+{
+    tr_debug("%s (%d)", __func__, __LINE__);
+
+    /* Get Lock */
+    rf_if_lock();
+
+    if(rf_radio_driver_id >= 0) {
+	rf_get_mac_address(mac);
+    } else {
+        error("NanostackRfPhySpirit1 must be registered to read mac address");
+    }
+
+    /* Release Lock */
+    rf_if_unlock();
+}
+
+void NanostackRfPhySpirit1::set_mac_address(uint8_t *mac)
+{
+    tr_debug("%s (%d)", __func__, __LINE__);
+
+    /* Get Lock */
+    rf_if_lock();
+
+    if(rf_radio_driver_id < 0) {
+	rf_set_mac_address(mac);
+    } else {
+        error("NanostackRfPhySpirit1 cannot change mac address when running");
+    }
+
+    /* Release Lock */
+    rf_if_unlock();
+}
+
+#endif /* MBED_CONF_RTOS_PRESENT */
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/SimpleSpirit1.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/SimpleSpirit1.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,616 @@
+/*** Mbed Includes ***/
+#include "SimpleSpirit1.h"
+#include "radio_spi.h"
+
+#define SPIRIT_GPIO_IRQ			(SPIRIT_GPIO_3)
+
+static uint16_t last_state;
+#define SPIRIT1_STATUS()		((last_state = (uint16_t)refresh_state()) & SPIRIT1_STATE_STATEBITS)
+
+#define XO_ON                   (0x1)
+
+#define BUSYWAIT_UNTIL(cond, millisecs)                                        					\
+		do {                                                                 					 		\
+			uint32_t start = us_ticker_read();                         							\
+			while (!(cond) && ((us_ticker_read() - start) < ((uint32_t)millisecs)*1000U));	\
+		} while(0)
+
+#define st_lib_spirit_irqs		SpiritIrqs
+
+#define STATE_TIMEOUT           (100)
+
+// betzw: switching force & back from standby is on some devices quite unstable
+#define USE_STANDBY_STATE
+
+/*** Class Implementation ***/
+/** Static Class Variables **/
+SimpleSpirit1 *SimpleSpirit1::_singleton = NULL;
+
+/** Constructor **/
+SimpleSpirit1::SimpleSpirit1(PinName mosi, PinName miso, PinName sclk,
+		PinName irq, PinName cs, PinName sdn,
+		PinName led) :
+    		_spi(mosi, miso, sclk),
+			_irq(irq),
+			_chip_select(cs),
+			_shut_down(sdn),
+			_led(led),
+			_current_irq_callback(),
+			_rx_receiving_timeout()
+{
+}
+
+/** Init Function **/
+void SimpleSpirit1::init() {
+	/* reset irq disable counter and irq callback & disable irq */
+	_nr_of_irq_disables = 0;
+	disable_spirit_irq();
+
+	/* unselect chip */
+	chip_unselect();
+
+	/* configure spi */
+	_spi.format(8, 0); /* 8-bit, mode = 0, [order = SPI_MSB] only available in mbed3 */
+	_spi.frequency(10000000); // 10MHz (i.e. max speed allowed for Spirit1)
+
+	/* install irq handler */
+	_irq.mode(PullUp);
+	_irq.fall(Callback<void()>(this, &SimpleSpirit1::IrqHandler));
+
+	/* init cube vars */
+	spirit_on = OFF;
+	last_rssi = 0 ; //MGR
+	last_sqi = 0 ;  //MGR
+
+	/* set frequencies */
+	radio_set_xtal_freq(XTAL_FREQUENCY);
+	mgmt_set_freq_base((uint32_t)BASE_FREQUENCY);
+
+	/* restart board */
+	enter_shutdown();
+	exit_shutdown();
+
+	/* soft core reset */
+	cmd_strobe(SPIRIT1_STROBE_SRES);
+
+	/* Configures the SPIRIT1 radio part */
+	SRadioInit x_radio_init = {
+			XTAL_OFFSET_PPM,
+			(uint32_t)BASE_FREQUENCY,
+			(uint32_t)CHANNEL_SPACE,
+			CHANNEL_NUMBER,
+			MODULATION_SELECT,
+			DATARATE,
+			(uint32_t)FREQ_DEVIATION,
+			(uint32_t)BANDWIDTH
+	};
+	radio_init(&x_radio_init);
+	radio_set_pa_level_dbm(0,POWER_DBM);
+	radio_set_pa_level_max_index(0);
+
+	/* Configures the SPIRIT1 packet handler part*/
+	PktBasicInit x_basic_init = {
+			PREAMBLE_LENGTH,
+			SYNC_LENGTH,
+			SYNC_WORD,
+			LENGTH_TYPE,
+			LENGTH_WIDTH,
+			CRC_MODE,
+			CONTROL_LENGTH,
+			EN_ADDRESS,
+			EN_FEC,
+			EN_WHITENING
+	};
+	pkt_basic_init(&x_basic_init);
+
+	/* Enable the following interrupt sources, routed to GPIO */
+	irq_de_init(NULL);
+	irq_clear_status();
+	irq_set_status(TX_DATA_SENT, S_ENABLE);
+	irq_set_status(RX_DATA_READY,S_ENABLE);
+	irq_set_status(RX_DATA_DISC, S_ENABLE);
+	irq_set_status(VALID_SYNC, S_ENABLE);
+	irq_set_status(TX_FIFO_ERROR, S_ENABLE);
+	irq_set_status(RX_FIFO_ERROR, S_ENABLE);
+#ifndef RX_FIFO_THR_WA
+	irq_set_status(TX_FIFO_ALMOST_EMPTY, S_ENABLE);
+	irq_set_status(RX_FIFO_ALMOST_FULL, S_ENABLE);
+#endif // !RX_FIFO_THR_WA
+
+	/* Configure Spirit1 */
+	radio_persistent_rx(S_ENABLE);
+	qi_set_sqi_threshold(SQI_TH_0);
+	qi_sqi_check(S_ENABLE);
+	qi_set_rssi_threshold_dbm(CCA_THRESHOLD);
+	timer_set_rx_timeout_stop_condition(SQI_ABOVE_THRESHOLD);
+	timer_set_infinite_rx_timeout();
+	radio_afc_freeze_on_sync(S_ENABLE);
+	calibration_rco(S_ENABLE);
+
+	spirit_on = OFF;
+	CLEAR_TXBUF();
+	CLEAR_RXBUF();
+	_spirit_tx_started = false;
+	_is_receiving = false;
+
+	/* Configure the radio to route the IRQ signal to its GPIO 3 */
+	SGpioInit x_gpio_init = {
+			SPIRIT_GPIO_IRQ,
+			SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP,
+			SPIRIT_GPIO_DIG_OUT_IRQ
+	};
+	spirit_gpio_init(&x_gpio_init);
+
+	/* Setup CSMA/CA */
+	CsmaInit x_csma_init = {
+			S_ENABLE,         // enable persistent mode
+			TBIT_TIME_64,     // Tcca time
+			TCCA_TIME_3,      // Lcca length
+			3,                // max nr of backoffs (<8)
+			1,                // BU counter seed
+			8                 // BU prescaler
+	};
+	csma_ca_init(&x_csma_init);
+
+#ifdef USE_STANDBY_STATE
+	/* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
+	cmd_strobe(SPIRIT1_STROBE_STANDBY);
+#endif // USE_STANDBY_STATE
+}
+
+static volatile int tx_fifo_remaining = 0;     // to be used in irq handler
+static volatile int tx_buffer_pos = 0;         // to be used in irq handler
+const volatile uint8_t *tx_fifo_buffer = NULL; // to be used in irq handler
+int SimpleSpirit1::send(const void *payload, unsigned int payload_len) {
+	/* Checks if the payload length is supported */
+	if(payload_len > MAX_PACKET_LEN) {
+		return RADIO_TX_ERR;
+	}
+
+	disable_spirit_irq();
+
+	BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+#ifndef NDEBUG
+	if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+	}
+#endif
+
+	/* Reset State to Ready */
+	set_ready_state();
+
+	cmd_strobe(SPIRIT1_STROBE_FTX); // flush TX FIFO buffer
+
+#ifndef NDEBUG
+	debug_if(!(linear_fifo_read_num_elements_tx_fifo() == 0), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+	pkt_basic_set_payload_length(payload_len); // set desired payload len
+
+	csma_ca_state(S_ENABLE); // enable CSMA/CA
+
+	/* Init buffer & number of bytes to be send */
+	tx_fifo_remaining = payload_len;
+	tx_fifo_buffer = (const uint8_t*)payload;
+
+	int8_t fifo_available = SPIRIT_MAX_FIFO_LEN; // fill-up whole fifo
+	int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining;
+
+	tx_fifo_remaining -= to_send;
+
+	/* Fill FIFO Buffer */
+	if(to_send > 0) {
+		spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[0]);
+	}
+
+	tx_buffer_pos = to_send;
+	_spirit_tx_started = true;
+
+	enable_spirit_irq();
+
+	/* Start transmitting */
+	cmd_strobe(SPIRIT1_STROBE_TX);
+
+	while(tx_fifo_remaining != 0); // wait until not everything is yet send (evtl. by irq handler)
+
+	BUSYWAIT_UNTIL(!_spirit_tx_started, STATE_TIMEOUT);
+#ifdef HEAVY_DEBUG
+	debug("\n\r%s (%d): state=%x, _spirit_tx_started=%d\n\r", __func__, __LINE__, SPIRIT1_STATUS()>>1, _spirit_tx_started);
+#endif
+
+	_spirit_tx_started = false; // in case of state timeout
+
+	csma_ca_state(S_DISABLE); // disable CSMA/CA
+
+	cmd_strobe(SPIRIT1_STROBE_RX); // Return to RX state
+
+	return RADIO_TX_OK;
+}
+
+/** Set Ready State **/
+void SimpleSpirit1::set_ready_state(void) {
+	uint16_t state;
+
+	disable_spirit_irq();
+
+	_spirit_tx_started = false;
+	_is_receiving = false;
+	stop_rx_timeout();
+
+	cmd_strobe(SPIRIT1_STROBE_FRX);
+	CLEAR_RXBUF();
+	CLEAR_TXBUF();
+
+	state = SPIRIT1_STATUS();
+	if(state == SPIRIT1_STATE_STANDBY) {
+		cmd_strobe(SPIRIT1_STROBE_READY);
+	} else if(state == SPIRIT1_STATE_RX) {
+		cmd_strobe(SPIRIT1_STROBE_SABORT);
+	} else if(state != SPIRIT1_STATE_READY) {
+#ifndef NDEBUG
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, state>>1);
+#endif
+	}
+
+	BUSYWAIT_UNTIL((SPIRIT1_STATUS() == SPIRIT1_STATE_READY) && ((last_state & XO_ON) == XO_ON), STATE_TIMEOUT);
+	if(last_state != (SPIRIT1_STATE_READY | XO_ON)) {
+		error("\n\rSpirit1: failed to become ready (%x) => pls. reset!\n\r", last_state);
+		enable_spirit_irq();
+		return;
+	}
+
+	irq_clear_status();
+
+	enable_spirit_irq();
+}
+
+int SimpleSpirit1::off(void) {
+	if(spirit_on == ON) {
+		/* Disables the mcu to get IRQ from the SPIRIT1 */
+		disable_spirit_irq();
+
+		/* first stop rx/tx */
+		set_ready_state();
+
+#ifdef USE_STANDBY_STATE
+		/* Puts the SPIRIT1 in STANDBY */
+		cmd_strobe(SPIRIT1_STROBE_STANDBY);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, STATE_TIMEOUT);
+		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_STANDBY) {
+			error("\n\rSpirit1: failed to enter standby (%x)\n\r", last_state>>1);
+			return 1;
+		}
+#endif // USE_STANDBY_STATE
+
+		spirit_on = OFF;
+		_nr_of_irq_disables = 1;
+	}
+	return 0;
+}
+
+int SimpleSpirit1::on(void) {
+	if(spirit_on == OFF) {
+		set_ready_state();
+
+		/* now we go to Rx */
+		cmd_strobe(SPIRIT1_STROBE_RX);
+
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
+			error("\n\rSpirit1: failed to enter rx (%x) => retry\n\r", last_state>>1);
+		}
+
+		/* Enables the mcu to get IRQ from the SPIRIT1 */
+		spirit_on = ON;
+#ifndef NDEBUG
+		debug_if(!(_nr_of_irq_disables == 1), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+		enable_spirit_irq();
+	}
+
+#ifndef NDEBUG
+	if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+	}
+#endif
+
+	return 0;
+}
+
+uint8_t SimpleSpirit1::refresh_state(void) {
+	uint8_t mcstate;
+
+	SpiritSpiReadRegisters(MC_STATE0_BASE, 1, &mcstate);
+
+	return mcstate;
+}
+
+int SimpleSpirit1::read(void *buf, unsigned int bufsize)
+{
+	disable_spirit_irq();
+
+	/* Checks if the RX buffer is empty */
+	if(IS_RXBUF_EMPTY()) {
+#ifndef NDEBUG
+		debug("\n\rBuffer is empty\n\r");
+#endif
+		set_ready_state();
+
+		cmd_strobe(SPIRIT1_STROBE_RX);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+		enable_spirit_irq();
+		return 0;
+	}
+
+	if(bufsize < spirit_rx_len) {
+		enable_spirit_irq();
+
+		/* If buf has the correct size */
+#ifndef NDEBUG
+		debug("\n\rTOO SMALL BUF\n\r");
+#endif
+		return 0;
+	} else {
+		/* Copies the packet received */
+		memcpy(buf, spirit_rx_buf, spirit_rx_len);
+
+		bufsize = spirit_rx_len;
+		CLEAR_RXBUF();
+
+		enable_spirit_irq();
+
+		return bufsize;
+	}
+
+}
+
+int SimpleSpirit1::channel_clear(void)
+{
+	float rssi_value;
+	/* Local variable used to memorize the SPIRIT1 state */
+	uint8_t spirit_state = ON;
+
+	if(spirit_on == OFF) {
+		/* Wakes up the SPIRIT1 */
+		on();
+		spirit_state = OFF;
+	}
+
+#ifndef NDEBUG
+	if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+		debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+	}
+#endif
+
+	disable_spirit_irq();
+
+	/* Reset State to Ready */
+	set_ready_state();
+
+	/* Stores the RSSI value */
+	rssi_value = qi_get_rssi_dbm();
+
+	enable_spirit_irq();
+
+	/* Puts the SPIRIT1 in its previous state */
+	if(spirit_state==OFF) {
+		off();
+#ifndef NDEBUG
+#ifdef USE_STANDBY_STATE
+		if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
+#else
+		if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
+#endif
+			debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		}
+#endif
+	} else {
+		disable_spirit_irq();
+
+        set_ready_state();
+
+		cmd_strobe(SPIRIT1_STROBE_RX);
+		BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, STATE_TIMEOUT);
+		if((last_state & SPIRIT1_STATE_STATEBITS) != SPIRIT1_STATE_RX) {
+			error("\n\rSpirit1: (#2) failed to enter rx (%x) => retry\n\r", last_state>>1);
+		}
+
+		enable_spirit_irq();
+
+#ifndef NDEBUG
+		if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
+			debug("\n\rAssert failed in: %s (%d): state=%x\n\r", __func__, __LINE__, last_state>>1);
+		}
+#endif
+	}
+
+	/* Checks the RSSI value with the threshold */
+	if(rssi_value<CCA_THRESHOLD) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+int SimpleSpirit1::get_pending_packet(void)
+{
+	return !IS_RXBUF_EMPTY();
+}
+
+/** Spirit Irq Callback **/
+/* betzw - TODO: use threaded interrupt handling when `MBED_CONF_RTOS_PRESENT` is defined (see `atmel-rf-driver`) */
+void SimpleSpirit1::IrqHandler() {
+	st_lib_spirit_irqs x_irq_status;
+
+	/* get interrupt source from radio */
+	irq_get_status(&x_irq_status);
+
+	/* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */
+	if(x_irq_status.IRQ_TX_DATA_SENT) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug_if(!_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!((*tmp) & IRQ_TX_DATA_SENT_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(tx_fifo_remaining != 0, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+		tx_fifo_buffer = NULL;
+		_spirit_tx_started = false;
+
+		/* call user callback */
+		if(_current_irq_callback) {
+			_current_irq_callback(TX_DONE);
+		}
+
+		/* Disable handling of other TX flags */
+		x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY = S_RESET;
+	}
+
+#ifndef RX_FIFO_THR_WA
+	/* The IRQ_TX_FIFO_ALMOST_EMPTY notifies an nearly empty TX fifo */
+	if(x_irq_status.IRQ_TX_FIFO_ALMOST_EMPTY) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug_if(!((*tmp) & IRQ_TX_FIFO_ALMOST_EMPTY_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(!_spirit_tx_started, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+		debug_if(tx_fifo_buffer == NULL, "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+		int8_t fifo_available = SPIRIT_MAX_FIFO_LEN/2; // fill-up half fifo
+		int8_t to_send = (tx_fifo_remaining > fifo_available) ? fifo_available : tx_fifo_remaining;
+
+		tx_fifo_remaining -= to_send;
+
+		/* Fill FIFO Buffer */
+		if(to_send > 0) {
+			spi_write_linear_fifo(to_send, (uint8_t*)&tx_fifo_buffer[tx_buffer_pos]);
+		}
+		tx_buffer_pos += to_send;
+	}
+#endif // !RX_FIFO_THR_WA
+
+	/* Transmission error */
+	if(x_irq_status.IRQ_TX_FIFO_ERROR) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+		debug_if(!((*tmp) & IRQ_TX_FIFO_ERROR_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+		if(_spirit_tx_started) {
+			_spirit_tx_started = false;
+			/* call user callback */
+			if(_current_irq_callback) {
+				_current_irq_callback(TX_ERR);
+			}
+		}
+
+		/* reset data still to be sent */
+		tx_fifo_remaining = 0;
+	}
+
+	/* The IRQ_RX_DATA_READY notifies a new packet arrived */
+	if(x_irq_status.IRQ_RX_DATA_READY) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug_if(!((*tmp) & IRQ_RX_DATA_READY_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+
+		if(!_is_receiving) { // spurious irq?!? (betzw: see comments on macro 'RX_FIFO_THR_WA'!)
+#ifdef HEAVY_DEBUG
+			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+#endif
+		} else {
+			_is_receiving = false; // Finished receiving
+			stop_rx_timeout();
+
+			spirit_rx_len = pkt_basic_get_received_pkt_length();
+
+#ifdef DEBUG_IRQ
+			debug_if(!(spirit_rx_len <= MAX_PACKET_LEN), "\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+#endif
+
+			if(spirit_rx_len <= MAX_PACKET_LEN) {
+				uint8_t to_receive = spirit_rx_len - _spirit_rx_pos;
+				if(to_receive > 0) {
+					spi_read_linear_fifo(to_receive, &spirit_rx_buf[_spirit_rx_pos]);
+					_spirit_rx_pos += to_receive;
+				}
+			}
+
+			cmd_strobe(SPIRIT1_STROBE_FRX);
+
+			last_rssi = qi_get_rssi(); //MGR
+			last_sqi  = qi_get_sqi();  //MGR
+
+			/* call user callback */
+			if((_spirit_rx_pos == spirit_rx_len) && _current_irq_callback) {
+				_current_irq_callback(RX_DONE);
+			}
+
+			/* Disable handling of other RX flags */
+			x_irq_status.IRQ_RX_FIFO_ALMOST_FULL = S_RESET;
+		}
+	}
+
+#ifndef RX_FIFO_THR_WA
+	/* RX FIFO almost full */
+	if(x_irq_status.IRQ_RX_FIFO_ALMOST_FULL) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug_if(!((*tmp) & IRQ_RX_FIFO_ALMOST_FULL_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+		if(!_is_receiving) { // spurious irq?!?
+#ifdef DEBUG_IRQ
+			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+#endif
+		} else {
+			uint8_t fifo_available = linear_fifo_read_num_elements_rx_fifo();
+			if((fifo_available + _spirit_rx_pos) <= MAX_PACKET_LEN) {
+				spi_read_linear_fifo(fifo_available, &spirit_rx_buf[_spirit_rx_pos]);
+				_spirit_rx_pos += fifo_available;
+			} else {
+#ifdef DEBUG_IRQ
+				debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+#endif
+			}
+		}
+	}
+#endif // !RX_FIFO_THR_WA
+
+	/* Reception errors */
+	if((x_irq_status.IRQ_RX_FIFO_ERROR) || (x_irq_status.IRQ_RX_DATA_DISC)) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+		debug_if(!((*tmp) & (IRQ_RX_FIFO_ERROR_MASK | IRQ_RX_DATA_DISC_MASK)), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+		rx_timeout_handler();
+		if(_spirit_tx_started) {
+			_spirit_tx_started = false;
+			/* call user callback */
+			if(_current_irq_callback) {
+				_current_irq_callback(TX_ERR);
+			}
+		}
+	}
+
+	/* The IRQ_VALID_SYNC is used to notify a new packet is coming */
+	if(x_irq_status.IRQ_VALID_SYNC) {
+#ifdef DEBUG_IRQ
+		uint32_t *tmp = (uint32_t*)&x_irq_status;
+		debug_if(!((*tmp) & IRQ_VALID_SYNC_MASK), "\n\rAssert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+		/* betzw - NOTE: there is a race condition between Spirit1 receiving packets and
+		 *               the MCU trying to send a packet, which gets resolved in favor of
+		 *               sending.
+		 */
+		if(_spirit_tx_started) {
+#ifdef DEBUG_IRQ
+			debug("\n\r%s (%d): irq=%x\n\r", __func__, __LINE__, *tmp);
+#endif
+		} else {
+			_is_receiving = true;
+			start_rx_timeout();
+		}
+	}
+}
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/README.md	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,155 @@
+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.
+
+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 buttons (user, reset)
+- USB
+- SPIRIT1 sub-1GHz transceiver  
+- HTS221, LIS3MDL, LPS25HB, LSM6DS0 sensors
+
+
+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.
+Detailed information on the NUCLEO-L152RE development board can be found at:
+http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002
+
+
+* 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.
+
+ >Detailed information on the X-NUCLEO-IDS01A4 expansion board can be found at:
+http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261982
+
+ >Detailed information on the X-NUCLEO-IDS01A5 expansion board can be found at:
+http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261983 
+
+ >Detailed information on the SPIRIT1 sub-1GHz transceiver can be found at:
+http://www.st.com/web/catalog/sense_power/FM2185/SC1845/PF253167
+
+* 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. 
+
+ >Detailed information on the X-NUCLEO-IKS01A1 expansion board can be found at:
+http://www.st.com/web/catalog/tools/FM146/CL2167/SC2006/PF261191
+
+
+* 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 commands are needed to download the full porting: 
+
+	git clone https://github.com/STclab/contiki.git
+	cd contiki/
+	git checkout stm32nucleo-spirit1
+	git submodule init
+	git submodule update
+
+
+Note: the first and third steps are required only if using the STclab GitHub repository, they won't be needed any more once the Pull Request is accepted.
+
+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 USE_SUBGHZ_BOARD=IDS01A4 clean
+	make TARGET=stm32nucleo-spirit1 USE_SUBGHZ_BOARD=IDS01A4
+
+If the X-NUCLEO-IDS01A5 sub-1GHz RF expansion board is used, the following must be run:
+
+	make TARGET=stm32nucleo-spirit1 USE_SUBGHZ_BOARD=IDS01A5 clean
+	make TARGET=stm32nucleo-spirit1 USE_SUBGHZ_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 USE_SUBGHZ_BOARD=IDS01A4 USE_SENSOR_BOARD=1
+
+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 -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/contiki-conf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/contiki-conf.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,155 @@
+/**
+******************************************************************************
+* @file    platform/stm32nucleo-spirit1/contiki-conf.h
+* @author  System LAB 
+* @version V1.0.0
+* @date    17-May-2015
+* @brief   Contiki configuration parameters
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*      without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (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"
+//#include "project-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 */
+
+#ifndef UIP_CONF_ND6_SEND_RA
+#define UIP_CONF_ND6_SEND_RA    0
+#endif
+#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
+
+
+#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS
+#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS   5
+#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */
+
+#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 -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/hw-config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/hw-config.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,125 @@
+ /**
+  ******************************************************************************
+  * @file    hw-config.h
+  * @author  System LAB 
+ * @version V1.0.0
+ * @date    17-May-2015
+  * @brief   Header file for Hardware Configuration & Setup
+  ******************************************************************************
+  * @attention
+  *
+ * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *   1. Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation
+ *      and/or other materials provided with the distribution.
+ *   3. Neither the name of STMicroelectronics nor the names of its contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+  *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (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 -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/ip64-conf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/ip64-conf.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * 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
+
+
+#undef UIP_FALLBACK_INTERFACE
+#define UIP_FALLBACK_INTERFACE ip64_uip_fallback_interface
+*/
+#ifdef MY_DRIVERS
+#include <my_wifi_interface.h>
+#include <my_wifi_driver.h>
+
+#define IP64_CONF_UIP_FALLBACK_INTERFACE_SLIP 0
+#define IP64_CONF_UIP_FALLBACK_INTERFACE my_wifi_interface
+#define IP64_CONF_INPUT                  my_wifi_interface_input
+#define IP64_CONF_ETH_DRIVER             my_wifi_driver
+
+#undef UIP_CONF_ND6_RA_RDNSS
+#define UIP_CONF_ND6_RA_RDNSS 1
+
+#undef UIP_CONF_ND6_SEND_RA
+#define UIP_CONF_ND6_SEND_RA  1
+
+#undef UIP_CONF_ROUTER
+#define UIP_CONF_ROUTER       1
+
+#ifndef QUEUEBUF_CONF_NUM
+#define QUEUEBUF_CONF_NUM          16
+#endif
+
+
+#else
+
+
+#include "net/ip64/ip64-slip-interface.h"
+#include "net/ip64/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
+
+#undef UIP_CONF_ND6_RA_RDNSS
+#define UIP_CONF_ND6_RA_RDNSS 1
+
+#undef UIP_CONF_ND6_SEND_RA
+#define UIP_CONF_ND6_SEND_RA  1
+
+#undef UIP_CONF_ROUTER
+#define UIP_CONF_ROUTER       1
+
+#ifndef QUEUEBUF_CONF_NUM
+#define QUEUEBUF_CONF_NUM          16
+#endif
+
+#endif//MY_DRIVERS
+
+#endif /* IP64_CONF_H */
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/platform-conf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/platform-conf.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,197 @@
+/**
+******************************************************************************
+* @file    platform/stm32nucleo-spirit1/platform-conf.h
+* @author  System LAB 
+* @version V1.0.0
+* @date    17-May-2015
+* @brief   Configuration parameters
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*      without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (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__
+/*---------------------------------------------------------------------------*/
+#ifdef USE_STM32L1XX_NUCLEO
+#include <inttypes.h>
+#include <string.h>
+/*---------------------------------------------------------------------------*/
+#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 COMPILE_SENSORS
+#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 /*COMPILE_SENSORS*/
+/*---------------------------------------------------------------------------*/
+#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 */
+
+#if WITH_IP64
+#include "ip64-conf.h"
+#define WITH_SLIP 1
+#ifndef UIP_FALLBACK_INTERFACE
+#define UIP_FALLBACK_INTERFACE ip64_uip_fallback_interface
+#endif
+#endif /* WITH_IP64 */
+
+/*---------------------------------------------------------------------------*/
+/* 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
+#define RELOAD_VALUE        ((F_CPU/CLOCK_CONF_SECOND) - 1)
+/* One tick: 62.5 ms */
+
+#define RTIMER_CLOCK_LT(a,b)     ((signed short)((a)-(b)) < 0)
+/*---------------------------------------------------------------------------*/
+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//USE_STM32L1XX_NUCLEO
+
+#ifdef USE_STM32F4XX_NUCLEO
+#include <inttypes.h>
+#include <string.h>
+#include "main.h"
+/*---------------------------------------------------------------------------*/
+#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 COMPILE_SENSORS
+#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 /*COMPILE_SENSORS*/
+/*---------------------------------------------------------------------------*/
+#define F_CPU                   	84000000ul
+#define RTIMER_ARCH_SECOND          96000//32678
+//#define PRESCALER       			uwPrescalerValue
+
+#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 */
+
+#if WITH_IP64
+#include "ip64-conf.h"
+#define WITH_SLIP 1
+#ifndef UIP_FALLBACK_INTERFACE
+#define UIP_FALLBACK_INTERFACE ip64_uip_fallback_interface
+#endif
+#endif /* WITH_IP64 */
+
+/*---------------------------------------------------------------------------*/
+/* 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             512
+#define RELOAD_VALUE        ((F_CPU/CLOCK_CONF_SECOND) - 1)
+
+/* One tick: 62.5 ms */
+
+#define RTIMER_CLOCK_LT(a,b)     ((signed short)((a)-(b)) < 0)
+/*---------------------------------------------------------------------------*/
+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//USE_STM32F4XX_NUCLEO
+
+#endif /* __PLATFORM_CONF_H__ */
+/*---------------------------------------------------------------------------*/
+/**
+ * @}
+ * @}
+ */
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/radio.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/radio.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,282 @@
+/*
+ * 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 radio API
+ * \author
+ *         Adam Dunkels <adam@sics.se>
+ *         Joakim Eriksson <joakime@sics.se>
+ *         Niclas Finne <nfi@sics.se>
+ *         Nicolas Tsiftes <nvt@sics.se>
+ */
+
+/**
+ * \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 <stddef.h>
+
+/**
+ * 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,
+
+  /*
+   * 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,
+
+  /* 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)
+
+/**
+ * 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);
+
+  /** Send the packet that has previously been prepared. */
+  int (* transmit)(unsigned short transmit_len);
+
+  /** Prepare & transmit a packet. */
+  int (* send)(const void *payload, unsigned short payload_len);
+
+  /** Read a received packet into a buffer. */
+  int (* read)(void *buf, unsigned short buf_len);
+
+  /** Perform a Clear-Channel Assessment (CCA) to find out if there is
+      a packet in the air or not. */
+  int (* channel_clear)(void);
+
+  /** Check if the radio driver is currently receiving a packet */
+  int (* receiving_packet)(void);
+
+  /** Check if the radio driver has just received a packet */
+  int (* pending_packet)(void);
+
+  /** Turn the radio on. */
+  int (* on)(void);
+
+  /** Turn the radio off. */
+  int (* off)(void);
+
+  /** 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 -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-config.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * 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               -98.0   /* dBm */
+#define XTAL_FREQUENCY              50000000    /* Hz */ 
+#define SPIRIT_MAX_FIFO_LEN         (96) // betzw - WAS: 600
+/*---------------------------------------------------------------------------*/
+
+/* Sometimes Spirit1 seems to NOT deliver (correctly) the 'IRQ_RX_DATA_READY'
+ * event for packets which have a length which is close to a multiple of
+ * RX FIFO size. Furthermore, in these cases also the content delivery seems
+ * to be compromised as well as the generation of RX/TX FIFO errors.
+ * This can be avoided by reducing the maximum packet length to a value which
+ * is lower than the RX FIFO size.
+ *
+ * Enable beyond macro if you want to use the version of the driver which avoids
+ * FIFO overflows by reducing packet length.
+ *
+ * NOTE: the non delivery of event 'IRQ_RX_DATA_READY' MUST still be
+ *       investigated further deeply (both on HW & SW level)!
+ */
+#define RX_FIFO_THR_WA
+
+/**    
+ * 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.
+ */
+#ifdef RX_FIFO_THR_WA
+#define MAX_PACKET_LEN              (SPIRIT_MAX_FIFO_LEN-1)
+#else
+#define MAX_PACKET_LEN              (255) // betzw - WAS: SPIRIT_MAX_FIFO_LEN, but LEN_WIDTH is set to 7 so the variable payload length is theoretically from 0 to 255 bytes
+#endif
+
+/*---------------------------------------------------------------------------*/
+/**    
+ * Spirit1 IC version
+ */
+#define SPIRIT1_VERSION             SPIRIT_VERSION_3_0
+/*---------------------------------------------------------------------------*/
+#endif /* __SPIRIT1_CONFIG_H__ */
+/*---------------------------------------------------------------------------*/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-const.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1-const.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,75 @@
+/*
+ * 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 copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (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
+/*---------------------------------------------------------------------------*/
+
+
+
+/* Exported types ------------------------------------------------------------*/
+/*------------------------------------------------------------------*/
+
+
+#endif /* __SPIRIT1_CONST_H__ */
+/*---------------------------------------------------------------------------*/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/spirit1.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,179 @@
+/*
+ * 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 __SPIRIT_H__
+#define __SPIRIT_H__
+/*---------------------------------------------------------------------------*/
+#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);
+
+/* exported from spirit1appli.h */
+
+#include "radio_shield_config.h"
+#include "MCU_Interface.h"
+#include "SPIRIT_Config.h"
+// betzw - WAS: #include "SPIRIT1_Util.h"
+
+
+#if defined(X_NUCLEO_IDS01A3)
+	 #define USE_SPIRIT1_433MHz
+#elif defined(X_NUCLEO_IDS01A4)
+         #define USE_SPIRIT1_868MHz
+#elif defined(X_NUCLEO_IDS01A5)
+         #define USE_SPIRIT1_915MHz
+#else
+#error SPIRIT1 Nucleo Shield undefined or unsupported
+#endif
+
+/*  Uncomment the Link Layer features to be used */
+// #define USE_AUTO_ACK
+// #define USE_AUTO_ACK_PIGGYBACKING
+// #define USE_AUTO_RETRANSMISSION
+
+#if defined(USE_AUTO_ACK)&& defined(USE_AUTO_ACK_PIGGYBACKING)&& defined(USE_AUTO_RETRANSMISSION)
+#define USE_STack_PROTOCOL
+
+/* LLP configuration parameters */
+#define EN_AUTOACK                      S_ENABLE
+#define EN_PIGGYBACKING             	S_ENABLE
+#define MAX_RETRANSMISSIONS         	PKT_N_RETX_2
+
+#else
+#define USE_BASIC_PROTOCOL
+
+#endif
+
+/*  Uncomment the system Operating mode */
+//#define USE_LOW_POWER_MODE
+
+#if defined (USE_LOW_POWER_MODE)
+#define LPM_ENABLE
+#define MCU_STOP_MODE
+//#define MCU_SLEEP_MODE
+//#define RF_STANDBY
+#endif
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/*  Radio configuration parameters  */
+#define XTAL_OFFSET_PPM             0
+#define INFINITE_TIMEOUT            0.0
+
+#ifdef USE_SPIRIT1_433MHz
+#define BASE_FREQUENCY              433.0e6
+#endif
+
+#ifdef USE_SPIRIT1_868MHz
+#define BASE_FREQUENCY              868.0e6
+#endif
+
+#ifdef USE_SPIRIT1_915MHz
+//#define BASE_FREQUENCY              915.0e6
+#define BASE_FREQUENCY              902.0e6
+#endif
+
+
+/*  Addresses configuration parameters  */
+#define EN_FILT_MY_ADDRESS          S_DISABLE
+#define MY_ADDRESS                  0x24
+#define EN_FILT_MULTICAST_ADDRESS   S_DISABLE
+#define MULTICAST_ADDRESS           0xEE
+#define EN_FILT_BROADCAST_ADDRESS   S_DISABLE
+#define BROADCAST_ADDRESS           0xFF
+#define DESTINATION_ADDRESS         0x44
+#define EN_FILT_SOURCE_ADDRESS      S_DISABLE
+#define SOURCE_ADDR_MASK            0xf0
+#define SOURCE_ADDR_REF             0x37
+
+#define APPLI_CMD                       0x11
+#define NWK_CMD                         0x22
+#define LED_TOGGLE                      0xff
+#define ACK_OK                          0x01
+#define MAX_BUFFER_LEN                  96
+#define TIME_TO_EXIT_RX                 3000
+#define DELAY_RX_LED_TOGGLE             200
+#define DELAY_TX_LED_GLOW               1000
+#define LPM_WAKEUP_TIME                 100
+#define DATA_SEND_TIME                  30
+
+#define PREAMBLE_LENGTH             PKT_PREAMBLE_LENGTH_04BYTES
+#define SYNC_LENGTH                 PKT_SYNC_LENGTH_4BYTES
+#define CONTROL_LENGTH              PKT_CONTROL_LENGTH_0BYTES
+#define EN_ADDRESS                  S_DISABLE
+#define EN_FEC                      S_DISABLE
+#define CHANNEL_NUMBER              1 // betzw - WAS: 0
+#define LENGTH_TYPE                 PKT_LENGTH_VAR
+#define POWER_INDEX                 7
+#define RECEIVE_TIMEOUT             2000.0 /*change the value for required timeout period*/
+#define RSSI_THRESHOLD              -120
+
+
+
+#define POWER_DBM                   11.6
+#define CHANNEL_SPACE               100e3
+#define FREQ_DEVIATION              127e3
+#define BANDWIDTH                   540.0e3
+#define MODULATION_SELECT           GFSK_BT1
+#define DATARATE                    250000
+#define XTAL_OFFSET_PPM             0
+#define SYNC_WORD                   0x88888888
+#define LENGTH_WIDTH                8 // betzw - NOTE: only 255 bytes for payload!!!
+#define CRC_MODE                    PKT_CRC_MODE_16BITS_2
+#define EN_WHITENING                S_DISABLE
+#define INFINITE_TIMEOUT            0.0
+
+// extern volatile FlagStatus xRxDoneFlag, xTxDoneFlag;
+// extern volatile FlagStatus PushButtonStatusWakeup;
+extern uint16_t wakeupCounter;
+extern uint16_t dataSendCounter ;
+// extern volatile FlagStatus PushButtonStatusData, datasendFlag;
+
+typedef struct
+{
+  uint8_t Cmdtag;
+  uint8_t CmdType;
+  uint8_t CmdLen;
+  uint8_t Cmd;
+  uint8_t DataLen;
+  uint8_t* DataBuff;
+}AppliFrame_t;
+
+/*---------------------------------------------------------------------------*/
+#endif /* __SPIRIT_H__ */
+/*---------------------------------------------------------------------------*/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/stm32l-spirit1-config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/Contiki_STM32_Library/stm32l-spirit1-config.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,98 @@
+/**
+  ******************************************************************************
+  * @file    stm32l-spirit1-config.h
+  * @author  MCD Application Team
+  * @version V3.4.0
+  * @date    29-June-2012
+  * @brief   Evaluation board specific configuration file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+  *
+  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/software_license_agreement_liberty_v2
+  *
+  * Unless required by applicable law or agreed to in writing, software 
+  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+
+/* 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 -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/Release_Notes.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/Release_Notes.html	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head>
+
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<link rel="File-List" href="Library_files/filelist.xml">
+<link rel="Edit-Time-Data" href="Library_files/editdata.mso"><!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><title>Release Notes for SPIRIT1 Driver</title><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>STMicroelectronics</o:Author> <o:LastAuthor>STMicroelectronics</o:LastAuthor> <o:Revision>37</o:Revision> <o:TotalTime>136</o:TotalTime> <o:Created>2009-02-27T19:26:00Z</o:Created> <o:LastSaved>2009-03-01T17:56:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>522</o:Words> <o:Characters>2977</o:Characters> <o:Company>STMicroelectronics</o:Company> <o:Lines>24</o:Lines> <o:Paragraphs>6</o:Paragraphs> <o:CharactersWithSpaces>3493</o:CharactersWithSpaces> <o:Version>11.6568</o:Version> </o:DocumentProperties> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:Zoom>110</w:Zoom> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]-->
+
+
+
+<style>
+<!--
+/* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+{mso-style-parent:"";
+margin:0in;
+margin-bottom:.0001pt;
+mso-pagination:widow-orphan;
+font-size:12.0pt;
+font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";}
+h2
+{mso-style-next:Normal;
+margin-top:12.0pt;
+margin-right:0in;
+margin-bottom:3.0pt;
+margin-left:0in;
+mso-pagination:widow-orphan;
+page-break-after:avoid;
+mso-outline-level:2;
+font-size:14.0pt;
+font-family:Arial;
+font-weight:bold;
+font-style:italic;}
+a:link, span.MsoHyperlink
+{color:blue;
+text-decoration:underline;
+text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+{color:blue;
+text-decoration:underline;
+text-underline:single;}
+p
+{mso-margin-top-alt:auto;
+margin-right:0in;
+mso-margin-bottom-alt:auto;
+margin-left:0in;
+mso-pagination:widow-orphan;
+font-size:12.0pt;
+font-family:"Times New Roman";
+mso-fareast-font-family:"Times New Roman";}
+@page Section1
+{size:8.5in 11.0in;
+margin:1.0in 1.25in 1.0in 1.25in;
+mso-header-margin:.5in;
+mso-footer-margin:.5in;
+mso-paper-source:0;}
+div.Section1
+{page:Section1;}
+-->
+</style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="5122"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]-->
+<meta content="MCD Application Team" name="author"></head><body link="blue" vlink="blue">
+<div class="Section1">
+<p class="MsoNormal"><span style="font-family: Arial;"><o:p><br>
+</o:p></span></p>
+<div align="center">
+<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
+<tbody>
+<tr>
+<td style="padding: 0cm;" valign="top">
+<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900">
+<tbody>
+<tr>
+<td style="vertical-align: top;">
+<p class="MsoNormal"><span style="font-size: 8pt; font-family: Arial; color: blue;"><a href="../../../../Release_Notes.html">Back to Release page</a><o:p></o:p></span></p>
+</td>
+</tr>
+<tr style="">
+<td style="padding: 1.5pt;">
+<h1 style="margin-bottom: 18pt; text-align: center;" align="center"><span style="font-size: 20pt; font-family: Verdana; color: rgb(51, 102, 255);">Release
+Notes for SPIRIT1 Driver</span><span style="font-size: 20pt; font-family: Verdana;"><o:p></o:p></span></h1>
+<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;">Copyright
+2014 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p>
+<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;"><img alt="" id="_x0000_i1025" src="../../../../_htmresc/st_logo.png" style="border: 0px solid ; width: 86px; height: 65px;"></span><span style="font-size: 10pt;"><o:p></o:p></span></p>
+</td>
+</tr>
+</tbody>
+</table>
+<p class="MsoNormal"><span style="font-family: Arial; display: none;"><o:p>&nbsp;</o:p></span></p>
+<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900">
+<tbody>
+<tr style="">
+<td style="padding: 0cm;" valign="top">
+<span style="font-family: &quot;Times New Roman&quot;;">
+</span>
+<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">Update History</span></h2>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-right: 500pt; width: 200px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V3.0.1
+/ 10-Oct-2014</span></h3>
+<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main
+Changes<o:p></o:p></span></u></b></p>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span><span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<span style="font-size: 10pt; font-family: Verdana;"></span>
+<ul style="list-style-type: square;">
+<li><span style="font-size: 10pt; font-family: Verdana;">First
+official release.</span><span style="color: rgb(0, 0, 0); font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; display: inline ! important; float: none;"></span><span style="font-size: 10pt; font-family: Verdana;"></span><span style="font-size: 10pt; font-family: Verdana;"></span></li>
+</ul>
+<span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"></span>
+<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span><br>
+</h2>
+
+
+<font size="-1"><span style="font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;">Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"). You may not use this file except in compliance with the License. You may obtain a copy of the License at:</span><br><br>
+
+
+<font size="-1"><span style="font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;"><center>
+<a href=http://www.st.com/software_license_agreement_liberty_v2> http://www.st.com/software_license_agreement_liberty_v2</a></center></span><br><br>
+
+<font size="-1"><span style="font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;;">Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+</a></span>
+
+</font>
+
+
+<p class="MsoNormal"><span style="font-size: 10pt; font-family: &quot;Verdana&quot;,&quot;sans-serif&quot;; color: black;"><o:p></o:p></span></p>
+<b><span style="font-size: 10pt; font-family: Verdana; color: black;"></span></b>
+<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;">
+<hr align="center" size="2" width="100%"></span></div>
+<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt; text-align: center;" align="center"><span style="font-size: 10pt; font-family: Verdana; color: black;">For
+complete documentation on</span><span style="font-size: 10pt; font-family: Verdana;"><span style="color: black;">&nbsp;SPIRIT1 Driver
+visit </span><u><span style="color: blue;"><a href="http://www.st.com/web/catalog/sense_power/FM1968/CL1976/SC1845/PF253167" target="_blank">www.st.com/SPIRIT1</a></span></u></span><span style="font-size: 10pt; font-family: Verdana;"><a target="_blank" href="http://www.st.com/web/catalog/sense_power/FM1968/CL1976/SC1898/PF258646"><u><span style="color: blue;"></span></u></a></span><span style="font-size: 10pt; font-family: Verdana;"><u><span style="color: blue;"></span></u></span><span style="color: black;"><o:p></o:p></span></p>
+</td>
+</tr>
+</tbody>
+</table>
+<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
+</div>
+</body></html>
\ No newline at end of file
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/MCU_Interface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/MCU_Interface.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,152 @@
+/**
+ * @file    MCU_Interface.h
+ * @author  VMA division - AMS
+ * @version V2.0.2
+ * @date    Febrary 7, 2015
+ * @brief   Header file for low level SPIRIT SPI driver.
+ * @details
+ *
+ * This header file constitutes an interface to the SPI driver used to
+ * communicate with Spirit.
+ * It exports some function prototypes to write/read registers and FIFOs
+ * and to send command strobes.
+ * Since the Spirit libraries are totally platform independent, the implementation
+ * of these functions are not provided here. The user have to implement these functions
+ * taking care to keep the exported prototypes.
+ *
+ * These functions are:
+ *
+ * <ul>
+ * <li>SpiritSpiInit</i>
+ * <li>SpiritSpiWriteRegisters</i>
+ * <li>SpiritSpiReadRegisters</i>
+ * <li>SpiritSpiCommandStrobes</i>
+ * <li>SpiritSpiWriteLinearFifo</i>
+ * <li>SpiritSpiReadLinearFifo</i>
+ * </ul>
+ *
+ * @note An example of SPI driver implementation is available in the <i>Sdk_Eval</i> library.
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
+ *
+ * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MCU_INTERFACE_H
+#define __MCU_INTERFACE_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/** @defgroup SPIRIT_SPI_Driver         SPI Driver
+ * @brief Header file for low level SPIRIT SPI driver.
+ * @details See the file <i>@ref MCU_Interface.h</i> for more details.
+ * @{
+ */
+
+
+
+/** @defgroup SPI_Exported_Types        SPI Exported Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup SPI_Exported_Constants    SPI Exported Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup SPI_Exported_Macros       SPI Exported Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup SPI_Exported_Functions    SPI Exported Functions
+ * @{
+ */
+
+typedef SpiritStatus StatusBytes;
+
+void SdkEvalSpiInit(void);
+StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
+StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+
+void SdkEvalEnterShutdown(void);
+void SdkEvalExitShutdown(void);
+SpiritFlagStatus SdkEvalCheckShutdown(void);
+
+#define SpiritEnterShutdown                                  SdkEvalEnterShutdown
+#define SpiritExitShutdown                                   SdkEvalExitShutdown
+#define SpiritCheckShutdown                                  (SpiritFlagStatus)SdkEvalCheckShutdown
+
+
+#define SpiritSpiInit                                                  SdkEvalSpiInit
+#define SpiritSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer)       SdkEvalSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer)
+#define SpiritSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer)        SdkEvalSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer)
+#define SpiritSpiCommandStrobes(cCommandCode)                          SdkEvalSpiCommandStrobes(cCommandCode)
+#define SpiritSpiWriteLinearFifo(cNbBytes, pcBuffer)                         SdkEvalSpiWriteFifo(cNbBytes, pcBuffer)
+#define SpiritSpiReadLinearFifo(cNbBytes, pcBuffer)                          SdkEvalSpiReadFifo(cNbBytes, pcBuffer)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Aes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Aes.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,205 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Aes.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT AES Engine.
+  *
+ * @details
+ *
+ * In order to encrypt data, the user must manage the AES_END IRQ.
+ * The data have to be splitted in blocks of 16 bytes and written
+ * into the <i>AES DATA IN registers</i>. Then, after the key is written
+ * into the <i>AES KEY registers</i>, a command of <i>Execute encryption</i>
+ * has to be sent.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritAesWriteDataIn(data_buff , N_BYTES);
+ *  SpiritAesExecuteEncryption();
+ *
+ *  while(!aes_end_flag);       // the flag is set by the ISR routine which manages the AES_END irq
+ *  aes_end_flag=RESET;
+ *
+ *  SpiritAesReadDataOut(enc_data_buff , N_BYTES);
+ *
+ * @endcode
+ *
+ * In order to decrypt data, the user must manage the AES_END IRQ and have a decryption key.
+ * There are two operative modes to make the data decryption:
+ * <ul>
+ * <li> Derive the decryption key from the encryption key and decrypt data directly
+ * using the <i>SpiritAesDeriveDecKeyExecuteDec()</i> function
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritAesWriteDataIn(enc_data_buff , N_BYTES);
+ *  SpiritAesDeriveDecKeyExecuteDec();
+ *
+ *  while(!aes_end_flag);       // the flag is set by the ISR routine which manages the AES_END irq
+ *  aes_end_flag=RESET;
+ *
+ *  SpiritAesReadDataOut(data_buff , N_BYTES);
+ *
+ * @endcode
+ * </li>
+ *
+ * <li> Derive the decryption key from the encryption key using the <i>SpiritAesDeriveDecKeyFromEnc()</i>
+ * function, store it into the <i>AES KEY registers</i> and then decrypt data using the
+ * <i>SpiritAesExecuteDecryption()</i> function
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritAesWriteDataIn(key_enc , 16);
+ *  SpiritAesDeriveDecKeyFromEnc();
+ *
+ *  while(!aes_end_flag);       // the flag is set by the ISR routine which manages the AES_END irq
+ *  aes_end_flag=RESET;
+ *
+ *  SpiritAesReadDataOut(key_dec , 16);
+ *
+ *  SpiritAesWriteKey(key_dec);
+ *  SpiritAesWriteDataIn(enc_data_buff , 16);
+ *  SpiritAesExecuteDecryption();
+ *
+ *  while(!aes_end_flag);       // the flag is set by the ISR routine which manages the AES_END irq
+ *  aes_end_flag=RESET;
+ *
+ *  SpiritAesReadDataOut(data_buff , N_BYTES);
+ *
+ * @endcode
+ * </li>
+ * </ul>
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_AES_H
+#define __SPIRIT_AES_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Aes AES
+ * @brief Configuration and management of SPIRIT AES Engine.
+ * @details See the file <i>@ref SPIRIT_Aes.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Aes_Exported_Types AES Exported Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Exported_Constants     AES Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Exported_Macros        AES Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Exported_Functions     AES Exported Functions
+ * @{
+ */
+
+void SpiritAesMode(SpiritFunctionalState xNewState);
+void SpiritAesWriteDataIn(uint8_t* pcBufferDataIn, uint8_t cDataLength);
+void SpiritAesReadDataOut(uint8_t* pcBufferDataOut, uint8_t cDataLength);
+void SpiritAesWriteKey(uint8_t* pcKey);
+void SpiritAesReadKey(uint8_t* pcKey);
+void SpiritAesDeriveDecKeyFromEnc(void);
+void SpiritAesExecuteEncryption(void);
+void SpiritAesExecuteDecryption(void);
+void SpiritAesDeriveDecKeyExecuteDec(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Calibration.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Calibration.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,226 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Calibration.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT VCO-RCO calibration.
+  *
+ * @details
+ *
+ * This module allows the user to set some parameters which deal
+ * with the oscillators calibration.
+ * The state machine of Spirit contemplates some optional calibrating operations
+ * in the transition between the READY and the LOCK state.
+ * The user is allowed to enable or disable the automatic RCO/VCO calibration
+ * by calling the functions <i>@ref SpiritCalibrationVco()</i> and <i>@ref SpiritCalibrationRco()</i>.
+ * The following example shows how to do an initial calibration of VCO.
+ *
+ * <b>Example:</b>
+ * @code
+ *  uint8_t calData;
+ *
+ *  SpiritCalibrationVco(S_ENABLE);
+ *  SpiritCmdStrobeLockTx();
+ *
+ *  while(g_xStatus.MC_STATE != MC_STATE_LOCK){
+ *      SpiritRefreshStatus();
+ *  }
+ *
+ *  calData = SpiritCalibrationGetVcoCalDataTx();
+ *  SpiritCalibrationSetVcoCalDataTx(calData);
+ *
+ *  SpiritCmdStrobeReady();
+ *  SpiritCalibrationVco(S_DISABLE);
+ *
+ * @endcode
+ *
+ * Similar operations can be done for the RCO calibrator.
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_CALIBRATION_H
+#define __SPIRIT_CALIBRATION_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Calibration Calibration
+ * @brief Configuration and management of SPIRIT VCO-RCO calibration.
+ * @details See the file <i>@ref SPIRIT_Calibration.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Calibration_Exported_Types Calibration Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  VCO / RCO calibration window.
+ */
+typedef enum
+{
+
+  CALIB_TIME_7_33_US_24MHZ = 0x00,	/*!< calibration window of 7.33 us with XTAL=24MHz */
+  CALIB_TIME_14_67_US_24MHZ,		/*!< calibration window of 14.67 us with XTAL=24MHz */
+  CALIB_TIME_29_33_US_24MHZ,		/*!< calibration window of 29.33 us with XTAL=24MHz */
+  CALIB_TIME_58_67_US_24MHZ,		/*!< calibration window of 58.67 us with XTAL=24MHz */
+
+  CALIB_TIME_6_77_US_26MHZ = 0x00,	/*!< calibration window of 6.77 us with XTAL=26MHz */
+  CALIB_TIME_13_54_US_26MHZ,		/*!< calibration window of 13.54 us with XTAL=26MHz */
+  CALIB_TIME_27_08_US_26MHZ,		/*!< calibration window of 27.08 us with XTAL=26MHz */
+  CALIB_TIME_54_15_US_26MHZ		/*!< calibration window of 54.15 us with XTAL=26MHz */
+
+} VcoWin;
+
+
+#define IS_VCO_WIN(REF)   (REF == CALIB_TIME_7_33_US_24MHZ  ||\
+                           REF == CALIB_TIME_14_67_US_24MHZ ||\
+                           REF == CALIB_TIME_29_33_US_24MHZ ||\
+                           REF == CALIB_TIME_58_67_US_24MHZ ||\
+                           REF == CALIB_TIME_6_77_US_26MHZ  ||\
+                           REF == CALIB_TIME_13_54_US_26MHZ ||\
+                           REF == CALIB_TIME_27_08_US_26MHZ ||\
+                           REF == CALIB_TIME_54_15_US_26MHZ \
+                           )
+
+/**
+ * @brief  VCO_H / VCO_L selection.
+ */
+typedef enum
+{
+
+  VCO_L = 0x00,	        /*!< VCO lower */
+  VCO_H,		/*!< VCO higher */
+} VcoSel;
+
+
+#define IS_VCO_SEL(REF)   (REF == VCO_L  ||\
+                           REF == VCO_H \
+                           )
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Calibration_Exported_Constants     Calibration Exported Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup VCO_Calibration   VCO Calibration
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+
+
+/**
+ * @defgroup Calibration_Exported_Macros        Calibration Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Calibration_Exported_Functions     Calibration Exported Functions
+ * @{
+ */
+
+void SpiritCalibrationRco(SpiritFunctionalState xNewState);
+void SpiritCalibrationVco(SpiritFunctionalState xNewState);
+void SpiritCalibrationSetRcoCalWords(uint8_t cRwt, uint8_t cRfb);
+void SpiritCalibrationGetRcoCalWords(uint8_t* pcRwt, uint8_t* pcRfb);
+uint8_t SpiritCalibrationGetVcoCalData(void);
+void SpiritCalibrationSetVcoCalDataTx(uint8_t cVcoCalData);
+uint8_t SpiritCalibrationGetVcoCalDataTx(void);
+void SpiritCalibrationSetVcoCalDataRx(uint8_t cVcoCalData);
+uint8_t SpiritCalibrationGetVcoCalDataRx(void);
+void SpiritCalibrationSetVcoWindow(VcoWin xRefWord);
+VcoWin SpiritCalibrationGetVcoWindow(void);
+VcoSel SpiritCalibrationGetVcoSelecttion(void);
+void SpiritCalibrationSelectVco(VcoSel xVco);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Commands.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Commands.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,336 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Commands.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Management of SPIRIT Commands.
+  *
+ * @details
+ *
+ * In this module can be found all the API used to strobe commands to
+ * Spirit.
+ * Every command strobe is an SPI transaction with a specific command code.
+ *
+ * <b>Example:</b>
+ * @code
+ *   ...
+ *
+ *   SpiritCmdStrobeRx();
+ *
+ *   ...
+ * @endcode
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_COMMANDS_H
+#define __SPIRIT_COMMANDS_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Commands    Commands
+ * @brief Management of SPIRIT Commands.
+ * @details See the file <i>@ref SPIRIT_Commands.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Commands_Exported_Types    Commands Exported Types
+ * @{
+ */
+
+/**
+  * @brief  SPIRIT Commands codes enumeration
+  */
+typedef enum
+{
+  CMD_TX =  COMMAND_TX,                           /*!< Start to transmit; valid only from READY */
+  CMD_RX =  COMMAND_RX,                           /*!< Start to receive; valid only from READY */
+  CMD_READY =  COMMAND_READY,                     /*!< Go to READY; valid only from STANDBY or SLEEP or LOCK */
+  CMD_STANDBY =  COMMAND_STANDBY,                 /*!< Go to STANDBY; valid only from READY */
+  CMD_SLEEP = COMMAND_SLEEP,                      /*!< Go to SLEEP; valid only from READY */
+  CMD_LOCKRX = COMMAND_LOCKRX,                    /*!< Go to LOCK state by using the RX configuration of the synth; valid only from READY */
+  CMD_LOCKTX = COMMAND_LOCKTX,                    /*!< Go to LOCK state by using the TX configuration of the synth; valid only from READY */
+  CMD_SABORT = COMMAND_SABORT,                    /*!< Force exit form TX or RX states and go to READY state; valid only from TX or RX */
+  CMD_LDC_RELOAD = COMMAND_LDC_RELOAD,            /*!< LDC Mode: Reload the LDC timer with the value stored in the  LDC_PRESCALER / COUNTER  registers; valid from all states  */
+  CMD_SEQUENCE_UPDATE =  COMMAND_SEQUENCE_UPDATE, /*!< Autoretransmission: Reload the Packet sequence counter with the value stored in the PROTOCOL[2] register valid from all states */
+  CMD_AES_ENC = COMMAND_AES_ENC,                  /*!< Commands: Start the encryption routine; valid from all states; valid from all states */
+  CMD_AES_KEY = COMMAND_AES_KEY,                  /*!< Commands: Start the procedure to compute the key for the decryption; valid from all states */
+  CMD_AES_DEC = COMMAND_AES_DEC,                  /*!< Commands: Start the decryption routine using the current key; valid from all states */
+  CMD_AES_KEY_DEC = COMMAND_AES_KEY_DEC,          /*!< Commands: Compute the key and start the decryption; valid from all states */
+  CMD_SRES = COMMAND_SRES,                        /*!< Reset of all digital part, except SPI registers */
+  CMD_FLUSHRXFIFO = COMMAND_FLUSHRXFIFO,          /*!< Clean the RX FIFO; valid from all states */
+  CMD_FLUSHTXFIFO = COMMAND_FLUSHTXFIFO,          /*!< Clean the TX FIFO; valid from all states */
+} SpiritCmd;
+
+#define IS_SPIRIT_CMD(CMD)  (CMD == CMD_TX || \
+                             CMD == CMD_RX || \
+                             CMD == CMD_READY || \
+                             CMD == CMD_STANDBY || \
+                             CMD == CMD_SLEEP || \
+                             CMD == CMD_LOCKRX || \
+                             CMD == CMD_LOCKTX || \
+                             CMD == CMD_SABORT || \
+                             CMD == CMD_LDC_RELOAD || \
+                             CMD == CMD_SEQUENCE_UPDATE || \
+                             CMD == CMD_AES_ENC || \
+                             CMD == CMD_AES_KEY || \
+                             CMD == CMD_AES_DEC || \
+                             CMD == CMD_AES_KEY_DEC || \
+                             CMD == CMD_SRES || \
+                             CMD == CMD_FLUSHRXFIFO || \
+                             CMD == CMD_FLUSHTXFIFO \
+                            )
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Commands_Exported_Constants        Commands Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Commands_Exported_Macros   Commands Exported Macros
+ * @{
+ */
+
+/**
+ * @brief  Sends the TX command to SPIRIT. Start to transmit.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeTx()      {SpiritManagementWaCmdStrobeTx(); \
+                                  SpiritCmdStrobeCommand(CMD_TX);} 
+
+
+/**
+ * @brief  Sends the RX command to SPIRIT. Start to receive.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeRx()      {SpiritManagementWaCmdStrobeRx(); \
+                                  SpiritCmdStrobeCommand(CMD_RX); \
+                                  } 
+
+
+/**
+ * @brief  Sends the Ready state command to SPIRIT. Go to READY.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeReady()          SpiritCmdStrobeCommand(CMD_READY)
+
+
+
+/**
+ * @brief  Sends the Standby command to SPIRIT. Go to STANDBY.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeStandby()        SpiritCmdStrobeCommand(CMD_STANDBY)
+
+
+
+/**
+ * @brief  Sends the Sleep command to SPIRIT. Go to SLEEP.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeSleep()          SpiritCmdStrobeCommand(CMD_SLEEP)
+
+
+
+/**
+ * @brief  Sends the LOCK_RX command to SPIRIT. Go to the LOCK state by using the RX configuration of the synthesizer.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeLockRx()         SpiritCmdStrobeCommand(CMD_LOCKRX)
+
+
+
+/**
+ * @brief  Sends the LOCK_TX command to SPIRIT. Go to the LOCK state by using the TX configuration of the synthesizer.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeLockTx()         SpiritCmdStrobeCommand(CMD_LOCKTX)
+
+
+
+/**
+ * @brief  Sends the SABORT command to SPIRIT. Exit from TX or RX states and go to READY state.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeSabort()         SpiritCmdStrobeCommand(CMD_SABORT)
+
+
+/**
+ * @brief  Sends the LDC_RELOAD command to SPIRIT. Reload the LDC timer with the value stored in the LDC_PRESCALER / COUNTER registers.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeLdcReload()      SpiritCmdStrobeCommand(CMD_LDC_RELOAD)
+
+
+
+/**
+ * @brief  Sends the SEQUENCE_UPDATE command to SPIRIT. Reload the Packet sequence counter with the value stored in the PROTOCOL[2] register.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeSequenceUpdate() SpiritCmdStrobeCommand(CMD_SEQUENCE_UPDATE)
+
+
+
+/**
+ * @brief  Sends the AES_ENC command to SPIRIT. Starts the encryption routine.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeAesEnc()         SpiritCmdStrobeCommand(CMD_AES_ENC)
+
+
+
+/**
+ * @brief  Sends the AES_KEY command to SPIRIT. Starts the procedure to compute the key for the decryption.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeAesKey()         SpiritCmdStrobeCommand(CMD_AES_KEY)
+
+
+
+/**
+ * @brief  Sends the AES_DEC command to SPIRIT. Starts the decryption using the current key.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeAesDec()         SpiritCmdStrobeCommand(CMD_AES_DEC)
+
+
+
+/**
+ * @brief  Sends the KEY_DEC command to SPIRIT. Computes the key derivation and start the decryption.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeAesKeyDec()     SpiritCmdStrobeCommand(CMD_AES_KEY_DEC)
+
+/**
+ * @brief  Sends the SRES command to SPIRIT. Partial reset: all digital circuit will be reset (exception for SPI only).
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeSres()          SpiritCmdStrobeCommand(CMD_SRES)  
+  
+
+/**
+ * @brief  Sends the FLUSHRXFIFO command to SPIRIT. Clean the RX FIFO.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeFlushRxFifo()    SpiritCmdStrobeCommand(CMD_FLUSHRXFIFO)
+
+
+
+/**
+ * @brief  Sends the FLUSHTXFIFO command to SPIRIT. Clean the TX FIFO.
+ * @param  None.
+ * @retval None.
+ */
+#define SpiritCmdStrobeFlushTxFifo()    SpiritCmdStrobeCommand(CMD_FLUSHTXFIFO)
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Commands_Exported_Functions    Commands Exported Functions
+ * @{
+ */
+void SpiritCmdStrobeCommand(SpiritCmd xCommandCode);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Config.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,147 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Config.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Spirit Configuration and useful defines 
+  * 
+ * @details
+ *
+ * This file is used to include all or a part of the Spirit
+ * libraries into the application program which will be used.
+ * Moreover some important parameters are defined here and the
+ * user is allowed to edit them.
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_CONFIG_H
+#define __SPIRIT_CONFIG_H
+
+
+  /* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Aes.h"
+#include "SPIRIT_Calibration.h"
+#include "SPIRIT_Commands.h"
+#include "SPIRIT_Csma.h"
+#include "SPIRIT_DirectRF.h"
+#include "SPIRIT_General.h"
+#include "SPIRIT_Gpio.h"
+#include "SPIRIT_Irq.h"
+#include "SPIRIT_Timer.h"
+#include "SPIRIT_LinearFifo.h"
+#include "SPIRIT_PktBasic.h"
+#include "SPIRIT_PktMbus.h"
+#include "SPIRIT_PktStack.h"
+
+#include "SPIRIT_Qi.h"
+#include "SPIRIT_Radio.h"
+#include "MCU_Interface.h"
+#include "SPIRIT_Types.h"
+#include "SPIRIT_Management.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @addtogroup SPIRIT_Libraries        SPIRIT Libraries
+ * @brief This firmware implements libraries which allow the user
+ * to manage the features of Spirit without knowing the hardware details.
+ * @details The <i>SPIRIT_Libraries</i> modules are totally platform independent. The library provides one
+ * module for each device feature. Each module refers to some functions whose prototypes are located in the
+ * header file <i>@ref MCU_Interface.h</i>. The user who want to use these libraries on a particular
+ * platform has to implement these functions respecting them signatures.
+ * @{
+ */
+
+/** @defgroup SPIRIT_Configuration      Configuration
+ * @brief Spirit Configuration and useful defines.
+ * @details See the file <i>@ref SPIRIT_Config.h</i> for more details.
+ * @{
+ */
+
+
+/** @defgroup Configuration_Exported_Types      Configuration Exported Types
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Configuration_Exported_Constants  Configuration Exported Constants
+ * @{
+ */
+#define DOUBLE_XTAL_THR                         30000000
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Configuration_Exported_Macros     Configuration Exported Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Configuration_Exported_Functions  Configuration Exported Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Csma.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Csma.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,263 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Csma.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT CSMA.
+ * @details
+ *
+ * The Spirit CSMA feature, when configured and enabled, is transparent
+ * for the user. It means the user has only to call the <i>@ref SpiritCsmaInit()</i>
+ * function on a filled structure and then enable the CSMA policy using the <i>@ref SpiritCsma()</i>
+ * function.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * CsmaInit csmaInit={
+ *   S_DISABLE,         // persistent mode
+ *   TBIT_TIME_64,      // Tbit time
+ *   TCCA_TIME_3,       // Tcca time
+ *   5,                 // max number of backoffs
+ *   0xFA21,            // BU counter seed
+ *   32                 // CU prescaler
+ * };
+ *
+ * ...
+ *
+ * SpiritCsmaInit(&csmaInit);
+ * SpiritCsma(S_ENABLE);
+ *
+ *
+ * @endcode
+ *
+ * @note The CS status depends of the RSSI threshold set. Please see the Spirit_Qi
+ * module for details.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_CSMA_H
+#define __SPIRIT_CSMA_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Types.h"
+#include "SPIRIT_Regs.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Csma        CSMA
+ * @brief Configuration and management of SPIRIT CSMA.
+ * @details See the file <i>@ref SPIRIT_Csma.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Csma_Exported_Types        CSMA Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  Multiplier for Tcca time enumeration (Tcca = Multiplier*Tbit).
+ */
+typedef enum
+{
+  TBIT_TIME_64 = CSMA_CCA_PERIOD_64TBIT,      /*!< CSMA/CA: Sets CCA period to 64*TBIT */
+  TBIT_TIME_128 = CSMA_CCA_PERIOD_128TBIT,    /*!< CSMA/CA: Sets CCA period to 128*TBIT */
+  TBIT_TIME_256 = CSMA_CCA_PERIOD_256TBIT,    /*!< CSMA/CA: Sets CCA period to 256*TBIT */
+  TBIT_TIME_512 = CSMA_CCA_PERIOD_512TBIT,    /*!< CSMA/CA: Sets CCA period to 512*TBIT */
+}CcaPeriod;
+
+#define IS_CCA_PERIOD(PERIOD)   (PERIOD == TBIT_TIME_64 || \
+				 PERIOD == TBIT_TIME_128 || \
+				 PERIOD == TBIT_TIME_256 || \
+				 PERIOD == TBIT_TIME_512)
+
+
+/**
+ * @brief  Multiplier of Tcca time enumeration to obtain Tlisten (Tlisten = [1...15]*Tcca).
+ */
+typedef enum
+{
+  TCCA_TIME_0   = 0x00,     /*!< CSMA/CA: Sets CCA length to 0 */
+  TCCA_TIME_1   = 0x10,     /*!< CSMA/CA: Sets CCA length to 1*TLISTEN */
+  TCCA_TIME_2   = 0x20,     /*!< CSMA/CA: Sets CCA length to 2*TLISTEN */
+  TCCA_TIME_3   = 0x30,     /*!< CSMA/CA: Sets CCA length to 3*TLISTEN */
+  TCCA_TIME_4   = 0x40,     /*!< CSMA/CA: Sets CCA length to 4*TLISTEN */
+  TCCA_TIME_5   = 0x50,     /*!< CSMA/CA: Sets CCA length to 5*TLISTEN */
+  TCCA_TIME_6   = 0x60,     /*!< CSMA/CA: Sets CCA length to 6*TLISTEN */
+  TCCA_TIME_7   = 0x70,     /*!< CSMA/CA: Sets CCA length to 7*TLISTEN */
+  TCCA_TIME_8   = 0x80,     /*!< CSMA/CA: Sets CCA length to 8*TLISTEN */
+  TCCA_TIME_9   = 0x90,     /*!< CSMA/CA: Sets CCA length to 9*TLISTEN */
+  TCCA_TIME_10  = 0xA0,     /*!< CSMA/CA: Sets CCA length to 10*TLISTEN */
+  TCCA_TIME_11  = 0xB0,     /*!< CSMA/CA: Sets CCA length to 11*TLISTEN */
+  TCCA_TIME_12  = 0xC0,     /*!< CSMA/CA: Sets CCA length to 12*TLISTEN */
+  TCCA_TIME_13  = 0xD0,     /*!< CSMA/CA: Sets CCA length to 13*TLISTEN */
+  TCCA_TIME_14  = 0xE0,     /*!< CSMA/CA: Sets CCA length to 14*TLISTEN */
+  TCCA_TIME_15  = 0xF0,     /*!< CSMA/CA: Sets CCA length to 15*TLISTEN */
+}CsmaLength;
+
+#define IS_CSMA_LENGTH(LENGTH)	(LENGTH == TCCA_TIME_0 || \
+                                 LENGTH == TCCA_TIME_1 || \
+				 LENGTH == TCCA_TIME_2 || \
+				 LENGTH == TCCA_TIME_3 || \
+				 LENGTH == TCCA_TIME_4 || \
+				 LENGTH == TCCA_TIME_5 || \
+				 LENGTH == TCCA_TIME_6 || \
+				 LENGTH == TCCA_TIME_7 || \
+				 LENGTH == TCCA_TIME_8 || \
+				 LENGTH == TCCA_TIME_9 || \
+				 LENGTH == TCCA_TIME_10 || \
+				 LENGTH == TCCA_TIME_11 || \
+				 LENGTH == TCCA_TIME_12 || \
+				 LENGTH == TCCA_TIME_13 || \
+				 LENGTH == TCCA_TIME_14 || \
+				 LENGTH == TCCA_TIME_15)
+
+
+/**
+  * @brief  SPIRIT CSMA Init structure definition
+  */
+typedef struct
+{
+  SpiritFunctionalState     xCsmaPersistentMode;          /*!< Specifies if the CSMA persistent mode has to be on or off.
+                                                               This parameter can be S_ENABLE or S_DISABLE */
+  CcaPeriod                 xMultiplierTbit;              /*!< Specifies the Tbit multiplier to obtain the Tcca.
+                                                               This parameter can be a value of @ref CcaPeriod */
+  CsmaLength                xCcaLength;                   /*!< Specifies the Tcca multiplier to determinate the Tlisten.
+                                                               This parameter can be a value of @ref CsmaLength. */
+  uint8_t                   cMaxNb;                       /*!< Specifies the max number of backoff cycles. Not used in persistent mode.
+                                                               This parameter is an uint8_t. */
+  uint16_t                  nBuCounterSeed;               /*!< Specifies the BU counter seed. Not used in persistent mode.
+                                                               This parameter can be a value of 16 bits. */
+  uint8_t                   cBuPrescaler;                 /*!< Specifies the BU prescaler. Not used in persistent mode.
+                                                               This parameter can be a value of 6 bits. */
+}CsmaInit;
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Exported_Constants    CSMA Exported Constants
+ * @{
+ */
+
+/**
+ * @defgroup Csma_Parameters            CSMA Parameters
+ * @{
+ */
+
+#define IS_BU_COUNTER_SEED(SEED)	(SEED!=0)
+#define IS_BU_PRESCALER(PRESCALER)	(PRESCALER<64)
+#define IS_CMAX_NB(NB)			(NB<8)
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Exported_Macros       CSMA Exported Macros
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Exported_Functions    CSMA Exported Functions
+ * @{
+ */
+
+void SpiritCsmaInit(CsmaInit* pxCsmaInit);
+void SpiritCsmaGetInfo(CsmaInit* pxCsmaInit);
+void SpiritCsma(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritCsmaGetCsma(void);
+void SpiritCsmaPersistentMode(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritCsmaGetPersistentMode(void);
+void SpiritCsmaSeedReloadMode(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritCsmaGetSeedReloadMode(void);
+void SpiritCsmaSetBuCounterSeed(uint16_t nBuCounterSeed);
+uint16_t SpiritCsmaGetBuCounterSeed(void);
+void SpiritCsmaSetBuPrescaler(uint8_t cBuPrescaler);
+uint8_t SpiritCsmaGetBuPrescaler(void);
+void SpiritCsmaSetCcaPeriod(CcaPeriod xMultiplierTbit);
+CcaPeriod SpiritCsmaGetCcaPeriod(void);
+void SpiritCsmaSetCcaLength(CsmaLength xCcaLength);
+uint8_t SpiritCsmaGetCcaLength(void);
+void SpiritCsmaSetMaxNumberBackoff(uint8_t cMaxNb);
+uint8_t SpiritCsmaGetMaxNumberBackoff(void);
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_DirectRF.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_DirectRF.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,165 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_DirectRF.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT direct transmission / receive modes.
+ * @details
+ *
+ * This module contains functions to manage the direct Tx/Rx mode.
+ * The user can choose the way to send data to Spirit through the
+ * enumerative types <i>@ref DirectTx</i>/<i>@ref DirectRx</i>.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT1_DIRECT_RF_H
+#define __SPIRIT1_DIRECT_RF_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_DirectRf    Direct RF
+ * @brief Configuration and management of SPIRIT direct transmission / receive modes.
+ * @details See the file <i>@ref SPIRIT_DirectRF.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup DirectRf_Exported_Types    Direct RF Exported Types
+ * @{
+ */
+
+/**
+ * @brief  Direct transmission mode enumeration for SPIRIT.
+ */
+typedef enum
+{
+  NORMAL_TX_MODE = 0x00,          /*!< Normal mode, no direct transmission is used */
+  DIRECT_TX_FIFO_MODE = 0x04,     /*!< Source is FIFO: payload bits are continuously read from the TX FIFO */
+  DIRECT_TX_GPIO_MODE = 0x08,     /*!< Source is GPIO: payload bits are continuously read from one of the GPIO ports and transmitted without any processing */
+  PN9_TX_MODE = 0x0C              /*!< A pseudorandom binary sequence is generated internally */
+}DirectTx;
+
+#define IS_DIRECT_TX(MODE)  (((MODE) == NORMAL_TX_MODE) || \
+			     ((MODE) == DIRECT_TX_FIFO_MODE) || \
+                             ((MODE) == DIRECT_TX_GPIO_MODE)  || \
+                             ((MODE) == PN9_TX_MODE))
+
+/**
+ * @brief  Direct receive mode enumeration for SPIRIT.
+ */
+typedef enum
+{
+  NORMAL_RX_MODE = 0x00,          /*!< Normal mode, no direct reception is used */
+  DIRECT_RX_FIFO_MODE = 0x10,     /*!< Destination is FIFO: payload bits are continuously written to the RX FIFO and not subjected to any processing*/
+  DIRECT_RX_GPIO_MODE = 0x20      /*!< Destination is GPIO: payload bits are continuously written to one of the GPIO ports and not subjected to any processing*/
+}DirectRx;
+
+#define IS_DIRECT_RX(MODE)  (((MODE) == NORMAL_RX_MODE) || \
+		             ((MODE) == DIRECT_RX_FIFO_MODE) || \
+		             ((MODE) == DIRECT_RX_GPIO_MODE))
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Exported_Constants        Direct RF Exported Constants
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Exported_Macros           Direct RF Exported Macros
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Exported_Functions        Direct RF Exported Functions
+ * @{
+ */
+
+void SpiritDirectRfSetRxMode(DirectRx xDirectRx);
+DirectRx SpiritDirectRfGetRxMode(void);
+void SpiritDirectRfSetTxMode(DirectTx xDirectTx);
+DirectTx SpiritDirectRfGetTxMode(void);
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_General.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_General.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,227 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_General.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT General functionalities.
+ * @details
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_GENERAL_H
+#define __SPIRIT_GENERAL_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_General     General
+ * @brief Configuration and management of SPIRIT General functionalities.
+ * @details See the file <i>@ref SPIRIT_General.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup General_Exported_Types     General Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  SPIRIT ModeExtRef enumeration
+ */
+
+typedef enum
+{
+  MODE_EXT_XO = 0,
+  MODE_EXT_XIN = !MODE_EXT_XO
+} ModeExtRef;
+
+#define IS_MODE_EXT(MODE)   (MODE == MODE_EXT_XO || \
+                             MODE == MODE_EXT_XIN)
+
+
+/**
+ * @brief  SPIRIT BatteryLevel enumeration
+ */
+
+typedef enum
+{
+  BLD_LVL_2_7_V = 0,
+  BLD_LVL_2_5_V = 1,
+  BLD_LVL_2_3_V = 2,
+  BLD_LVL_2_1_V = 3
+} BatteryLevel;
+
+#define IS_BLD_LVL(MODE)  (MODE == BLD_LVL_2_7_V || \
+                           MODE == BLD_LVL_2_5_V || \
+                           MODE == BLD_LVL_2_3_V || \
+                           MODE == BLD_LVL_2_1_V)
+
+
+/**
+ * @brief  SPIRIT GmConf enumeration
+ */
+
+typedef enum
+{
+  GM_SU_13_2 = 0,
+  GM_SU_18_2,
+  GM_SU_21_5,
+  GM_SU_25_6,
+  GM_SU_28_8,
+  GM_SU_33_9,
+  GM_SU_38_5,
+  GM_SU_43_0
+} GmConf;
+
+#define IS_GM_CONF(MODE)    (MODE == GM_SU_13_2 || \
+                             MODE == GM_SU_18_2 || \
+                             MODE == GM_SU_21_5 || \
+                             MODE == GM_SU_25_6 || \
+                             MODE == GM_SU_28_8 || \
+                             MODE == GM_SU_33_9 || \
+                             MODE == GM_SU_38_5 || \
+                             MODE == GM_SU_43_0)
+
+
+/**
+ * @brief  SPIRIT packet type enumeration
+ */
+
+typedef enum
+{
+  PKT_BASIC = 0x00,
+  PKT_MBUS = 0x02,
+  PKT_STACK
+
+} PacketType;
+
+#define IS_PKT_TYPE(TYPE)    (TYPE == PKT_BASIC || \
+                             TYPE == PKT_MBUS || \
+                             TYPE == PKT_STACK || \
+                             )
+
+
+/**
+ * @brief  SPIRIT version type enumeration
+ */
+
+typedef enum
+{
+  SPIRIT_VERSION_2_1 = 0x01,    /* Deprecated */
+  SPIRIT_VERSION_3_0,           /* The only version of SPIRIT1 */
+} SpiritVersion;
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup General_Exported_Constants         General Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup General_Exported_Macros            General Exported Macros
+ * @{
+ */
+#define SpiritGeneralLibraryVersion() "Spirit1_Libraries_v.3.2.0"
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup General_Exported_Functions         General Exported Functions
+ * @{
+ */
+
+
+void SpiritGeneralBatteryLevel(SpiritFunctionalState xNewState);
+void SpiritGeneralSetBatteryLevel(BatteryLevel xBatteryLevel);
+BatteryLevel SpiritGeneralGetBatteryLevel(void);
+void SpiritGeneralBrownOut(SpiritFunctionalState xNewState);
+void SpiritGeneralHighPwr(SpiritFunctionalState xNewState);
+void SpiritGeneralSetExtRef(ModeExtRef xExtMode);
+ModeExtRef SpiritGeneralGetExtRef(void);
+void SpiritGeneralSetXoGm(GmConf xGm);
+GmConf SpiritGeneralGetXoGm(void);
+PacketType SpiritGeneralGetPktType(void);
+uint16_t SpiritGeneralGetDevicePartNumber(void);
+uint8_t SpiritGeneralGetSpiritVersion(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Gpio.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Gpio.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,405 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Gpio.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   This file provides all the low level API to manage SPIRIT GPIO.
+  * 
+ * @details
+ *
+ * This module can be used to configure the Spirit GPIO pins to perform
+ * specific functions.
+ * The structure <i>@ref gpioIRQ</i> can be used to specify these features for
+ * one of the four Spirit Gpio pin.
+ * The following example shows how to configure a pin (GPIO 3) to be used as an IRQ source
+ * for a microcontroller using the <i>@ref SpiritGpioInit()</i> function.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * SGpioInit gpioIRQ={
+ *   SPIRIT_GPIO_3,
+ *   SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP,
+ *   SPIRIT_GPIO_DIG_OUT_IRQ
+ * };
+ *
+ * ...
+ *
+ * SpiritGpioInit(&gpioIRQ);
+ *
+ * @endcode
+ *
+ * @note Please read the functions documentation for the other GPIO features.
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_GPIO_H
+#define __SPIRIT_GPIO_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/** @defgroup SPIRIT_Gpio       GPIO
+ * @brief Configuration and management of SPIRIT GPIO.
+ * @details See the file <i>@ref SPIRIT_Gpio.h</i> for more details.
+ * @{
+ */
+
+
+
+/** @defgroup Gpio_Exported_Types       GPIO Exported Types
+ * @{
+ */
+
+/**
+ * @brief  SPIRIT GPIO pin enumeration.
+ */
+typedef enum
+{
+  SPIRIT_GPIO_0  = GPIO0_CONF_BASE, /*!< GPIO_0 selected */
+  SPIRIT_GPIO_1  = GPIO1_CONF_BASE, /*!< GPIO_1 selected */
+  SPIRIT_GPIO_2  = GPIO2_CONF_BASE, /*!< GPIO_2 selected */
+  SPIRIT_GPIO_3  = GPIO3_CONF_BASE  /*!< GPIO_3 selected */
+}SpiritGpioPin;
+
+
+#define IS_SPIRIT_GPIO(PIN)  ((PIN == SPIRIT_GPIO_0) || \
+                              (PIN == SPIRIT_GPIO_1) || \
+                              (PIN == SPIRIT_GPIO_2) || \
+                              (PIN == SPIRIT_GPIO_3))
+
+
+/**
+ * @brief  SPIRIT GPIO mode enumeration.
+ */
+typedef enum
+{
+  SPIRIT_GPIO_MODE_DIGITAL_INPUT      = 0x01, /*!< Digital Input on GPIO */
+  SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP  = 0x02, /*!< Digital Output on GPIO (low current) */
+  SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP  = 0x03  /*!< Digital Output on GPIO (high current) */
+}SpiritGpioMode;
+
+#define IS_SPIRIT_GPIO_MODE(MODE)   ((MODE == SPIRIT_GPIO_MODE_DIGITAL_INPUT) || \
+                                     (MODE == SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP) || \
+                                     (MODE == SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP))
+
+
+
+/**
+ * @brief  SPIRIT I/O selection enumeration.
+ */
+typedef enum
+{
+  SPIRIT_GPIO_DIG_OUT_IRQ                               = 0x00, /*!< nIRQ (Interrupt Request, active low) , default configuration after POR */
+  SPIRIT_GPIO_DIG_OUT_POR_INV                           = 0x08, /*!< POR inverted (active low) */
+  SPIRIT_GPIO_DIG_OUT_WUT_EXP                           = 0x10, /*!< Wake-Up Timer expiration: "1" when WUT has expired */
+  SPIRIT_GPIO_DIG_OUT_LBD                               = 0x18, /*!< Low battery detection: "1" when battery is below threshold setting */
+  SPIRIT_GPIO_DIG_OUT_TX_DATA                           = 0x20, /*!< TX data internal clock output (TX data are sampled on the rising edge of it) */
+  SPIRIT_GPIO_DIG_OUT_TX_STATE                          = 0x28, /*!< TX state indication: "1" when Spirit1 is passing in the TX state */
+  SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_EMPTY              = 0x30, /*!< TX FIFO Almost Empty Flag */
+  SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_FULL               = 0x38, /*!< TX FIFO Almost Full Flag */
+  SPIRIT_GPIO_DIG_OUT_RX_DATA                           = 0x40, /*!< RX data output */
+  SPIRIT_GPIO_DIG_OUT_RX_CLOCK                          = 0x48, /*!< RX clock output (recovered from received data) */
+  SPIRIT_GPIO_DIG_OUT_RX_STATE                          = 0x50, /*!< RX state indication: "1" when Spirit1 is passing in the RX state */
+  SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_FULL               = 0x58, /*!< RX FIFO Almost Full Flag */
+  SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_EMPTY              = 0x60, /*!< RX FIFO Almost Empty Flag */
+  SPIRIT_GPIO_DIG_OUT_ANTENNA_SWITCH                    = 0x68, /*!< Antenna switch used for antenna diversity  */
+  SPIRIT_GPIO_DIG_OUT_VALID_PREAMBLE                    = 0x70, /*!< Valid Preamble Detected Flag */
+  SPIRIT_GPIO_DIG_OUT_SYNC_DETECTED                     = 0x78, /*!< Sync WordSync Word Detected Flag */
+  SPIRIT_GPIO_DIG_OUT_RSSI_THRESHOLD                    = 0x80, /*!< RSSI above threshold */
+  SPIRIT_GPIO_DIG_OUT_MCU_CLOCK                         = 0x88, /*!< MCU Clock */
+  SPIRIT_GPIO_DIG_OUT_TX_RX_MODE                        = 0x90, /*!< TX or RX mode indicator (to enable an external range extender) */
+  SPIRIT_GPIO_DIG_OUT_VDD                               = 0x98, /*!< VDD (to emulate an additional GPIO of the MCU, programmable by SPI) */
+  SPIRIT_GPIO_DIG_OUT_GND                               = 0xA0, /*!< GND (to emulate an additional GPIO of the MCU, programmable by SPI) */
+  SPIRIT_GPIO_DIG_OUT_SMPS_EXT                          = 0xA8, /*!< External SMPS enable signal (active high) */
+  SPIRIT_GPIO_DIG_OUT_SLEEP_OR_STANDBY                  = 0xB0,
+  SPIRIT_GPIO_DIG_OUT_READY                             = 0xB8,
+  SPIRIT_GPIO_DIG_OUT_LOCK                              = 0xC0,
+  SPIRIT_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG                 = 0xC8,
+  SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_LOCK           = 0xD0,
+  SPIRIT_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG               = 0xD8,
+  SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET         = 0xE0,
+  SPIRIT_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION              = 0xE8,
+  SPIRIT_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT         = 0xF0,
+  SPIRIT_GPIO_DIG_OUT_WAIT_FOR_RCCAL_OK_SIG             = 0xFF,
+
+  SPIRIT_GPIO_DIG_IN_TX_COMMAND                         = 0x00,
+  SPIRIT_GPIO_DIG_IN_RX_COMMAND                         = 0x08,
+  SPIRIT_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF         = 0x10,
+  SPIRIT_GPIO_DIG_IN_DATA_WAKEUP                        = 0x18,
+  SPIRIT_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ               = 0x20
+
+}SpiritGpioIO;
+
+#define IS_SPIRIT_GPIO_IO(IO_SEL)        ((IO_SEL == SPIRIT_GPIO_DIG_OUT_IRQ) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_POR_INV) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WUT_EXP) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_LBD) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_TX_DATA) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_TX_STATE) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_EMPTY) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_FULL) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RX_DATA) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RX_CLOCK) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RX_STATE) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_FULL) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_EMPTY) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_ANTENNA_SWITCH) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_VALID_PREAMBLE) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_SYNC_DETECTED) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_RSSI_THRESHOLD) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_MCU_CLOCK) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_TX_RX_MODE) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_VDD) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_GND) || \
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_SMPS_EXT) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_SLEEP_OR_STANDBY) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_READY) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_LOCK) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_LOCK) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_RCCAL_OK_SIG) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_IN_TX_COMMAND) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_IN_RX_COMMAND) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_IN_DATA_WAKEUP) ||\
+                                          (IO_SEL == SPIRIT_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ))
+
+/**
+ * @brief  SPIRIT OutputLevel enumeration.
+ */
+
+typedef enum
+{
+  LOW = 0,
+  HIGH = !LOW
+}OutputLevel;
+
+#define IS_SPIRIT_GPIO_LEVEL(LEVEL)      ((LEVEL == LOW) || \
+                                          (LEVEL == HIGH))
+
+
+/**
+ * @brief  SPIRIT GPIO Init structure definition.
+ */
+typedef struct
+{
+  SpiritGpioPin xSpiritGpioPin;    /*!< Specifies the GPIO pins to be configured.
+                                        This parameter can be any value of @ref SpiritGpioPin */
+
+  SpiritGpioMode xSpiritGpioMode;  /*!< Specifies the operating mode for the selected pins.
+                                        This parameter can be a value of @ref SpiritGpioMode */
+
+  SpiritGpioIO xSpiritGpioIO;      /*!< Specifies the I/O selection for the selected pins.
+                                        This parameter can be a value of @ref SpiritGpioIO */
+
+}SGpioInit;
+
+
+
+/**
+ * @brief  SPIRIT clock output XO prescaler enumeration.
+ */
+
+typedef enum
+{
+ XO_RATIO_1     = 0x00, /*!< XO Clock signal available on the GPIO divided by 1     */
+ XO_RATIO_2_3	= 0x02, /*!< XO Clock signal available on the GPIO divided by 2/3   */
+ XO_RATIO_1_2	= 0x04, /*!< XO Clock signal available on the GPIO divided by 1/2   */
+ XO_RATIO_1_3	= 0x06, /*!< XO Clock signal available on the GPIO divided by 1/3   */
+ XO_RATIO_1_4	= 0x08, /*!< XO Clock signal available on the GPIO divided by 1/4   */
+ XO_RATIO_1_6	= 0x0A, /*!< XO Clock signal available on the GPIO divided by 1/6   */
+ XO_RATIO_1_8	= 0x0C, /*!< XO Clock signal available on the GPIO divided by 1/8   */
+ XO_RATIO_1_12	= 0x0E, /*!< XO Clock signal available on the GPIO divided by 1/12  */
+ XO_RATIO_1_16	= 0x10, /*!< XO Clock signal available on the GPIO divided by 1/16  */
+ XO_RATIO_1_24	= 0x12, /*!< XO Clock signal available on the GPIO divided by 1/24  */
+ XO_RATIO_1_36	= 0x14, /*!< XO Clock signal available on the GPIO divided by 1/36  */
+ XO_RATIO_1_48	= 0x16, /*!< XO Clock signal available on the GPIO divided by 1/48  */
+ XO_RATIO_1_64	= 0x18, /*!< XO Clock signal available on the GPIO divided by 1/64  */
+ XO_RATIO_1_96	= 0x1A, /*!< XO Clock signal available on the GPIO divided by 1/96  */
+ XO_RATIO_1_128	= 0x1C, /*!< XO Clock signal available on the GPIO divided by 1/128 */
+ XO_RATIO_1_192	= 0x1E  /*!< XO Clock signal available on the GPIO divided by 1/196 */
+}ClockOutputXOPrescaler;
+
+#define IS_SPIRIT_CLOCK_OUTPUT_XO(RATIO) ((RATIO == XO_RATIO_1) || \
+                                           (RATIO == XO_RATIO_2_3) || \
+                                           (RATIO == XO_RATIO_1_2) || \
+                                           (RATIO == XO_RATIO_1_3) || \
+                                           (RATIO == XO_RATIO_1_4) || \
+                                           (RATIO == XO_RATIO_1_6) || \
+                                           (RATIO == XO_RATIO_1_8) || \
+                                           (RATIO == XO_RATIO_1_12) || \
+                                           (RATIO == XO_RATIO_1_16) || \
+                                           (RATIO == XO_RATIO_1_24) || \
+                                           (RATIO == XO_RATIO_1_36) || \
+                                           (RATIO == XO_RATIO_1_48) || \
+                                           (RATIO == XO_RATIO_1_64) || \
+                                           (RATIO == XO_RATIO_1_96) || \
+                                           (RATIO == XO_RATIO_1_128) || \
+                                           (RATIO == XO_RATIO_1_192))
+
+/**
+ * @brief  SPIRIT Clock Output RCO prescaler enumeration.
+ */
+
+typedef enum
+{
+ RCO_RATIO_1              = 0x00, /*!< RCO Clock signal available on the GPIO divided by 1     */
+ RCO_RATIO_1_128	  = 0x01  /*!< RCO Clock signal available on the GPIO divided by 1/128   */
+}ClockOutputRCOPrescaler;
+
+#define IS_SPIRIT_CLOCK_OUTPUT_RCO(RATIO) ((RATIO == RCO_RATIO_1) || \
+                                           (RATIO == RCO_RATIO_1_128))
+
+/**
+ * @brief  SPIRIT ExtraClockCycles enumeration.
+ */
+
+typedef enum
+{
+EXTRA_CLOCK_CYCLES_0	= 0x00, /*!< 0   extra clock cycles provided to the MCU before switching to STANDBY state */
+EXTRA_CLOCK_CYCLES_64	= 0x20, /*!< 64  extra clock cycles provided to the MCU before switching to STANDBY state */
+EXTRA_CLOCK_CYCLES_256	= 0x40, /*!< 256 extra clock cycles provided to the MCU before switching to STANDBY state */
+EXTRA_CLOCK_CYCLES_512	= 0x60  /*!< 512 extra clock cycles provided to the MCU before switching to STANDBY state */
+}ExtraClockCycles;
+
+#define IS_SPIRIT_CLOCK_OUTPUT_EXTRA_CYCLES(CYCLES) ((CYCLES == EXTRA_CLOCK_CYCLES_0) || \
+                                                      (CYCLES == EXTRA_CLOCK_CYCLES_64) || \
+                                                      (CYCLES == EXTRA_CLOCK_CYCLES_256) || \
+                                                      (CYCLES == EXTRA_CLOCK_CYCLES_512))
+
+
+/**
+ * @brief  SPIRIT Clock Output initialization structure definition.
+ */
+typedef struct
+{
+  ClockOutputXOPrescaler   xClockOutputXOPrescaler;  /*!< Specifies the XO Ratio as clock output.
+                                                          This parameter can be any value of @ref ClockOutputXOPrescaler */
+
+  ClockOutputRCOPrescaler  xClockOutputRCOPrescaler; /*!< Specifies the RCO Ratio as clock output.
+                                                          This parameter can be a value of @ref ClockOutputRCOPrescaler */
+
+  ExtraClockCycles         xExtraClockCycles;       /*!< Specifies the Extra Clock Cycles provided before entering in Standby State.
+                                                          This parameter can be a value of @ref ExtraClockCycles */
+
+}ClockOutputInit;
+
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Exported_Constants   GPIO Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Exported_Macros      GPIO Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Exported_Functions   GPIO Exported Functions
+ * @{
+ */
+
+void SpiritGpioInit(SGpioInit* pxGpioInitStruct);
+void SpiritGpioTemperatureSensor(SpiritFunctionalState xNewState);
+void SpiritGpioSetLevel(SpiritGpioPin xGpioX, OutputLevel xLevel);
+OutputLevel SpiritGpioGetLevel(SpiritGpioPin xGpioX);
+void SpiritGpioClockOutput(SpiritFunctionalState xNewState);
+void SpiritGpioClockOutputInit(ClockOutputInit* pxClockOutputInitStruct);
+void SpiritGpioSetXOPrescaler(ClockOutputXOPrescaler xXOPrescaler);
+ClockOutputXOPrescaler SpiritGpioGetXOPrescaler(void);
+void SpiritGpioSetRCOPrescaler(ClockOutputRCOPrescaler xRCOPrescaler);
+ClockOutputRCOPrescaler SpiritGpioGetRCOPrescaler(void);
+void SpiritGpioSetExtraClockCycles(ExtraClockCycles xExtraCycles);
+ExtraClockCycles SpiritGpioGetExtraClockCycles(void);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Irq.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Irq.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,357 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Irq.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT IRQs.
+  * 
+ * @details
+ *
+ * On the Spirit side specific IRQs can be enabled by setting a specific bitmask.
+ * The Spirit libraries allow the user to do this in two different ways:
+ * <ul>
+ *
+ * <li>The first enables the IRQs one by one, i.e. using an SPI transaction for each
+ * IRQ to enable.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritIrqDeInit(NULL);                // this call is used to reset the IRQ mask registers
+ *  SpiritIrq(RX_DATA_READY , S_ENABLE);
+ *  SpiritIrq(VALID_SYNC , S_ENABLE);
+ *  SpiritIrq(RX_TIMEOUT , S_ENABLE);
+ *
+ * @endcode
+ *
+ * </li>
+ *
+ * <li>The second strategy is to set the IRQ bitfields structure. So, during the initialization the user
+ * has to fill the @ref SpiritIrqs structure setting to one the single field related to the IRQ he
+ * wants to enable, and to zero the single field related to all the IRQs he wants to disable.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritIrqs irqMask;
+ *
+ *  ...
+ *
+ *  SpiritIrqDeInit(&irqMask);                // this call is used to reset the IRQ mask registers
+ *                                            // and to set to 0x00000000 the irq mask in order to disable
+ *                                            // all IRQs (disabled by default on startup)
+ *  irqMask.IRQ_RX_DATA_READY = 1;
+ *  irqMask.IRQ_VALID_SYNC = 1;
+ *  irqMask.IRQ_RX_TIMEOUT = 1;
+ *
+ *  ...
+ * @endcode
+ * </li>
+ * </ul>
+ *
+ * The most applications will require a Spirit IRQ notification on an microcontroller EXTI line.
+ * Then, the user can check which IRQ has been raised using two different ways.
+ *
+ * On the ISR of the EXTI line phisically linked to the Spirit pin configured for IRQ:
+ *
+ * <ul>
+ * <li> Check <b>only one</b> Spirit IRQ (because the Spirit IRQ status register automatically blanks itself
+ * after an SPI reading) into the ISR.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  if(SpiritIrqCheckFlag(RX_DATA_READY))
+ *  {
+ *          // do something...
+ *  }
+ *
+ * @endcode
+ * </li>
+ *
+ * <li> Check more than one Spirit IRQ status by storing the entire IRQ status registers into a bitfields <i>@ref SpiritIrqs</i> structure
+ * and then check the interested bits.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritIrqGetStatus(&irqStatus);
+ *
+ *  if(irqStatus.IRQ_RX_DATA_READY)
+ *  {
+ *          // do something...
+ *  }
+ *  if(irqStatus.IRQ_VALID_SYNC)
+ *  {
+ *         // do something...
+ *  }
+ *  if(irqStatus.RX_TIMEOUT)
+ *  {
+ *         // do something...
+ *  }
+ *
+ * @endcode
+ * </li>
+ * </ul>
+ *
+
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT1_IRQ_H
+#define __SPIRIT1_IRQ_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Irq IRQ
+ * @brief Configuration and management of SPIRIT IRQs.
+ * @details See the file <i>@ref SPIRIT_Irq.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Irq_Exported_Types IRQ Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief IRQ bitfield structure for SPIRIT. This structure is used to read or write the single IRQ bit.
+ *        During the initialization the user has to fill this structure setting to one the single field related
+ *        to the IRQ he wants to enable, and to zero the single field related to all the IRQs he wants to disable.
+ *        The same structure can be used to retrieve all the IRQ events from the IRQ registers IRQ_STATUS[3:0],
+ *        and read if one or more specific IRQ raised.
+ * @note  The fields order in the structure depends on used endianness (little or big
+ *        endian). The actual definition is valid ONLY for LITTLE ENDIAN mode. Be sure to
+ *        change opportunely the fields order when use a different endianness.
+ */
+typedef struct
+{
+	  SpiritFlagStatus  IRQ_SYNTH_LOCK_TIMEOUT:1;       /*!< IRQ: only for debug; LOCK state timeout */
+	  SpiritFlagStatus  IRQ_SYNTH_LOCK_STARTUP:1;       /*!< IRQ: only for debug; see CALIBR_START_COUNTER */
+	  SpiritFlagStatus  IRQ_SYNTH_CAL_TIMEOUT:1;        /*!< IRQ: only for debug; SYNTH calibration timeout */
+	  SpiritFlagStatus  IRQ_TX_START_TIME:1;            /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */
+	  SpiritFlagStatus  IRQ_RX_START_TIME:1;            /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */
+	  SpiritFlagStatus  IRQ_RX_TIMEOUT:1;               /*!< IRQ: RX operation timeout */
+	  SpiritFlagStatus  IRQ_AES_END:1;                  /*!< IRQ: AES End of operation */
+	  SpiritFlagStatus  reserved:1;                     /*!< Reserved bit */
+
+	  SpiritFlagStatus  IRQ_READY:1;                    /*!< IRQ: READY state */
+	  SpiritFlagStatus  IRQ_STANDBY_DELAYED:1;          /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */
+	  SpiritFlagStatus  IRQ_LOW_BATT_LVL:1;             /*!< IRQ: Battery level below threshold*/
+	  SpiritFlagStatus  IRQ_POR:1;                      /*!< IRQ: Power On Reset */
+	  SpiritFlagStatus  IRQ_BOR:1;                      /*!< IRQ: Brown out event (both accurate and inaccurate)*/
+	  SpiritFlagStatus  IRQ_LOCK:1;                     /*!< IRQ: LOCK state */
+	  SpiritFlagStatus  IRQ_PM_COUNT_EXPIRED:1;         /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */
+	  SpiritFlagStatus  IRQ_XO_COUNT_EXPIRED:1;         /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */
+
+	  SpiritFlagStatus  IRQ_TX_FIFO_ALMOST_EMPTY:1;     /*!< IRQ: TX FIFO almost empty */
+	  SpiritFlagStatus  IRQ_RX_FIFO_ALMOST_FULL:1;      /*!< IRQ: RX FIFO almost full */
+	  SpiritFlagStatus  IRQ_RX_FIFO_ALMOST_EMPTY:1;     /*!< IRQ: RX FIFO almost empty  */
+	  SpiritFlagStatus  IRQ_MAX_BO_CCA_REACH:1;         /*!< IRQ: Max number of back-off during CCA */
+	  SpiritFlagStatus  IRQ_VALID_PREAMBLE:1;           /*!< IRQ: Valid preamble detected */
+	  SpiritFlagStatus  IRQ_VALID_SYNC:1;               /*!< IRQ: Sync word detected */
+	  SpiritFlagStatus  IRQ_RSSI_ABOVE_TH:1;            /*!< IRQ: RSSI above threshold */
+	  SpiritFlagStatus  IRQ_WKUP_TOUT_LDC:1;            /*!< IRQ: Wake-up timeout in LDC mode */
+
+	  SpiritFlagStatus  IRQ_RX_DATA_READY:1;            /*!< IRQ: RX data ready */
+	  SpiritFlagStatus  IRQ_RX_DATA_DISC:1;             /*!< IRQ: RX data discarded (upon filtering) */
+	  SpiritFlagStatus  IRQ_TX_DATA_SENT:1;             /*!< IRQ: TX data sent */
+	  SpiritFlagStatus  IRQ_MAX_RE_TX_REACH:1;          /*!< IRQ: Max re-TX reached */
+	  SpiritFlagStatus  IRQ_CRC_ERROR:1;                /*!< IRQ: CRC error */
+	  SpiritFlagStatus  IRQ_TX_FIFO_ERROR:1;            /*!< IRQ: TX FIFO underflow/overflow error */
+	  SpiritFlagStatus  IRQ_RX_FIFO_ERROR:1;            /*!< IRQ: RX FIFO underflow/overflow error */
+	  SpiritFlagStatus  IRQ_TX_FIFO_ALMOST_FULL:1;      /*!< IRQ: TX FIFO almost full */
+} SpiritIrqs;
+
+// betzw: uint32_t masks
+#define IRQ_TX_FIFO_ALMOST_EMPTY_MASK	(0x00010000) /* (1<<16) */
+#define IRQ_RX_FIFO_ALMOST_FULL_MASK	(0x00020000) /* (1<<17) */
+#define IRQ_VALID_SYNC_MASK				(0x00200000) /* (1<<21) */
+#define IRQ_RX_DATA_READY_MASK			(0x01000000) /* (1<<24) */
+#define IRQ_RX_DATA_DISC_MASK			(0x02000000) /* (1<<25) */
+#define IRQ_TX_DATA_SENT_MASK			(0x04000000) /* (1<<26) */
+#define IRQ_TX_FIFO_ERROR_MASK			(0x20000000) /* (1<<29) */
+#define IRQ_RX_FIFO_ERROR_MASK			(0x40000000) /* (1<<30) */
+
+/**
+ * @brief  IRQ list enumeration for SPIRIT. This enumeration type can be used to address a
+ *         specific IRQ.
+ */
+typedef enum
+{
+  RX_DATA_READY = 0x00000001,           /*!< IRQ: RX data ready */
+  RX_DATA_DISC = 0x00000002,            /*!< IRQ: RX data discarded (upon filtering) */
+  TX_DATA_SENT = 0x00000004,            /*!< IRQ: TX data sent */
+  MAX_RE_TX_REACH = 0x00000008,         /*!< IRQ: Max re-TX reached */
+  CRC_ERROR = 0x00000010,               /*!< IRQ: CRC error */
+  TX_FIFO_ERROR = 0x00000020,           /*!< IRQ: TX FIFO underflow/overflow error */
+  RX_FIFO_ERROR = 0x00000040,           /*!< IRQ: RX FIFO underflow/overflow error */
+  TX_FIFO_ALMOST_FULL = 0x00000080,     /*!< IRQ: TX FIFO almost full */
+  TX_FIFO_ALMOST_EMPTY = 0x00000100,    /*!< IRQ: TX FIFO almost empty */
+  RX_FIFO_ALMOST_FULL = 0x00000200,     /*!< IRQ: RX FIFO almost full */
+  RX_FIFO_ALMOST_EMPTY = 0x00000400,    /*!< IRQ: RX FIFO almost empty  */
+  MAX_BO_CCA_REACH = 0x00000800,        /*!< IRQ: Max number of back-off during CCA */
+  VALID_PREAMBLE = 0x00001000,          /*!< IRQ: Valid preamble detected */
+  VALID_SYNC = 0x00002000,              /*!< IRQ: Sync word detected */
+  RSSI_ABOVE_TH = 0x00004000,           /*!< IRQ: RSSI above threshold */
+  WKUP_TOUT_LDC = 0x00008000,           /*!< IRQ: Wake-up timeout in LDC mode */
+  READY = 0x00010000,                   /*!< IRQ: READY state */
+  STANDBY_DELAYED = 0x00020000,         /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */
+  LOW_BATT_LVL = 0x00040000,            /*!< IRQ: Battery level below threshold*/
+  POR = 0x00080000,                     /*!< IRQ: Power On Reset */
+  BOR = 0x00100000,                     /*!< IRQ: Brown out event (both accurate and inaccurate)*/
+  LOCK = 0x00200000,                    /*!< IRQ: LOCK state */
+  PM_COUNT_EXPIRED = 0x00400000,        /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */
+  XO_COUNT_EXPIRED = 0x00800000,        /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */
+  SYNTH_LOCK_TIMEOUT = 0x01000000,      /*!< IRQ: only for debug; LOCK state timeout */
+  SYNTH_LOCK_STARTUP = 0x02000000,      /*!< IRQ: only for debug; see CALIBR_START_COUNTER */
+  SYNTH_CAL_TIMEOUT = 0x04000000,       /*!< IRQ: only for debug; SYNTH calibration timeout */
+  TX_START_TIME = 0x08000000,	        /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */
+  RX_START_TIME = 0x10000000,	        /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */
+  RX_TIMEOUT = 0x20000000,	        /*!< IRQ: RX operation timeout */
+  AES_END = 0x40000000,                 /*!< IRQ: AES End of operation */
+  ALL_IRQ = 0x7FFFFFFF			/*!< All the above mentioned IRQs */
+
+} IrqList;
+
+#define IS_SPIRIT_IRQ_LIST(VALUE)   ((VALUE == RX_DATA_READY) || \
+                                     (VALUE == RX_DATA_DISC)  || \
+                                     (VALUE == TX_DATA_SENT)  || \
+                                     (VALUE == MAX_RE_TX_REACH)  || \
+                                     (VALUE == CRC_ERROR)  || \
+                                     (VALUE == TX_FIFO_ERROR)  || \
+                                     (VALUE == RX_FIFO_ERROR)  || \
+                                     (VALUE == TX_FIFO_ALMOST_FULL)  || \
+                                     (VALUE == TX_FIFO_ALMOST_EMPTY)  || \
+                                     (VALUE == RX_FIFO_ALMOST_FULL)  || \
+                                     (VALUE == RX_FIFO_ALMOST_EMPTY)  || \
+                                     (VALUE == MAX_BO_CCA_REACH)  || \
+                                     (VALUE == VALID_PREAMBLE)  || \
+                                     (VALUE == VALID_SYNC)  || \
+                                     (VALUE == RSSI_ABOVE_TH)  || \
+                                     (VALUE == WKUP_TOUT_LDC)  || \
+                                     (VALUE == READY)  || \
+                                     (VALUE == STANDBY_DELAYED)  || \
+                                     (VALUE == LOW_BATT_LVL)  || \
+                                     (VALUE == POR)  || \
+                                     (VALUE == BOR)  || \
+                                     (VALUE == LOCK)  || \
+                                     (VALUE == PM_COUNT_EXPIRED)  || \
+                                     (VALUE == XO_COUNT_EXPIRED)  || \
+                                     (VALUE == SYNTH_LOCK_TIMEOUT)  || \
+                                     (VALUE == SYNTH_LOCK_STARTUP)  || \
+                                     (VALUE == SYNTH_CAL_TIMEOUT)  || \
+                                     (VALUE == TX_START_TIME)  || \
+                                     (VALUE == RX_START_TIME)  || \
+                                     (VALUE == RX_TIMEOUT)  || \
+                                     (VALUE == AES_END)   || \
+				     (VALUE == ALL_IRQ ))
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Irq_Exported_Constants     IRQ Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Irq_Exported_Macros        IRQ Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Irq_Exported_Functions     IRQ Exported Functions
+ * @{
+ */
+
+void SpiritIrqDeInit(SpiritIrqs* pxIrqInit);
+void SpiritIrqInit(SpiritIrqs* pxIrqInit);
+void SpiritIrq(IrqList xIrq, SpiritFunctionalState xNewState);
+void SpiritIrqGetMask(SpiritIrqs* pxIrqMask);
+void SpiritIrqGetStatus(SpiritIrqs* pxIrqStatus);
+void SpiritIrqClearStatus(void);
+SpiritBool SpiritIrqCheckFlag(IrqList xFlag);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_LinearFifo.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_LinearFifo.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,136 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_LinearFifo.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT Fifo.
+ * @details
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+ *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_LINEAR_FIFO_H
+#define __SPIRIT_LINEAR_FIFO_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_LinearFifo          Linear FIFO
+ * @brief Configuration and management of SPIRIT FIFO.
+ * @details See the file <i>@ref SPIRIT_LinearFifo.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup LinearFifo_Exported_Types  Linear FIFO Exported Types
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Exported_Constants      Linear FIFO Exported Constants
+ * @{
+ */
+#define IS_FIFO_THR(VAL)  (VAL<=96)
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Exported_Macros         Linear FIFO Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Exported_Functions                      Linear FIFO Exported Functions
+ * @{
+ */
+
+uint8_t SpiritLinearFifoReadNumElementsRxFifo(void);
+uint8_t SpiritLinearFifoReadNumElementsTxFifo(void);
+void SpiritLinearFifoSetAlmostFullThresholdRx(uint8_t cThrRxFifo);
+uint8_t SpiritLinearFifoGetAlmostFullThresholdRx(void);
+void SpiritLinearFifoSetAlmostEmptyThresholdRx(uint8_t cThrRxFifo);
+uint8_t SpiritLinearFifoGetAlmostEmptyThresholdRx(void);
+void SpiritLinearFifoSetAlmostFullThresholdTx(uint8_t cThrTxFifo);
+uint8_t SpiritLinearFifoGetAlmostFullThresholdTx(void);
+void SpiritLinearFifoSetAlmostEmptyThresholdTx(uint8_t cThrTxFifo);
+uint8_t SpiritLinearFifoGetAlmostEmptyThresholdTx(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Management.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Management.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,100 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Management.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   The management layer for SPIRIT1 library.
+ * @details
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 SPIRIT_MANAGEMENT_H_
+#define SPIRIT_MANAGEMENT_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Config.h"
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_MANAGEMENT          Management
+ * @brief Workarounds for Spirit1.
+ * @details See the file <i>@ref SPIRIT_Management.h</i> for more details.
+ * @{
+ */
+
+
+/**
+ * @addgroup SPIRIT_MANAGEMENT_FUNCTIONS
+ * @{
+ */
+
+   
+
+
+uint8_t SpiritManagementWaVcoCalibration(void);
+void SpiritManagementWaCmdStrobeTx(void);
+void SpiritManagementWaCmdStrobeRx(void);
+void SpiritManagementWaTRxFcMem(uint32_t nDesiredFreq);
+void SpiritManagementWaExtraCurrent(void);
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+
+ /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktBasic.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktBasic.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,696 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_PktBasic.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT Basic packets.
+  * 
+ * @details
+ *
+ * This module can be used to manage the configuration of Spirit Basic
+ * packets.
+ * The user can obtain a packet configuration filling the structure
+ * <i>@ref PktBasicInit</i>, defining in it some general parameters
+ * for the Spirit Basic packet format.
+ * Another structure the user can fill is <i>@ref PktBasicAddressesInit</i>
+ * to define the addresses which will be used during the communication.
+ * Moreover, functions to set the payload length and the destination address
+ * are provided.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * PktBasicInit basicInit={
+ *   PKT_PREAMBLE_LENGTH_08BYTES,       // preamble length in bytes
+ *   PKT_SYNC_LENGTH_4BYTES,            // sync word length in bytes
+ *   0x1A2635A8,                        // sync word
+ *   PKT_LENGTH_VAR,                    // variable or fixed payload length
+ *   7,                                 // length field width in bits (used only for variable length)
+ *   PKT_NO_CRC,                        // CRC mode
+ *   PKT_CONTROL_LENGTH_0BYTES,         // control field length
+ *   S_ENABLE,                          // address field
+ *   S_DISABLE,                         // FEC
+ *   S_ENABLE                           // whitening
+ * };
+ *
+ * PktBasicAddressesInit addressInit={
+ *   S_ENABLE,                          // enable/disable filtering on my address
+ *   0x34,                              // my address (address of the current node)
+ *   S_DISABLE,                         // enable/disable filtering on multicast address
+ *   0xEE,                              // multicast address
+ *   S_DISABLE,                         // enable/disable filtering on broadcast address
+ *   0xFF                               // broadcast address
+ * };
+ *
+ * ...
+ *
+ * SpiritPktBasicInit(&basicInit);
+ * SpiritPktBasicAddressesInit(&addressInit);
+ *
+ * ...
+ *
+ * SpiritPktBasicSetPayloadLength(20);
+ * SpiritPktBasicSetDestinationAddress(0x44);
+ *
+ * ...
+ *
+ * @endcode
+ *
+ * The module provides some other functions that can be used to modify
+ * or read only some configuration parameters.
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_PKT_BASIC_H
+#define __SPIRIT_PKT_BASIC_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+#include "SPIRIT_PktCommon.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_PktBasic    Pkt Basic
+ * @brief Configuration and management of SPIRIT Basic packets.
+ * @details See the file <i>@ref SPIRIT_PktBasic.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup PktBasic_Exported_Types    Pkt Basic Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  Preamble length in bytes enumeration.
+ */
+typedef PktPreambleLength                  BasicPreambleLength;
+
+#define IS_BASIC_PREAMBLE_LENGTH           IS_PKT_PREAMBLE_LENGTH
+
+/**
+ * @brief  Sync length in bytes enumeration.
+ */
+typedef PktSyncLength                      BasicSyncLength;
+
+#define IS_BASIC_SYNC_LENGTH               IS_PKT_SYNC_LENGTH
+
+
+
+/**
+ * @brief  CRC length in bytes enumeration.
+ */
+typedef PktCrcMode                         BasicCrcMode;
+
+#define IS_BASIC_CRC_MODE                  IS_PKT_CRC_MODE
+
+
+/**
+ * @brief  Fixed or variable payload length enumeration.
+ */
+typedef PktFixVarLength                    BasicFixVarLength;
+
+#define IS_BASIC_FIX_VAR_LENGTH            IS_PKT_FIX_VAR_LENGTH
+
+/**
+ * @brief  Control length in bytes enumeration.
+ */
+typedef PktControlLength                   BasicControlLength;
+
+#define IS_BASIC_CONTROL_LENGTH            IS_PKT_CONTROL_LENGTH
+
+/**
+ * @brief  Sync words enumeration.
+ */
+typedef PktSyncX                           BasicSyncX;
+
+#define IS_BASIC_SYNCx                     IS_PKT_SYNCx
+
+
+/**
+ * @brief  SPIRIT Basic Packet Init structure definition. This structure allows users to set the main options
+ *         for the Basic packet.
+ */
+typedef struct
+{
+
+  BasicPreambleLength           xPreambleLength;        /*!< Specifies the preamble length.
+                                                             This parameter can be any value of @ref BasicPreambleLength */
+  BasicSyncLength               xSyncLength;            /*!< Specifies the sync word length. The 32bit word passed (lSyncWords) will be stored in the SYNCx registers from the MSb
+                                                             until the number of bytes in xSyncLength has been stored.
+                                                             This parameter can be any value of @ref BasicSyncLength */
+  uint32_t                      lSyncWords;             /*!< Specifies the sync words.
+                                                             This parameter is a uint32_t word with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4| */
+  BasicFixVarLength             xFixVarLength;          /*!< Specifies if a fixed length of packet has to be used.
+                                                             This parameter can be any value of @ref BasicFixVarLength */
+  uint8_t                       cPktLengthWidth;        /*!< Specifies the size of the length of packet in bits. This field is useful only if
+                                                             the field xFixVarLength is set to BASIC_LENGTH_VAR. For Basic packets the length width
+                                                             is log2( max payload length + control length (0 to 4) + address length (0 or 1)).
+                                                             This parameter is an uint8_t */
+  BasicCrcMode                  xCrcMode;               /*!< Specifies the CRC word length of packet.
+                                                             This parameter can be any value of @ref BasicCrcMode */
+  BasicControlLength            xControlLength;         /*!< Specifies the length of a control field to be sent.
+                                                             This parameter can be any value of @ref BasicControlLength */
+  SpiritFunctionalState         xAddressField;          /*!< Specifies if the destination address has to be sent.
+                                                             This parameter can be S_ENABLE or S_DISABLE */
+  SpiritFunctionalState         xFec;                   /*!< Specifies if FEC has to be enabled.
+                                                             This parameter can be S_ENABLE or S_DISABLE */
+  SpiritFunctionalState         xDataWhitening;         /*!< Specifies if data whitening has to be enabled.
+                                                             This parameter can be S_ENABLE or S_DISABLE */
+}PktBasicInit;
+
+
+/**
+ * @brief  SPIRIT Basic Packet address structure definition. This structure allows users to specify
+ *         the node/multicast/broadcast addresses and the correspondent filtering options.
+ */
+typedef struct
+{
+
+  SpiritFunctionalState         xFilterOnMyAddress;             /*!< If set RX packet is accepted if its destination address matches with cMyAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cMyAddress;                     /*!< Specifies the TX packet source address (address of this node).
+                                                                     This parameter is an uint8_t */
+  SpiritFunctionalState         xFilterOnMulticastAddress;      /*!< If set RX packet is accepted if its destination address matches with cMulticastAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cMulticastAddress;              /*!< Specifies the Multicast group address for this node.
+                                                                     This parameter is an uint8_t */
+  SpiritFunctionalState         xFilterOnBroadcastAddress;      /*!< If set RX packet is accepted if its destination address matches with cBroadcastAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cBroadcastAddress;              /*!< Specifies the Broadcast address for this node.
+                                                                     This parameter is an uint8_t */
+}PktBasicAddressesInit;
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Exported_Constants        Pkt Basic Exported Constants
+ * @{
+ */
+
+#define IS_BASIC_LENGTH_WIDTH_BITS                      IS_PKT_LENGTH_WIDTH_BITS
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Exported_Macros   Pkt Basic Exported Macros
+ * @{
+ */
+
+/**
+ * @brief  Macro used to compute per lower part of the packet length
+ *         for Spirit Basic packets, to write in the PCKTLEN0 register.
+ * @param  nLength Length of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define BASIC_BUILD_PCKTLEN0(nLength)                                            BUILD_PCKTLEN0(nLength)
+
+
+/**
+ * @brief  Macro used to compute per upper part of the packet length
+ *         for Spirit Basic packets, to write the PCKTLEN1 register.
+ * @param  nLengthLength of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define BASIC_BUILD_PCKTLEN1(nLength)                                            BUILD_PCKTLEN1(nLength)
+
+/**
+ * @brief  Sets the CONTROL field length for SPIRIT Basic packets.
+ * @param  xControlLength length of CONTROL field in bytes.
+ *         This parameter can be any value of @ref PktControlLength.
+ * @retval None.
+ */
+#define SpiritPktBasicSetControlLength(xControlLength)                  SpiritPktCommonSetControlLength(xControlLength)
+
+
+/**
+ * @brief  Returns the CONTROL field length for SPIRIT Basic packets.
+ * @param  None.
+ * @retval uint8_t Control field length.
+ */
+#define SpiritPktBasicGetControlLength()                                SpiritPktCommonGetControlLength()
+
+
+/**
+ * @brief  Sets the PREAMBLE field length for SPIRIT Basic packets.
+ * @param  xPreambleLength length of PREAMBLE field in bytes.
+ *         This parameter can be any value of @ref BasicPreambleLength.
+ * @retval None.
+ */
+#define SpiritPktBasicSetPreambleLength(xPreambleLength)                SpiritPktCommonSetPreambleLength((PktPreambleLength)xPreambleLength)
+
+
+/**
+ * @brief  Returns the PREAMBLE field length mode for SPIRIT Basic packets.
+ * @param  None.
+ * @retval uint8_t Preamble field length in bytes.
+ */
+#define SpiritPktBasicGetPreambleLength()                               SpiritPktCommonGetPreambleLength()
+
+
+/**
+ * @brief  Sets the SYNC field length for SPIRIT Basic packets.
+ * @param  xSyncLength length of SYNC field in bytes.
+ *         This parameter can be any value of @ref BasicSyncLength.
+ * @retval None.
+ */
+#define SpiritPktBasicSetSyncLength(xSyncLength)                         SpiritPktCommonSetSyncLength((PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns the SYNC field length for SPIRIT Basic packets.
+ * @param  None.
+ * @retval uint8_t SYNC field length in bytes.
+ */
+#define SpiritPktBasicGetSyncLength()                                   SpiritPktCommonGetSyncLength()
+
+
+/**
+ * @brief  Sets fixed or variable payload length mode for SPIRIT packets.
+ * @param  xFixVarLength variable or fixed length.
+ *         BASIC_FIXED_LENGTH_VAR -> variable (the length is extracted from the received packet).
+ *         BASIC_FIXED_LENGTH_FIX -> fix (the length is set by PCKTLEN0 and PCKTLEN1).
+ * @retval None.
+ */
+#define SpiritPktBasicSetFixVarLength(xFixVarLength)                    SpiritPktCommonSetFixVarLength((PktFixVarLength)xFixVarLength)
+
+
+/**
+ * @brief  Enables or Disables the CRC filtering.
+ * @param  xNewState new state for CRC_CHECK.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicFilterOnCrc(xNewState)                            SpiritPktCommonFilterOnCrc(xNewState)
+
+
+/**
+ * @brief  Returns the CRC filtering bit.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktBasicGetFilterOnCrc()                                  SpiritPktCommonGetFilterOnCrc()
+
+
+/**
+ * @brief  Sets the CRC mode for SPIRIT Basic packets.
+ * @param  xCrcMode CRC mode.
+ *         This parameter can be any value of @ref BasicCrcMode.
+ * @retval None.
+ */
+#define SpiritPktBasicSetCrcMode(xCrcMode)                              SpiritPktCommonSetCrcMode((PktCrcMode)xCrcMode)
+
+
+/**
+ * @brief  Returns the CRC mode for SPIRIT Basic packets.
+ * @param  None.
+ * @retval BasicCrcMode Crc mode.
+ */
+#define SpiritPktBasicGetCrcMode()                                      (BasicCrcMode)SpiritPktCommonGetCrcMode()
+
+
+/**
+ * @brief  Enables or Disables WHITENING for SPIRIT packets.
+ * @param  xNewState new state for WHITENING mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicWhitening(xNewState)                               SpiritPktCommonWhitening(xNewState)
+
+
+/**
+ * @brief  Enables or Disables FEC for SPIRIT Basic packets.
+ * @param  xNewState new state for FEC mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicFec(xNewState)                                     SpiritPktCommonFec(xNewState)
+
+
+/**
+ * @brief  Sets a specific SYNC word for SPIRIT Basic packets.
+ * @param  xSyncX SYNC word number to be set.
+ *         This parameter can be any value of @ref BasicSyncX.
+ * @param  cSyncWord SYNC word.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetSyncxWord(xSyncX, cSyncWord)                   SpiritPktCommonSetSyncxWord((PktSyncX)xSyncX, cSyncWord)
+
+
+/**
+ * @brief  Returns a specific SYNC words for SPIRIT Basic packets.
+ * @param  xSyncX SYNC word number to be get.
+ *         This parameter can be any value of @ref BasicSyncX.
+ * @retval uint8_t Sync word x.
+ */
+#define SpiritPktBasicGetSyncxWord(xSyncX)                              SpiritPktCommonGetSyncxWord(xSyncX)
+
+
+/**
+ * @brief  Sets multiple SYNC words for SPIRIT Basic packets.
+ * @param  lSyncWords SYNC words to be set with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ *         This parameter is a uint32_t.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a @ref BasicSyncLength.
+ * @retval None.
+ */
+#define SpiritPktBasicSetSyncWords(lSyncWords, xSyncLength)              SpiritPktCommonSetSyncWords(lSyncWords, (PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns multiple SYNC words for SPIRIT Basic packets.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a pointer to @ref BasicSyncLength.
+ * @retval uint32_t Sync words. The format of the read 32 bit word is 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ */
+#define SpiritPktBasicGetSyncWords(xSyncLength)                         SpiritPktCommonGetSyncWords((PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns the SPIRIT variable length width (in number of bits).
+ * @param  None.
+ * @retval Variable length width in bits.
+ */
+#define SpiritPktBasicGetVarLengthWidth()                               SpiritPktCommonGetVarLengthWidth()
+
+
+/**
+ * @brief  Sets the destination address for the Tx packet.
+ * @param  cAddress destination address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetDestinationAddress(cAddress)                   SpiritPktCommonSetDestinationAddress(cAddress)
+
+
+/**
+ * @brief  Returns the settled destination address.
+ * @param  None.
+ * @retval uint8_t Transmitted destination address.
+ */
+#define SpiritPktBasicGetTransmittedDestAddress()                       SpiritPktCommonGetTransmittedDestAddress()
+
+
+/**
+ * @brief  Sets the node address. When the filtering on my address is on, if the destination address extracted from the received packet is equal to the content of the
+ *         my address, then the packet is accepted (this is the address of the node).
+ * @param  cAddress Address of the present node.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetMyAddress(cAddress)                            SpiritPktCommonSetMyAddress(cAddress)
+
+
+/**
+ * @brief  Returns the address of the present node.
+ * @param  None.
+ * @retval uint8_t My address (address of this node).
+ */
+#define SpiritPktBasicGetMyAddress()                                    SpiritPktCommonGetMyAddress()
+
+
+/**
+ * @brief  Sets the broadcast address. When the broadcast filtering is on, if the destination address extracted from the received packet is equal to the content of the
+ *         BROADCAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Broadcast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetBroadcastAddress(cAddress)                     SpiritPktCommonSetBroadcastAddress(cAddress)
+
+
+/**
+ * @brief  Returns the broadcast address.
+ * @param  None.
+ * @retval uint8_t Broadcast address.
+ */
+#define SpiritPktBasicGetBroadcastAddress()                             SpiritPktCommonGetBroadcastAddress()
+
+
+/**
+ * @brief  Sets the multicast address. When the multicast filtering is on, if the destination address extracted from the received packet is equal to the content of the
+ *         MULTICAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Multicast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetMulticastAddress(cAddress)                     SpiritPktCommonSetMulticastAddress(cAddress)
+
+
+/**
+ * @brief  Returns the multicast address.
+ * @param  None.
+ * @retval uint8_t Multicast address.
+ */
+#define SpiritPktBasicGetMulticastAddress()                             SpiritPktCommonGetMulticastAddress()
+
+
+/**
+ * @brief  Sets the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  lMask Control mask.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetCtrlMask(lMask)                                SpiritPktCommonSetCtrlMask(lMask)
+
+
+/**
+ * @brief  Returns the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  None.
+ * @retval uint32_t Control mask.
+ */
+#define SpiritPktBasicGetCtrlMask()                                     SpiritPktCommonGetCtrlMask()
+
+
+/**
+ * @brief  Sets the control field reference. If the bits enabled by the
+ *         CONTROL_MASK match the ones of the control fields extracted from the received packet
+ *         then the packet is accepted.
+ * @param  lReference Control reference.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetCtrlReference(lReference)                      SpiritPktCommonSetCtrlReference(lReference)
+
+
+/**
+ * @brief  Returns the control field reference.
+ * @param  None.
+ * @retval uint32_t Control reference.
+ */
+#define SpiritPktBasicGetCtrlReference()                                SpiritPktCommonGetCtrlReference()
+
+
+/**
+ * @brief  Sets the TX control field.
+ * @param  lField Tx control field.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktBasicSetTransmittedCtrlField(lField)                   SpiritPktCommonSetTransmittedCtrlField(lField)
+
+
+/**
+ * @brief  Returns the TX control field.
+ * @param  None.
+ * @retval uint32_t Control field of the transmitted packet.
+ */
+#define SpiritPktBasicGetTransmittedCtrlField()                         SpiritPktCommonGetTransmittedCtrlField()
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with My address.
+ * @param  xNewState new state for DEST_VS_SOURCE_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicFilterOnMyAddress(xNewState)                      SpiritPktCommonFilterOnMyAddress(xNewState)
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with multicast address.
+ * @param  xNewState new state for DEST_VS_MULTICAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicFilterOnMulticastAddress(xNewState)               SpiritPktCommonFilterOnMulticastAddress(xNewState)
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with broadcast address.
+ * @param  xNewState new state for DEST_VS_BROADCAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktBasicFilterOnBroadcastAddress(xNewState)               SpiritPktCommonFilterOnBroadcastAddress(xNewState)
+
+
+/**
+ * @brief  Returns the enable bit of the my address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktBasicGetFilterOnMyAddress()                            SpiritPktCommonGetFilterOnMyAddress();
+
+
+/**
+ * @brief  Returns the enable bit of the multicast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktBasicGetFilterOnMulticastAddress()                     SpiritPktCommonGetFilterOnMulticastAddress();
+
+
+/**
+ * @brief  Returns the enable bit of the broadcast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktBasicGetFilterOnBroadcastAddress()                     SpiritPktCommonGetFilterOnBroadcastAddress();
+
+
+/**
+ * @brief  Returns the destination address of the received packet.
+ * @param  None.
+ * @retval uint8_t Destination address of the received packet.
+ */
+#define SpiritPktBasicGetReceivedDestAddress()                          SpiritPktCommonGetReceivedDestAddress()
+
+
+/**
+ * @brief  Returns the control field of the received packet.
+ * @param  None.
+ * @retval uint32_t Received control field.
+ */
+#define SpiritPktBasicGetReceivedCtrlField()                            SpiritPktCommonGetReceivedCtrlField()
+
+
+/**
+ * @brief  Returns the CRC field of the received packet.
+ * @param  cCrcFieldVect array in which the CRC field has to be stored.
+ *         This parameter is an uint8_t array of 3 elements.
+ * @retval None.
+ */
+#define SpiritPktBasicGetReceivedCrcField(cCrcFieldVect)                SpiritPktCommonGetReceivedCrcField(cCrcFieldVect)
+
+
+/**
+ * @brief  If enabled RX packet is accepted only if the masked control field matches the
+ *         masked control field reference (CONTROL_MASK & CONTROL_FIELD_REF == CONTROL_MASK & RX_CONTROL_FIELD).
+ * @param  xNewState new state for Control filtering enable bit.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ * @note   This filtering control is enabled by default but the control mask is by default set to 0.
+ *         As a matter of fact the user has to enable the control filtering bit after the packet initialization
+ *         because the PktInit routine disables it.
+ */
+#define SpiritPktBasicFilterOnControlField(xNewState)                           SpiritPktCommonFilterOnControlField(xNewState)
+
+
+/**
+ * @brief  Returns the enable bit of the control field filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktBasicGetFilterOnControlField()                                 SpiritPktCommonGetFilterOnControlField();
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Exported_Functions        Pkt Basic Exported Functions
+ * @{
+ */
+
+void SpiritPktBasicInit(PktBasicInit* pxPktBasicInit);
+void SpiritPktBasicGetInfo(PktBasicInit* pxPktBasicInit);
+void SpiritPktBasicAddressesInit(PktBasicAddressesInit* pxPktBasicAddresses);
+void SpiritPktBasicGetAddressesInfo(PktBasicAddressesInit* pxPktBasicAddresses);
+void SpiritPktBasicSetFormat(void);
+void SpiritPktBasicAddressField(SpiritFunctionalState xAddressField);
+SpiritFunctionalState SpiritPktBasicGetAddressField(void);
+void SpiritPktBasicSetPayloadLength(uint16_t nPayloadLength);
+uint16_t SpiritPktBasicGetPayloadLength(void);
+uint16_t SpiritPktBasicGetReceivedPktLength(void);
+void SpiritPktBasicSetVarLengthWidth(uint16_t nMaxPayloadLength,SpiritFunctionalState xAddressField, BasicControlLength xControlLength);
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktCommon.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktCommon.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,432 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_PktCommon.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of the common features of SPIRIT packets.
+  * 
+ * @details
+ *
+ * This module provides all the common functions and definitions used by the
+ * packets modules.
+ * Here are also defined all the generic enumeration types that are redefined
+ * in the specific packets modules, but every enumeration value is referred
+ * to this module. So the user who wants to configure the preamble of a Basic,
+ * or a STack packet has to use the enumeration values defined here.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *   ...
+ *
+ *   SpiritPktBasicSetPreambleLength(PKT_PREAMBLE_LENGTH_18BYTES);
+ *
+ *   ...
+ *
+ * @endcode
+ *
+ * @note Is recommended for the user to not use these API directly
+ * importing this module in his application.
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_PKT_COMMON_H
+#define __SPIRIT_PKT_COMMON_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_PktCommon           Pkt Common
+ * @brief Configuration and management of the common features of SPIRIT packets.
+ * @details See the file <i>@ref SPIRIT_PktCommon.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup PktCommon_Exported_Types   Pkt Common Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  Preamble length in bytes enumeration.
+ */
+typedef enum
+{
+  PKT_PREAMBLE_LENGTH_01BYTE            = 0x00, /*!< Preamble length 1 byte*/
+  PKT_PREAMBLE_LENGTH_02BYTES           = 0x08, /*!< Preamble length 2 bytes */
+  PKT_PREAMBLE_LENGTH_03BYTES           = 0x10, /*!< Preamble length 3 bytes */
+  PKT_PREAMBLE_LENGTH_04BYTES           = 0x18, /*!< Preamble length 4 bytes */
+  PKT_PREAMBLE_LENGTH_05BYTES           = 0x20, /*!< Preamble length 5 bytes */
+  PKT_PREAMBLE_LENGTH_06BYTES           = 0x28, /*!< Preamble length 6 bytes */
+  PKT_PREAMBLE_LENGTH_07BYTES           = 0x30, /*!< Preamble length 7 bytes */
+  PKT_PREAMBLE_LENGTH_08BYTES           = 0x38, /*!< Preamble length 8 bytes */
+  PKT_PREAMBLE_LENGTH_09BYTES           = 0x40, /*!< Preamble length 9 bytes */
+  PKT_PREAMBLE_LENGTH_10BYTES           = 0x48, /*!< Preamble length 10 bytes */
+  PKT_PREAMBLE_LENGTH_11BYTES           = 0x50, /*!< Preamble length 11 bytes */
+  PKT_PREAMBLE_LENGTH_12BYTES           = 0x58, /*!< Preamble length 12 bytes */
+  PKT_PREAMBLE_LENGTH_13BYTES           = 0x60, /*!< Preamble length 13 bytes */
+  PKT_PREAMBLE_LENGTH_14BYTES           = 0x68, /*!< Preamble length 14 bytes */
+  PKT_PREAMBLE_LENGTH_15BYTES           = 0x70, /*!< Preamble length 15 bytes */
+  PKT_PREAMBLE_LENGTH_16BYTES           = 0x78, /*!< Preamble length 16 bytes */
+  PKT_PREAMBLE_LENGTH_17BYTES           = 0x80, /*!< Preamble length 17 bytes */
+  PKT_PREAMBLE_LENGTH_18BYTES           = 0x88, /*!< Preamble length 18 bytes */
+  PKT_PREAMBLE_LENGTH_19BYTES           = 0x90, /*!< Preamble length 19 bytes */
+  PKT_PREAMBLE_LENGTH_20BYTES           = 0x98, /*!< Preamble length 20 bytes */
+  PKT_PREAMBLE_LENGTH_21BYTES           = 0xA0, /*!< Preamble length 21 bytes */
+  PKT_PREAMBLE_LENGTH_22BYTES           = 0xA8, /*!< Preamble length 22 bytes */
+  PKT_PREAMBLE_LENGTH_23BYTES           = 0xB0, /*!< Preamble length 23 bytes */
+  PKT_PREAMBLE_LENGTH_24BYTES           = 0xB8, /*!< Preamble length 24 bytes */
+  PKT_PREAMBLE_LENGTH_25BYTES           = 0xC0, /*!< Preamble length 25 bytes */
+  PKT_PREAMBLE_LENGTH_26BYTES           = 0xC8, /*!< Preamble length 26 bytes */
+  PKT_PREAMBLE_LENGTH_27BYTES           = 0xD0, /*!< Preamble length 27 bytes */
+  PKT_PREAMBLE_LENGTH_28BYTES           = 0xD8, /*!< Preamble length 28 bytes */
+  PKT_PREAMBLE_LENGTH_29BYTES           = 0xE0, /*!< Preamble length 29 bytes */
+  PKT_PREAMBLE_LENGTH_30BYTES           = 0xE8, /*!< Preamble length 30 bytes */
+  PKT_PREAMBLE_LENGTH_31BYTES           = 0xF0, /*!< Preamble length 31 bytes */
+  PKT_PREAMBLE_LENGTH_32BYTES           = 0xF8  /*!< Preamble length 32 bytes */
+
+}PktPreambleLength;
+
+#define IS_PKT_PREAMBLE_LENGTH(LENGTH)  ((LENGTH == PKT_PREAMBLE_LENGTH_01BYTE) || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_02BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_03BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_04BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_05BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_06BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_07BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_08BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_09BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_10BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_11BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_12BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_13BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_14BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_15BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_16BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_17BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_18BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_19BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_20BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_21BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_22BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_23BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_24BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_25BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_26BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_27BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_28BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_29BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_30BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_31BYTES)  || \
+                                           (LENGTH == PKT_PREAMBLE_LENGTH_32BYTES))
+
+
+
+/**
+ * @brief  Sync length in bytes enumeration.
+ */
+typedef enum
+{
+  PKT_SYNC_LENGTH_1BYTE            = 0x00, /*!< Sync length 1 byte*/
+  PKT_SYNC_LENGTH_2BYTES           = 0x02, /*!< Sync length 2 bytes*/
+  PKT_SYNC_LENGTH_3BYTES           = 0x04, /*!< Sync length 3 bytes */
+  PKT_SYNC_LENGTH_4BYTES           = 0x06 , /*!< Sync length 4 bytes */
+
+}PktSyncLength;
+
+#define IS_PKT_SYNC_LENGTH(LENGTH)     ((LENGTH == PKT_SYNC_LENGTH_1BYTE) || \
+                                          (LENGTH == PKT_SYNC_LENGTH_2BYTES)|| \
+                                          (LENGTH == PKT_SYNC_LENGTH_3BYTES)|| \
+                                          (LENGTH == PKT_SYNC_LENGTH_4BYTES))
+
+
+
+/**
+ * @brief  CRC length in bytes enumeration.
+ */
+typedef enum
+{
+  PKT_NO_CRC               = 0x00, /*!< No CRC                              */
+  PKT_CRC_MODE_8BITS       = 0x20, /*!< CRC length 8 bits  - poly: 0x07     */
+  PKT_CRC_MODE_16BITS_1    = 0x40, /*!< CRC length 16 bits - poly: 0x8005   */
+  PKT_CRC_MODE_16BITS_2    = 0x60, /*!< CRC length 16 bits - poly: 0x1021   */
+  PKT_CRC_MODE_24BITS      = 0x80, /*!< CRC length 24 bits - poly: 0x864CFB */
+
+}PktCrcMode;
+
+#define IS_PKT_CRC_MODE(MODE)   ((MODE == PKT_NO_CRC) || \
+                                   (MODE == PKT_CRC_MODE_8BITS)  || \
+                                   (MODE == PKT_CRC_MODE_16BITS_1)  || \
+                                   (MODE == PKT_CRC_MODE_16BITS_2) || \
+                                   (MODE == PKT_CRC_MODE_24BITS))
+
+
+
+/**
+ * @brief  Fixed or variable payload length enumeration.
+ */
+typedef enum
+{
+  PKT_LENGTH_FIX  = 0x00,    /*!< Fixed payload length     */
+  PKT_LENGTH_VAR  = 0x01     /*!< Variable payload length  */
+
+}PktFixVarLength;
+
+#define IS_PKT_FIX_VAR_LENGTH(LENGTH)   ((LENGTH == PKT_LENGTH_FIX) || \
+                                           (LENGTH == PKT_LENGTH_VAR))
+
+
+/**
+ * @brief  Control length in bytes enumeration for SPIRIT packets.
+ */
+typedef enum
+{
+  PKT_CONTROL_LENGTH_0BYTES = 0x00,     /*!< Control length 0 byte*/
+  PKT_CONTROL_LENGTH_1BYTE,             /*!< Control length 1 byte*/
+  PKT_CONTROL_LENGTH_2BYTES,            /*!< Control length 2 bytes*/
+  PKT_CONTROL_LENGTH_3BYTES,            /*!< Control length 3 bytes*/
+  PKT_CONTROL_LENGTH_4BYTES             /*!< Control length 4 bytes*/
+
+}PktControlLength;
+
+#define IS_PKT_CONTROL_LENGTH(LENGTH) ((LENGTH == PKT_CONTROL_LENGTH_0BYTES) || \
+                                         (LENGTH == PKT_CONTROL_LENGTH_1BYTE)   || \
+                                         (LENGTH == PKT_CONTROL_LENGTH_2BYTES)  || \
+                                         (LENGTH == PKT_CONTROL_LENGTH_3BYTES)  || \
+                                         (LENGTH == PKT_CONTROL_LENGTH_4BYTES))
+
+/**
+ * @brief  Sync words enumeration for SPIRIT packets.
+ */
+typedef enum
+{
+  PKT_SYNC_WORD_1=0x01,  /*!< Index of the 1st sync word*/
+  PKT_SYNC_WORD_2,       /*!< Index of the 2nd sync word*/
+  PKT_SYNC_WORD_3,       /*!< Index of the 3rd sync word*/
+  PKT_SYNC_WORD_4        /*!< Index of the 4th sync word*/
+
+}PktSyncX;
+
+#define IS_PKT_SYNCx(WORD)    ((WORD == PKT_SYNC_WORD_1) || \
+                                 (WORD == PKT_SYNC_WORD_2) || \
+                                 (WORD == PKT_SYNC_WORD_3) || \
+                                 (WORD == PKT_SYNC_WORD_4))
+
+
+
+/**
+ * @brief  Max retransmissions number enumeration for SPIRIT packets.
+ */
+typedef enum
+{
+  PKT_DISABLE_RETX    = 0x00,   /*!< No retrasmissions*/
+  PKT_N_RETX_1        = 0x10,   /*!< Max retrasmissions 1*/
+  PKT_N_RETX_2        = 0x20,   /*!< Max retrasmissions 2*/
+  PKT_N_RETX_3        = 0x30,   /*!< Max retrasmissions 3*/
+  PKT_N_RETX_4        = 0x40,   /*!< Max retrasmissions 4*/
+  PKT_N_RETX_5        = 0x50,   /*!< Max retrasmissions 5*/
+  PKT_N_RETX_6        = 0x60,   /*!< Max retrasmissions 6*/
+  PKT_N_RETX_7        = 0x70,   /*!< Max retrasmissions 7*/
+  PKT_N_RETX_8        = 0x80,   /*!< Max retrasmissions 8*/
+  PKT_N_RETX_9        = 0x90,   /*!< Max retrasmissions 9*/
+  PKT_N_RETX_10       = 0xA0,   /*!< Max retrasmissions 10*/
+  PKT_N_RETX_11       = 0xB0,   /*!< Max retrasmissions 11*/
+  PKT_N_RETX_12       = 0xC0,   /*!< Max retrasmissions 12*/
+  PKT_N_RETX_13       = 0xD0,   /*!< Max retrasmissions 13*/
+  PKT_N_RETX_14       = 0xE0,   /*!< Max retrasmissions 14*/
+  PKT_N_RETX_15       = 0xF0    /*!< Max retrasmissions 15*/
+
+}PktNMaxReTx;
+
+#define IS_PKT_NMAX_RETX(N_RETX)    ((N_RETX == PKT_DISABLE_RETX) || \
+                                       (N_RETX == PKT_N_RETX_1) || \
+                                       (N_RETX == PKT_N_RETX_2) || \
+                                       (N_RETX == PKT_N_RETX_3) || \
+                                       (N_RETX == PKT_N_RETX_4) || \
+                                       (N_RETX == PKT_N_RETX_5) || \
+                                       (N_RETX == PKT_N_RETX_6) || \
+                                       (N_RETX == PKT_N_RETX_7) || \
+                                       (N_RETX == PKT_N_RETX_8) || \
+                                       (N_RETX == PKT_N_RETX_9) || \
+                                       (N_RETX == PKT_N_RETX_10) || \
+                                       (N_RETX == PKT_N_RETX_11) || \
+                                       (N_RETX == PKT_N_RETX_12) || \
+                                       (N_RETX == PKT_N_RETX_13) || \
+                                       (N_RETX == PKT_N_RETX_14) || \
+                                       (N_RETX == PKT_N_RETX_15))
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Exported_Constants               Pkt Common Exported Constants
+ * @{
+ */
+
+#define IS_PKT_LENGTH_WIDTH_BITS(BITS)                (BITS<=16)
+#define IS_PKT_SEQ_NUMBER_RELOAD(SEQN)                (SEQN<=3)
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Exported_Macros                  Pkt Common Exported Macros
+ * @{
+ */
+
+
+/**
+ * @brief  Macro used to compute the lower part of the packet length, to write in the PCKTLEN0 register
+ * @param  nLength Length of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define BUILD_PCKTLEN0(nLength) ((nLength) & 0xFF)
+
+
+/**
+ * @brief  Macro used to compute the upper part of the packet length, to write the PCKTLEN1 register
+ * @param  nLength Length of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define BUILD_PCKTLEN1(nLength) ((nLength) >> 8)
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Exported_Functions               Pkt Common Exported Functions
+ * @{
+ */
+
+void SpiritPktCommonSetControlLength(PktControlLength xControlLength);
+uint8_t SpiritPktCommonGetControlLength(void);
+void SpiritPktCommonSetPreambleLength(PktPreambleLength xPreambleLength);
+uint8_t SpiritPktCommonGetPreambleLength(void);
+void SpiritPktCommonSetSyncLength(PktSyncLength xSyncLength);
+uint8_t SpiritPktCommonGetSyncLength(void);
+void SpiritPktCommonSetFixVarLength(PktFixVarLength xFixVarLength);
+void SpiritPktCommonFilterOnCrc(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritPktCommonGetFilterOnCrc(void);
+void SpiritPktCommonSetCrcMode(PktCrcMode xCrcLength);
+PktCrcMode SpiritPktCommonGetCrcMode(void);
+void SpiritPktCommonWhitening(SpiritFunctionalState xNewState);
+void SpiritPktCommonFec(SpiritFunctionalState xNewState);
+void SpiritPktCommonSetSyncxWord(PktSyncX xSyncX,  uint8_t cSyncWord);
+uint8_t SpiritPktCommonGetSyncxWord(PktSyncX xSyncX);
+void SpiritPktCommonSetSyncWords(uint32_t lSyncWords, PktSyncLength xSyncLength);
+uint32_t SpiritPktCommonGetSyncWords(PktSyncLength xSyncLength);
+uint8_t SpiritPktCommonGetVarLengthWidth(void);
+void SpiritPktCommonSetDestinationAddress(uint8_t cAddress);
+uint8_t SpiritPktCommonGetTransmittedDestAddress(void);
+void SpiritPktCommonSetMyAddress(uint8_t cAddress);
+uint8_t SpiritPktCommonGetMyAddress(void);
+void SpiritPktCommonSetBroadcastAddress(uint8_t cAddress);
+uint8_t SpiritPktCommonGetBroadcastAddress(void);
+SpiritFunctionalState SpiritPktCommonGetTxAckRequest(void);
+void SpiritPktCommonSetMulticastAddress(uint8_t cAddress);
+uint8_t SpiritPktCommonGetMulticastAddress(void);
+void SpiritPktCommonSetCtrlMask(uint32_t lMask);
+uint32_t SpiritPktCommonGetCtrlMask(void);
+void SpiritPktCommonSetCtrlReference(uint32_t lReference);
+uint32_t SpiritPktCommonGetCtrlReference(void);
+void SpiritPktCommonSetTransmittedCtrlField(uint32_t lField);
+uint32_t SpiritPktCommonGetTransmittedCtrlField(void);
+void SpiritPktCommonFilterOnMyAddress(SpiritFunctionalState xNewState);
+void SpiritPktCommonFilterOnMulticastAddress(SpiritFunctionalState xNewState);
+void SpiritPktCommonFilterOnBroadcastAddress(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritPktCommonGetFilterOnMyAddress(void);
+SpiritFunctionalState SpiritPktCommonGetFilterOnMulticastAddress(void);
+SpiritFunctionalState SpiritPktCommonGetFilterOnBroadcastAddress(void);
+uint8_t SpiritPktCommonGetReceivedDestAddress(void);
+uint32_t SpiritPktCommonGetReceivedCtrlField(void);
+void SpiritPktCommonGetReceivedCrcField(uint8_t* cCrcFieldVect);
+void SpiritPktCommonAutoAck(SpiritFunctionalState xAutoAck,SpiritFunctionalState xPiggybacking);
+void SpiritPktCommonRequireAck(SpiritFunctionalState xRequireAck);
+void SpiritPktCommonSetTransmittedSeqNumberReload(uint8_t cSeqNumberReload);
+void SpiritPktCommonSetNMaxReTx(PktNMaxReTx xNMaxReTx);
+uint8_t SpiritPktCommonGetNMaxReTx(void);
+uint8_t SpiritPktCommonGetReceivedDestAddress(void);
+uint8_t SpiritPktCommonGetReceivedSourceAddress(void);
+uint8_t SpiritPktCommonGetReceivedSeqNumber(void);
+uint8_t SpiritPktCommonGetReceivedNackRx(void);
+uint8_t SpiritPktCommonGetTransmittedSeqNumber(void);
+uint8_t SpiritPktCommonGetNReTx(void);
+void SpiritPktCommonFilterOnControlField(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritPktCommonGetFilterOnControlField(void);
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktMbus.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktMbus.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,206 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_PktMbus.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT MBUS packets.
+  * 
+ * @details
+ *
+ * This module can be used to manage the configuration of Spirit MBUS
+ * packets.
+ * The user can obtain a packet configuration filling the structure
+ * <i>@ref PktMbusInit</i>, defining in it some general parameters
+ * for the Spirit MBUS packet format.
+ * Since the MBUS protocol is a standard, the configuration of a MBUS
+ * packet is very simple to do.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * PktMbusInit mbusInit={
+ *   MBUS_SUBMODE_S1_S2_LONG_HEADER,    // MBUS submode selection
+ *   36,                                // added "01" chips on preamble
+ *   16                                 // postamble length in "01" chips
+ * };
+ *
+ * ...
+ *
+ * SpiritPktMbusInit(&mbusInit);
+ *
+ * ...
+ *
+ * @endcode
+ *
+ * The module provides some other functions that can be used to modify
+ * or read only some configuration parameters.
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_PACKET_MBUS_H
+#define __SPIRIT_PACKET_MBUS_H
+
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+#include "SPIRIT_PktCommon.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_PktMbus     Pkt MBUS
+ * @brief Configuration and management of SPIRIT MBUS packets.
+ * @details See the file <i>@ref SPIRIT_PktMbus.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup PktMbus_Exported_Types     Pkt MBUS Exported Types
+ * @{
+ */
+
+
+
+/**
+ * @brief  MBUS submode enumeration.
+ */
+
+typedef enum
+{
+  MBUS_SUBMODE_S1_S2_LONG_HEADER            = MBUS_CTRL_MBUS_SUBMODE_S1_S2L,                /*!< MBUS submode S1, S2 (long header) - Header length = mbus_prmbl_ctrl + 279 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits) */
+  MBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER    = MBUS_CTRL_MBUS_SUBMODE_S2_S1M_T2_OTHER,       /*!< MBUS submode S1-m, S2, T2 (other to meter) - Header length = mbus_prmbl_ctrl + 15 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits)*/
+  MBUS_SUBMODE_T1_T2_METER_TO_OTHER         = MBUS_CTRL_MBUS_SUBMODE_T1_T2_METER,           /*!< MBUS submode T1, T2 (meter to other) - Header length = mbus_prmbl_ctrl + 19 (in "01" bit pairs) ,  Sync word = 0x3D (length 10 bits)*/
+  MBUS_SUBMODE_R2_SHORT_HEADER              = MBUS_CTRL_MBUS_SUBMODE_R2,                    /*!< MBUS submode R2, short header - Header length = mbus_prmbl_ctrl + 39 (in "01" bit pairs) , Sync word = 0x7696 (length 18 bits)*/
+
+}MbusSubmode;
+
+#define IS_MBUS_SUBMODE(MODE)   (((MODE) == MBUS_SUBMODE_S1_S2_LONG_HEADER) || \
+                                 ((MODE) == MBUS_SUBMODE_S1_M_S2_T2_OTHER_TO_METER) || \
+                                 ((MODE) == MBUS_SUBMODE_T1_T2_METER_TO_OTHER) || \
+                                 ((MODE) == MBUS_SUBMODE_R2_SHORT_HEADER))
+
+
+/**
+ * @brief  SPIRIT MBUS Packet Init structure definition
+ */
+typedef struct
+{
+  MbusSubmode  	    xMbusSubmode;              /*!< Specifies the SUBMODE to be configured.
+                                                    This parameter can be a value of @ref MbusSubmode */
+
+  uint8_t           cPreambleLength;           /*!< Specifies the PREAMBLE length.
+                                                    This parameter can be any value between 0 and 255 chip sequence '01' */
+
+  uint8_t           cPostambleLength;          /*!< Specifies the POSTAMBLE length.
+                                                    This parameter can be any value between 0 and 255 chip sequence '01' */
+
+}PktMbusInit;
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Exported_Constants         Pkt MBUS Exported Constants
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Exported_Macros            Pkt MBUS Exported Macros
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Exported_Functions                 Pkt MBUS Exported Functions
+ * @{
+ */
+void SpiritPktMbusInit(PktMbusInit* pxPktMbusInit);
+void SpiritPktMbusGetInfo(PktMbusInit* pxPktMbusInit);
+void SpiritPktMbusSetFormat(void);
+void SpiritPktMbusSetPreamble(uint8_t cPreamble);
+uint8_t SpiritPktMbusGetPreamble(void);
+void SpiritPktMbusSetPostamble(uint8_t cPostamble);
+uint8_t SpiritPktMbusGetPostamble(void);
+void SpiritPktMbusSetSubmode(MbusSubmode xMbusSubmode);
+MbusSubmode SpiritPktMbusGetSubmode(void);
+void SpiritPktMbusSetPayloadLength(uint16_t nPayloadLength);
+uint16_t SpiritPktMbusGetPayloadLength(void);
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktStack.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_PktStack.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,849 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_PktStack.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT STack packets.
+  * 
+ * @details
+ *
+ * This module can be used to manage the configuration of Spirit STack
+ * packets, and it is quite similar to the Basic packets one since the
+ * STack packets can be considered an extension of Basic.
+ * The user can obtain a packet configuration filling the structure
+ * <i>@ref PktStackInit</i>, defining in it some general parameters
+ * for the Spirit STack packet format.
+ * Another structure the user can fill is <i>@ref PktStackAddressesInit</i>
+ * to define the addresses which will be used during the communication.
+ * The structure <i>@ref PktStackLlpInit</i> is provided in order to configure
+ * the link layer protocol features like autoack, autoretransmission
+ * or piggybacking.
+ * Moreover, functions to set the payload length and the destination address
+ * are provided.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * PktStackInit stackInit={
+ *   PKT_PREAMBLE_LENGTH_08BYTES,       // preamble length in bytes
+ *   PKT_SYNC_LENGTH_4BYTES,            // sync word length in bytes
+ *   0x1A2635A8,                        // sync word
+ *   PKT_LENGTH_VAR,                    // variable or fixed payload length
+ *   7,                                 // length field width in bits (used only for variable length)
+ *   PKT_NO_CRC,                        // CRC mode
+ *   PKT_CONTROL_LENGTH_0BYTES,         // control field length
+ *   S_DISABLE,                         // FEC
+ *   S_ENABLE                           // whitening
+ * };
+ *
+ * PktStackAddressesInit addressInit={
+ *   S_ENABLE,                          // enable/disable filtering on my address
+ *   0x34,                              // my address (address of the current node)
+ *   S_DISABLE,                         // enable/disable filtering on multicast address
+ *   0xEE,                              // multicast address
+ *   S_DISABLE,                         // enable/disable filtering on broadcast address
+ *   0xFF                               // broadcast address
+ * };
+ *
+ * PktStackLlpInit stackLLPInit ={
+ *   S_DISABLE,                         // enable/disable the autoack feature
+ *   S_DISABLE,                         // enable/disable the piggybacking feature
+ *   PKT_DISABLE_RETX                   // set the max number of retransmissions or disable them
+ * };
+ * ...
+ *
+ * SpiritPktStackInit(&stackInit);
+ * SpiritPktStackAddressesInit(&addressInit);
+ * SpiritPktStackLlpInit(&stackLLPInit);
+ *
+ * ...
+ *
+ * SpiritPktStackSetPayloadLength(20);
+ * SpiritPktStackSetDestinationAddress(0x44);
+ *
+ * ...
+ *
+ * @endcode
+ *
+ * The module provides some other functions that can be used to modify
+ * or read only some configuration parameters.
+ *
+ *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_PKT_STACK_H
+#define __SPIRIT_PKT_STACK_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+#include "SPIRIT_PktCommon.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_PktStack    Pkt STack
+ * @brief Configuration and management of SPIRIT STack packets.
+ * @details See the file <i>@ref SPIRIT_PktStack.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup PktStack_Exported_Types    Pkt STack Exported Types
+ * @{
+ */
+
+/**
+ * @brief  Preamble length in bytes enumeration.
+ */
+typedef PktPreambleLength                  StackPreambleLength;
+
+#define IS_STACK_PREAMBLE_LENGTH           IS_PKT_PREAMBLE_LENGTH
+
+/**
+ * @brief  Sync length in bytes enumeration.
+ */
+typedef PktSyncLength                      StackSyncLength;
+
+#define IS_STACK_SYNC_LENGTH               IS_PKT_SYNC_LENGTH
+
+
+
+/**
+ * @brief  CRC length in bytes enumeration.
+ */
+typedef PktCrcMode                         StackCrcMode;
+
+#define IS_STACK_CRC_MODE                  IS_PKT_CRC_MODE
+
+
+/**
+ * @brief  Fixed or variable payload length enumeration.
+ */
+typedef PktFixVarLength                    StackFixVarLength;
+
+#define IS_STACK_FIX_VAR_LENGTH            IS_PKT_FIX_VAR_LENGTH
+
+/**
+ * @brief  Control length in bytes enumeration for SPIRIT.
+ */
+typedef PktControlLength                   StackControlLength;
+
+#define IS_STACK_CONTROL_LENGTH            IS_PKT_CONTROL_LENGTH
+
+/**
+ * @brief  Sync words enumeration for SPIRIT.
+ */
+typedef PktSyncX                           StackSyncX;
+
+#define IS_STACK_SYNCx                     IS_PKT_SYNCx
+
+/**
+ * @brief  Max retransmission number enumeration for SPIRIT.
+ */
+typedef PktNMaxReTx                        StackNMaxReTx;
+
+#define IS_STACK_NMAX_RETX                 IS_PKT_NMAX_RETX
+
+
+/**
+ * @brief  SPIRIT STack Packet Init structure definition. This structure allows users to set the main options
+ *         for the STack packet.
+ */
+typedef struct
+{
+
+  StackPreambleLength           xPreambleLength;         /*!< Specifies the preamble length of packet.
+                                                              This parameter can be any value of @ref StackPreambleLength */
+  StackSyncLength               xSyncLength;             /*!< Specifies the sync word length of packet.
+                                                              This parameter can be any value of @ref StackSyncLength */
+  uint32_t                      lSyncWords;	         /*!< Specifies the sync words.
+                                                              This parameter is a uint32_t word with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4| */
+  StackFixVarLength             xFixVarLength;           /*!< Specifies if a fixed length of packet has to be used.
+                                                              This parameter can be any value of @ref StackFixVarLength */
+  uint8_t            	        cPktLengthWidth;         /*!< Specifies the size of the length of packet in bits. This field is useful only if
+                                                              the field xFixVarLength is set to STACK_LENGTH_VAR. For STack packets the length width
+                                                               is log2( max payload length + control length (0 to 4) + address length (always 2)).
+                                                              This parameter is an uint8_t */
+  StackCrcMode                	xCrcMode;              	 /*!< Specifies the CRC word length of packet.
+                                                              This parameter can be any value of @ref StackCrcMode */
+  StackControlLength            xControlLength;          /*!< Specifies the length of a control field to be sent.
+                                                              This parameter can be any value of @ref StackControlLength */
+  SpiritFunctionalState         xFec;                    /*!< Specifies if FEC has to be enabled.
+                                                              This parameter can be any value of @ref SpiritFunctionalState */
+  SpiritFunctionalState         xDataWhitening;          /*!< Specifies if data whitening has to be enabled.
+                                                              This parameter can be any value of @ref SpiritFunctionalState */
+
+}PktStackInit;
+
+
+/**
+ * @brief  SPIRIT STack packet address structure definition. This structure allows users to specify
+ *         the node/multicast/broadcast addresses and the correspondent filtering options.
+ */
+typedef struct
+{
+
+  SpiritFunctionalState         xFilterOnMyAddress;             /*!< If set RX packet is accepted if its destination address matches with cMyAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cMyAddress;                     /*!< Specifies the TX packet source address (address of this node).
+                                                                     This parameter is an uint8_t */
+  SpiritFunctionalState         xFilterOnMulticastAddress;      /*!< If set RX packet is accepted if its destination address matches with cMulticastAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cMulticastAddress;              /*!< Specifies the Multicast group address for this node.
+                                                                     This parameter is an uint8_t */
+  SpiritFunctionalState         xFilterOnBroadcastAddress;      /*!< If set RX packet is accepted if its destination address matches with cBroadcastAddress.
+                                                                     This parameter can be S_ENABLE or S_DISABLE */
+  uint8_t                       cBroadcastAddress;              /*!< Specifies the Broadcast address for this node.
+                                                                     This parameter is an uint8_t */
+}PktStackAddressesInit;
+
+
+/**
+ * @brief  SPIRIT STack packet LLP structure definition. This structure allows users to configure
+ *         all the LLP options for STack packets.
+ */
+typedef struct
+{
+
+  SpiritFunctionalState         xAutoAck;                /*!< Specifies if the auto ACK feature is used or not.
+                                                              This parameter can be a value of @ref SpiritFunctionalState */
+  SpiritFunctionalState         xPiggybacking;           /*!< Specifies if the piggybacking feature is used or not.
+                                                              This parameter can be a value of @ref SpiritFunctionalState */
+  StackNMaxReTx                 xNMaxRetx;               /*!< Specifies the number of MAX-Retransmissions.
+                                                              This parameter can be a value of @ref StackNMaxReTx */
+}PktStackLlpInit;
+
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Exported_Constants        Pkt STack Exported Constants
+ * @{
+ */
+
+#define IS_STACK_LENGTH_WIDTH_BITS                      IS_PKT_LENGTH_WIDTH_BITS
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Exported_Macros   Pkt STack Exported Macros
+ * @{
+ */
+
+/**
+ * @brief  Macro used to compute the lower part of the packet length
+ *         for Spirit STack packets, to write in the PCKTLEN0 register.
+ * @param  nLength length of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define STACK_BUILD_PCKTLEN0(nLength)                                    BUILD_PCKTLEN0(nLength)
+
+
+/**
+ * @brief  Macro used to compute the upper part of the packet length
+ *         for Spirit STack packets, to write the PCKTLEN1 register.
+ * @param  nLength length of the packet payload.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+#define STACK_BUILD_PCKTLEN1(nLength)                                    BUILD_PCKTLEN1(nLength)
+
+
+/**
+ * @brief  Sets the CONTROL length for SPIRIT STack packets.
+ * @param  xControlLength length of CONTROL field in bytes.
+ *         This parameter can be any value of @ref StackControlLength.
+ * @retval None.
+ */
+#define SpiritPktStackSetControlLength(xControlLength)                          SpiritPktCommonSetControlLength(xControlLength)
+
+
+/**
+ * @brief  Returns the CONTROL length for SPIRIT STack packets.
+ * @param  None.
+ * @retval Control length.
+ */
+#define SpiritPktStackGetControlLength()                                       SpiritPktCommonGetControlLength()
+
+
+/**
+ * @brief  Sets the PREAMBLE Length mode for SPIRIT STack packets.
+ * @param  xPreambleLength length of PREAMBLE field in bytes.
+ *         This parameter can be any value of @ref StackPreambleLength.
+ * @retval None.
+ */
+#define SpiritPktStackSetPreambleLength(xPreambleLength)                        SpiritPktCommonSetPreambleLength((PktPreambleLength)xPreambleLength)
+
+
+/**
+ * @brief  Returns the PREAMBLE Length mode for SPIRIT STack packets.
+ * @param  None.
+ * @retval uint8_t Preamble length in bytes.
+ */
+#define SpiritPktStackGetPreambleLength()                                      SpiritPktCommonGetPreambleLength()
+
+
+/**
+ * @brief  Sets the SYNC Length for SPIRIT STack packets.
+ * @param  xSyncLength length of SYNC field in bytes.
+ *         This parameter can be any value of @ref StackSyncLength.
+ * @retval None.
+ */
+#define SpiritPktStackSetSyncLength(xSyncLength)                                SpiritPktCommonSetSyncLength((PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns the SYNC Length for SPIRIT STack packets.
+ * @param  None.
+ * @retval uint8_t Sync length in bytes.
+ */
+#define SpiritPktStackGetSyncLength()                                           SpiritPktCommonGetSyncLength()
+
+
+/**
+ * @brief  Sets fixed or variable payload length mode for SPIRIT STack packets.
+ * @param  xFixVarLength variable or fixed length.
+ *         PKT_FIXED_LENGTH_VAR -> variable (the length is extracted from the received packet).
+ *         PKT_FIXED_LENGTH_FIX -> fix (the length is set by PCKTLEN0 and PCKTLEN1).
+ * @retval None.
+ */
+#define SpiritPktStackSetFixVarLength(xFixVarLength)                            SpiritPktCommonSetFixVarLength((PktFixVarLength)xFixVarLength)
+
+
+/**
+ * @brief  Enables or Disables the CRC filtering.
+ * @param  xNewState new state for CRC_CHECK.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackFilterOnCrc(xNewState)                                    SpiritPktCommonFilterOnCrc(xNewState)
+
+
+/**
+ * @brief  Returns the CRC filtering bit.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktStackGetFilterOnCrc()                                          SpiritPktCommonGetFilterOnCrc()
+
+
+/**
+ * @brief  Sets the CRC mode for SPIRIT STack packets.
+ * @param  xCrcMode CRC mode.
+ *         This parameter can be any value of @ref StackCrcMode.
+ * @retval None.
+ */
+#define SpiritPktStackSetCrcMode(xCrcMode)                                      SpiritPktCommonSetCrcMode((PktCrcMode)xCrcMode)
+
+
+/**
+ * @brief  Returns the CRC mode for SPIRIT packets.
+ * @param  None.
+ * @retval StackCrcMode Crc mode.
+ */
+#define SpiritPktStackGetCrcMode()                                             (StackCrcMode)SpiritPktCommonGetCrcMode()
+
+
+/**
+ * @brief  Enables or Disables WHITENING for SPIRIT STack packets.
+ * @param  xNewState new state for WHITENING mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackWhitening(xNewState)                                     SpiritPktCommonWhitening(xNewState)
+
+
+/**
+ * @brief  Enables or Disables FEC for SPIRIT STack packets.
+ * @param  xNewState new state for FEC mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackFec(xNewState)                                            SpiritPktCommonFec(xNewState)
+
+
+/**
+ * @brief  Sets a specific SYNC word for SPIRIT STack packets.
+ * @param  xSyncX SYNC word number to be set.
+ *         This parameter can be any value of @ref StackSyncX.
+ * @param  cSyncWord SYNC word.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetSyncxWord(xSyncX, cSyncWord)                          SpiritPktCommonSetSyncxWord((PktSyncX)xSyncX,cSyncWord)
+
+
+/**
+ * @brief  Returns a specific SYNC word for SPIRIT STack packets.
+ * @param  xSyncX SYNC word number to be get.
+ *         This parameter can be any value of @ref StackSyncX.
+ * @retval uint8_t Sync word x.
+ */
+#define SpiritPktStackGetSyncxWord(xSyncX)                                     SpiritPktCommonGetSyncxWord(xSyncX)
+
+
+/**
+ * @brief  Sets multiple SYNC words for SPIRIT STack packets.
+ * @param  lSyncWords SYNC words to be set with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ *         This parameter is a uint32_t.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a @ref StackSyncLength.
+ * @retval None.
+ */
+#define SpiritPktStackSetSyncWords(lSyncWords, xSyncLength)                    SpiritPktCommonSetSyncWords(lSyncWords,(PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns multiple SYNC words for SPIRIT packets.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a pointer to @ref StackSyncLength.
+ * @retval uint32_t Sync words. The format of the read 32 bit word is 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ */
+#define SpiritPktStackGetSyncWords(xSyncLength)                                 SpiritPktCommonGetSyncWords((PktSyncLength)xSyncLength)
+
+
+/**
+ * @brief  Returns the SPIRIT variable length width (in number of bits).
+ * @param  None.
+ * @retval uint8_t Variable length width in bits.
+ */
+#define SpiritPktStackGetVarLengthWidth()                                       SpiritPktCommonGetVarLengthWidth()
+
+
+/**
+ * @brief  Sets the destination address for the Tx packet.
+ * @param  cAddress destination address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetDestinationAddress(cAddress)                           SpiritPktCommonSetDestinationAddress(cAddress)
+
+
+/**
+ * @brief  Sets the Rx packet reference source address. The source address extracted from the received packet is masked
+ *         with the source reference mask and then compared to the masked reference value.
+ * @param  cAddress Reference source address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetSourceReferenceAddress(cAddress)                       SpiritPktCommonSetDestinationAddress(cAddress)
+
+
+/**
+ * @brief  Returns the Rx packet reference source address. The source address extracted from the received packet is masked
+ *         with the source reference mask and then compared to the masked reference value.
+ * @param  cAddress Reference source address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackGetSourceReferenceAddress()                               SpiritPktCommonGetTransmittedDestAddress()
+
+
+/**
+ * @brief  Returns the settled destination address.
+ * @param  None.
+ * @retval uint8_t Transmitted destination address.
+ */
+#define SpiritPktStackGetTransmittedDestAddress()                               SpiritPktCommonGetTransmittedDestAddress()
+
+
+/**
+ * @brief  Sets the node address. When the filtering on my address is on, if the destination address extracted from the received packet is equal to the content of the
+ *         my address, then the packet is accepted (this is the address of the node).
+ * @param  cAddress Address of the present node.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetMyAddress(cAddress)                                    SpiritPktCommonSetMyAddress(cAddress)
+
+
+/**
+ * @brief  Returns the address of the present node.
+ * @param  None.
+ * @retval uint8_t My address (address of this node).
+ */
+#define SpiritPktStackGetMyAddress()                                            SpiritPktCommonGetMyAddress()
+
+
+/**
+ * @brief  Sets the broadcast address. When the broadcast filtering is on, if the destination address extracted from the received packet is equal to the content of the
+ *         BROADCAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Broadcast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetBroadcastAddress(cAddress)                             SpiritPktCommonSetBroadcastAddress(cAddress)
+
+
+/**
+ * @brief  Returns the broadcast address.
+ * @param  None.
+ * @retval uint8_t Broadcast address.
+ */
+#define SpiritPktStackGetBroadcastAddress()                                     SpiritPktCommonGetBroadcastAddress()
+
+
+/**
+ * @brief  Sets the multicast address. When the multicast filtering is on, if the destination address extracted from the received packet is equal to the content of the
+ *         MULTICAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Multicast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetMulticastAddress(cAddress)                             SpiritPktCommonSetMulticastAddress(cAddress)
+
+
+/**
+ * @brief  Returns the multicast address.
+ * @param  None.
+ * @retval uint8_t Multicast address.
+ */
+#define SpiritPktStackGetMulticastAddress()                                     SpiritPktCommonGetMulticastAddress()
+
+
+/**
+ * @brief  Sets the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  lMask Control mask.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetCtrlMask(lMask)                                        SpiritPktCommonSetCtrlMask(lMask)
+
+
+/**
+ * @brief  Returns the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  None.
+ * @retval uint32_t Control mask.
+ */
+#define SpiritPktStackGetCtrlMask()                                             SpiritPktCommonGetCtrlMask()
+
+
+/**
+ * @brief  Sets the control field reference. If the bits enabled by the
+ *         CONTROL_MASK match the ones of the control fields extracted from the received packet
+ *         then the packet is accepted.
+ * @param  lReference Control reference.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetCtrlReference(lReference)                              SpiritPktCommonSetCtrlReference(lReference)
+
+
+/**
+ * @brief  Returns the control field reference.
+ * @param  None.
+ * @retval uint32_t Control reference.
+ */
+#define SpiritPktStackGetCtrlReference()                                        SpiritPktCommonGetCtrlReference()
+
+
+/**
+ * @brief  Sets the TX control field.
+ * @param  lField TX CONTROL FIELD.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+#define SpiritPktStackSetTransmittedCtrlField(lField)                           SpiritPktCommonSetTransmittedCtrlField(lField)
+
+
+/**
+ * @brief  Returns the TX control field.
+ * @param  None.
+ * @retval uint32_t Control field of the transmitted packet.
+ */
+#define SpiritPktStackGetTransmittedCtrlField()                                 SpiritPktCommonGetTransmittedCtrlField()
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with TX_SOURCE_ADDRESS.
+ * @param  xNewState new state for DEST_VS_SOURCE_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackFilterOnMyAddress(xNewState)                               SpiritPktCommonFilterOnMyAddress(xNewState)
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with MULTICAST_ADDRESS.
+ * @param  xNewState new state for DEST_VS_MULTICAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackFilterOnMulticastAddress(xNewState)                        SpiritPktCommonFilterOnMulticastAddress(xNewState)
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with BROADCAST_ADDRESS.
+ * @param  xNewState new state for DEST_VS_BROADCAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackFilterOnBroadcastAddress(xNewState)                        SpiritPktCommonFilterOnBroadcastAddress(xNewState)
+
+
+/**
+ * @brief  Returns the enable bit of the my address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalStateThis parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktStackGetFilterOnMyAddress()                                    SpiritPktCommonGetFilterOnMyAddress();
+
+
+/**
+ * @brief  Returns the enable bit of the multicast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktStackGetFilterOnMulticastAddress()                             SpiritPktCommonGetFilterOnMulticastAddress();
+
+
+/**
+ * @brief  Returns the enable bit of the broadcast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktStackGetFilterOnBroadcastAddress()                             SpiritPktCommonGetFilterOnBroadcastAddress();
+
+
+/**
+ * @brief  Returns the control field of the received packet.
+ * @param  None.
+ * @retval uint32_t Received control field.
+ */
+#define SpiritPktStackGetReceivedCtrlField()                                     SpiritPktCommonGetReceivedCtrlField()
+
+
+/**
+ * @brief  Returns the CRC field of the received packet.
+ * @param  cCrcFieldVect array in which the CRC field has to be stored.
+ *         This parameter is an uint8_t array of 3 elements.
+ * @retval None.
+ */
+#define SpiritPktStackGetReceivedCrcField(cCrcFieldVect)                         SpiritPktCommonGetReceivedCrcField(cCrcFieldVect)
+
+/**
+ * @brief  Sets the AUTO ACKNOLEDGEMENT mechanism on the receiver. When the feature is enabled and
+ *         a data packet has been correctly received, then an acknowledgement packet is sent back to the originator of the received
+ *         packet. If the PIGGYBACKING bit is also set, payload data will be read from the FIFO; otherwise an empty packet is sent
+ *         only containing the source and destination addresses and the sequence number of the packet being acknowledged.
+ * @param  xAutoAck new state for autoack.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @param  xPiggybacking new state for autoack.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackAutoAck(xAutoAck, xPiggybacking)                          SpiritPktCommonAutoAck(xAutoAck, xPiggybacking)
+
+
+/**
+ * @brief  Sets the AUTO ACKNOLEDGEMENT mechanism on the transmitter. On the transmitter side, the NACK_TX field can be used to require or not an acknowledgment for each individual packet: if
+ *         NACK_TX is set to "1" then acknowledgment will not be required; if NACK_TX is set to "0" then acknowledgment will be
+ *         required.
+ * @param  xNewState new state for TX_AUTOACK.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackRequireAck(xNewState)                                     SpiritPktCommonRequireAck(xNewState)
+
+
+/**
+ * @brief  Sets the TX sequence number to be used to start counting.
+ * @param  cSeqNumberReload new value for Tx seq number reload.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+#define SpiritPktStackSetTransmittedSeqNumberReload(cSeqNumberReload)           SpiritPktCommonSetTransmittedSeqNumberReload(cSeqNumberReload)
+
+
+/**
+ * @brief  Sets the max number of automatic retransmission.
+ * @param  xNMaxReTx max number of retransmission.
+ *         This parameter can be any value of @ref PktNMaxReTx.
+ * @retval None.
+ */
+#define SpiritPktStackSetNMaxReTx(xNMaxReTx)                                    SpiritPktCommonSetNMaxReTx((PktNMaxReTx)xNMaxReTx)
+
+
+/**
+ * @brief  Returns the max number of automatic retransmission.
+ * @param  None.
+ * @retval uint8_t Max number of retransmissions.
+ */
+#define SpiritPktStackGetNMaxReTx()                                             SpiritPktCommonGetNMaxReTx()
+
+
+/**
+ * @brief  Returns the TX ACK request.
+ * @param  None.
+ * @retval SpiritFunctionalState.
+ */
+#define SpiritPktStackGetGetTxAckRequest()                                       SpiritPktCommonGetTxAckRequest()
+
+/**
+ * @brief  Returns the destination address of the received packet.
+ * @param  None.
+ * @retval uint8_t Destination address of the received packet.
+ */
+#define SpiritPktStackGetReceivedDestAddress()                                  SpiritPktCommonGetReceivedDestAddress()
+
+
+/**
+ * @brief  Returns the source address of the received packet.
+ * @param  None.
+ * @retval uint8_t Source address of the received packet.
+ */
+#define SpiritPktStackGetReceivedSourceAddress()                                SpiritPktCommonGetReceivedSourceAddress()
+
+
+/**
+ * @brief  Returns the sequence number of the received packet.
+ * @param  None.
+ * @retval uint8_t Received Sequence number.
+ */
+#define SpiritPktStackGetReceivedSeqNumber()                                    SpiritPktCommonGetReceivedSeqNumber()
+
+
+/**
+ * @brief  Returns the Nack bit of the received packet
+ * @param  None.
+ * @retval uint8_t Value of the NAck bit.
+ */
+#define SpiritPktStackGetReceivedNackRx()                                       SpiritPktCommonGetReceivedNackRx()
+
+
+/**
+ * @brief  Returns the sequence number of the transmitted packet.
+ * @param  None.
+ * @retval uint8_t Sequence number of the transmitted packet.
+ */
+#define SpiritPktStackGetTransmittedSeqNumber()                                 SpiritPktCommonGetTransmittedSeqNumber()
+
+
+/**
+ * @brief  Returns the number of retransmission done on the transmitted packet.
+ * @param  None.
+ * @retval uint8_t Number of retransmissions done until now.
+ */
+#define SpiritPktStackGetNReTx()                                                SpiritPktCommonGetNReTx()
+
+
+/**
+ * @brief  If enabled RX packet is accepted only if the masked control field matches the
+ *         masked control field reference (CONTROL_MASK & CONTROL_FIELD_REF == CONTROL_MASK & RX_CONTROL_FIELD).
+ * @param  xNewState new state for Control filtering enable bit.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ * @note   This filtering control is enabled by default but the control mask is by default set to 0.
+ *         As a matter of fact the user has to enable the control filtering bit after the packet initialization
+ *         because the PktInit routine disables it.
+ */
+#define SpiritPktStackFilterOnControlField(xNewState)                           SpiritPktCommonFilterOnControlField(xNewState)
+
+
+/**
+ * @brief  Returns the enable bit of the control field filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+#define SpiritPktStackGetFilterOnControlField()                                 SpiritPktCommonGetFilterOnControlField();
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Exported_Functions        Pkt STack Exported Functions
+ * @{
+ */
+
+void SpiritPktStackInit(PktStackInit* pxPktStackInit);
+void SpiritPktStackGetInfo(PktStackInit* pxPktStackInit);
+void SpiritPktStackAddressesInit(PktStackAddressesInit* pxPktStackAddresses);
+void SpiritPktStackGetAddressesInfo(PktStackAddressesInit* pxPktStackAddresses);
+void SpiritPktStackLlpInit(PktStackLlpInit* pxPktStackLlpInit);
+void SpiritPktStackLlpGetInfo(PktStackLlpInit* pxPktStackLlpInit);
+void SpiritPktStackSetFormat(void);
+void SpiritPktStackSetPayloadLength(uint16_t nPayloadLength);
+uint16_t SpiritPktStackGetPayloadLength(void);
+void SpiritPktStackSetVarLengthWidth(uint16_t nMaxPayloadLength, StackControlLength xControlLength);
+void SpiritPktStackSetRxSourceMask(uint8_t cMask);
+uint8_t SpiritPktStackGetRxSourceMask(void);
+uint16_t SpiritPktStackGetReceivedPktLength(void);
+void SpiritPktStackFilterOnSourceAddress(SpiritFunctionalState xNewState);
+void SpiritPktStackSetAddressLength(void);
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Qi.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Qi.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,300 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Qi.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT QI.
+ * @details
+ *
+ * This module can be used to configure and read some quality indicators
+ * used by Spirit.
+ * API to set thresholds and to read values in raw mode or in dBm are
+ * provided.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *   float rssiValuedBm;
+ *   uint8_t pqiValue, sqiValue;
+ *
+ *   SpiritQiPqiCheck(S_ENABLE);
+ *   SpiritQiSqiCheck(S_ENABLE);
+ *
+ *   ...
+ *
+  *   rssiValueDbm = SpiritQiGetRssidBm();
+ *   pqiValue = SpiritQiGetPqi();
+ *   sqiValue = SpiritQiGetSqi();
+ *
+ *   ...
+ *
+ * @endcode
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_QI_H
+#define __SPIRIT_QI_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Qi          QI
+ * @brief Configuration and management of SPIRIT QI.
+ * @details See the file <i>@ref SPIRIT_Qi.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Qi_Exported_Types  QI Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  PQI threshold value enumeration.
+ */
+typedef enum
+{
+   PQI_TH_0=0x00,
+   PQI_TH_1=0x04,
+   PQI_TH_2=0x08,
+   PQI_TH_3=0x0C,
+   PQI_TH_4=0x10,
+   PQI_TH_5=0x14,
+   PQI_TH_6=0x18,
+   PQI_TH_7=0x1C,
+   PQI_TH_8=0x20,
+   PQI_TH_9=0x24,
+   PQI_TH_10=0x28,
+   PQI_TH_11=0x2C,
+   PQI_TH_12=0x30,
+   PQI_TH_13=0x34,
+   PQI_TH_14=0x38,
+   PQI_TH_15=0x3C
+
+} PqiThreshold;
+
+#define IS_PQI_THR(VALUE)   (VALUE==PQI_TH_0 ||\
+                             VALUE==PQI_TH_1 ||\
+                             VALUE==PQI_TH_2 ||\
+                             VALUE==PQI_TH_3 ||\
+                             VALUE==PQI_TH_4 ||\
+                             VALUE==PQI_TH_5 ||\
+                             VALUE==PQI_TH_6 ||\
+                             VALUE==PQI_TH_7 ||\
+                             VALUE==PQI_TH_8 ||\
+                             VALUE==PQI_TH_9 ||\
+                             VALUE==PQI_TH_10 ||\
+                             VALUE==PQI_TH_11 ||\
+                             VALUE==PQI_TH_12 ||\
+                             VALUE==PQI_TH_13 ||\
+                             VALUE==PQI_TH_14 ||\
+                             VALUE==PQI_TH_15)
+
+/**
+ * @brief  SQI threshold value enumeration.
+ */
+typedef enum
+{
+   SQI_TH_0=0x00,
+   SQI_TH_1=0x40,
+   SQI_TH_2=0x80,
+   SQI_TH_3=0xC0
+
+} SqiThreshold;
+
+#define IS_SQI_THR(VALUE)   (VALUE==SQI_TH_0 ||\
+                             VALUE==SQI_TH_1 ||\
+                             VALUE==SQI_TH_2 ||\
+                             VALUE==SQI_TH_3)
+
+
+/**
+ * @brief  RSSI filter gain value enumeration.
+ */
+typedef enum
+{
+   RSSI_FG_0=0x00,
+   RSSI_FG_1=0x10,
+   RSSI_FG_2=0x20,
+   RSSI_FG_3=0x30,
+   RSSI_FG_4=0x40,
+   RSSI_FG_5=0x50,
+   RSSI_FG_6=0x60,
+   RSSI_FG_7=0x70,
+   RSSI_FG_8=0x80,
+   RSSI_FG_9=0x90,
+   RSSI_FG_10=0xA0,
+   RSSI_FG_11=0xB0,
+   RSSI_FG_12=0xC0,
+   RSSI_FG_13=0xD0,
+   RSSI_FG_14=0xE0,     /*<! recommended value */
+   RSSI_FG_15=0xF0
+
+} RssiFilterGain;
+
+#define IS_RSSI_FILTER_GAIN(VALUE)  (VALUE==RSSI_FG_0 ||\
+                                     VALUE==RSSI_FG_1 ||\
+                                     VALUE==RSSI_FG_2 ||\
+                                     VALUE==RSSI_FG_3 ||\
+                                     VALUE==RSSI_FG_4 ||\
+                                     VALUE==RSSI_FG_5 ||\
+                                     VALUE==RSSI_FG_6 ||\
+                                     VALUE==RSSI_FG_7 ||\
+                                     VALUE==RSSI_FG_8 ||\
+                                     VALUE==RSSI_FG_9 ||\
+                                     VALUE==RSSI_FG_10 ||\
+                                     VALUE==RSSI_FG_11 ||\
+                                     VALUE==RSSI_FG_12 ||\
+                                     VALUE==RSSI_FG_13 ||\
+                                     VALUE==RSSI_FG_14 ||\
+                                     VALUE==RSSI_FG_15)
+
+/**
+ * @brief  CS mode enumeration.
+ */
+typedef enum
+{
+   CS_MODE_STATIC_3DB=0x00,
+   CS_MODE_DYNAMIC_6DB=0x04,
+   CS_MODE_DYNAMIC_12DB=0x08,
+   CS_MODE_DYNAMIC_18DB=0x0C
+
+} CSMode;
+
+#define IS_CS_MODE(MODE)    (MODE==CS_MODE_STATIC_3DB ||\
+                             MODE==CS_MODE_DYNAMIC_6DB ||\
+                             MODE==CS_MODE_DYNAMIC_12DB ||\
+                             MODE==CS_MODE_DYNAMIC_18DB)
+
+/**
+  *@}
+  */
+
+
+/**
+ * @defgroup Qi_Exported_Constants      QI Exported Constants
+ * @{
+ */
+
+/*  range for the RSSI Threshold in dBm  */
+#define IS_RSSI_THR_DBM(VALUE)  (VALUE>=-130 && VALUE<=-2)
+
+/**
+  *@}
+  */
+
+
+/**
+ * @defgroup Qi_Exported_Macros         QI Exported Macros
+ * @{
+ */
+
+/**
+ * @brief  Macro to obtain the RSSI value in dBm
+ * @param  None.
+ * @retval RSSI in dBm.
+ *         This parameter is a float.
+ */
+#define SpiritQiGetRssidBm()            (-120.0+((float)(SpiritQiGetRssi()-20))/2)
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Exported_Functions       QI Exported Functions
+ * @{
+ */
+
+void SpiritQiPqiCheck(SpiritFunctionalState xNewState);
+void SpiritQiSqiCheck(SpiritFunctionalState xNewState);
+void SpiritQiSetPqiThreshold(PqiThreshold xPqiThr);
+PqiThreshold SpiritQiGetPqiThreshold(void);
+void SpiritQiSetSqiThreshold(SqiThreshold xSqiThr);
+SqiThreshold SpiritQiGetSqiThreshold(void);
+void SpiritQiSetRssiThreshold(uint8_t cRssiThr);
+uint8_t SpiritQiGetRssiThreshold(void);
+uint8_t SpiritQiComputeRssiThreshold(int cDbmValue);
+void SpiritQiSetRssiThresholddBm(int nDbmValue);
+uint8_t SpiritQiGetPqi(void);
+uint8_t SpiritQiGetSqi(void);
+uint8_t SpiritQiGetLqi(void);
+SpiritFlagStatus SpiritQiGetCs(void);
+uint8_t SpiritQiGetRssi(void);
+void SpiritQiSetRssiFilterGain(RssiFilterGain xRssiFg);
+RssiFilterGain SpiritQiGetRssiFilterGain(void);
+void SpiritQiSetCsMode(CSMode xCsMode);
+CSMode SpiritQiGetCsMode(void);
+void SpiritQiCsTimeoutMask(SpiritFunctionalState xNewState);
+void SpiritQiPqiTimeoutMask(SpiritFunctionalState xNewState);
+void SpiritQiSqiTimeoutMask(SpiritFunctionalState xNewState);
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Radio.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Radio.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,636 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Radio.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   This file provides all the low level API to manage Analog and Digital
+  *          radio part of SPIRIT.
+ * @details
+ *
+ * In order to configure the Radio main parameters, the user can
+ * fit <i>SRadioInit</i> structure the and call the <i>SpiritRadioInit()</i>
+ * function passing its pointer as an argument.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ * SRadioInit radioInit = {
+ *     0,                       // Xtal offset in ppm
+ *     433.4e6,                 // base frequency
+ *     20e3,                    // channel space
+ *     0,                       // channel number
+ *     FSK,                     // modulation select
+ *     38400,                   // datarate
+ *     20e3,                    // frequency deviation
+ *     100.5e3                  // channel filter bandwidth
+ * };
+ *
+ * ...
+ *
+ * SpiritRadioInit(&radioInit);
+ * @endcode
+ *
+ * Another important parameter for the radio configuration is the
+ * transmission power.
+ * The user is allowed to configure it using the function <i>SpiritRadioSetPALeveldBm()</i>
+ * which sets the PA LEVEL specified by the first argument to the
+ * power expressed in dBm by the second parameter.
+ *
+ * <b>Example:</b>
+ * @code
+ *
+ *  SpiritRadioSetPALeveldBm(0 , 10.0);
+ *
+ * @endcode
+ *
+ *
+ * @note The effective power that is set can be a little different from the
+ * passed argument in dBm because the function performs an approximation.
+ *
+
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_RADIO_H
+#define __SPIRIT_RADIO_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+#include "SPIRIT_Config.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/** @defgroup SPIRIT_Radio          Radio
+ * @brief Configuration and management of SPIRIT RF Analog and Digital part.
+ * @details See the file <i>@ref SPIRIT_Radio.h</i> for more details.
+ * @{
+ */
+
+
+
+/** @defgroup Radio_Exported_Types      Radio Exported Types
+ * @{
+ */
+
+
+/**
+ * @brief  SPIRIT XTAL frequency enumeration
+ */
+typedef enum
+{
+  XTAL_FLAG_24_MHz     = 0x00, /*!< 24 MHz Xtal selected */
+  XTAL_FLAG_26_MHz     = 0x01  /*!< 26 MHz Xtal selected */
+
+}XtalFlag;
+
+
+#define IS_XTAL_FLAG(FLAG) (((FLAG) == XTAL_FLAG_24_MHz) || \
+                            ((FLAG) == XTAL_FLAG_26_MHz))
+
+/**
+ * @brief  SPIRIT Band enumeration
+ */
+typedef enum
+{
+  HIGH_BAND     = 0x00, /*!< High_Band selected: from 779 MHz to 915 MHz */
+  MIDDLE_BAND   = 0x01, /*!< Middle Band selected: from 387 MHz to 470 MHz */
+  LOW_BAND      = 0x02,  /*!< Low Band selected: from 300 MHz to 348 MHz */
+  VERY_LOW_BAND = 0x03  /*!< Vary low Band selected: from 150 MHz to 174 MHz */
+}BandSelect;
+
+
+#define IS_BAND_SELECTED(BAND) ((BAND == HIGH_BAND) || \
+                                (BAND == MIDDLE_BAND) || \
+                                (BAND == LOW_BAND) || \
+                                (BAND == VERY_LOW_BAND))
+
+/**
+ * @brief  SPIRIT Modulation enumeration
+ */
+typedef enum
+{
+  FSK         = 0x00, /*!< 2-FSK modulation selected */
+  GFSK_BT05   = 0x50, /*!< GFSK modulation selected with BT=0.5 */
+  GFSK_BT1    = 0x10, /*!< GFSK modulation selected with BT=1 */
+  ASK_OOK     = 0x20, /*!< ASK or OOK modulation selected. ASK will use power ramping */
+  MSK         = 0x30  /*!< MSK modulation selected */
+
+}ModulationSelect;
+
+
+#define IS_MODULATION_SELECTED(MOD) (((MOD) == FSK) || \
+                                     ((MOD) == GFSK_BT05) || \
+                                     ((MOD) == GFSK_BT1) || \
+                                     ((MOD) == ASK_OOK) || \
+                                     ((MOD) == MSK))
+
+
+/**
+ * @brief  SPIRIT PA additional load capacitors bank enumeration
+ */
+typedef enum
+{
+  LOAD_0_PF    = PA_POWER0_CWC_0,    /*!< No additional PA load capacitor */
+  LOAD_1_2_PF  = PA_POWER0_CWC_1_2P, /*!< 1.2pF additional PA load capacitor */
+  LOAD_2_4_PF  = PA_POWER0_CWC_2_4P, /*!< 2.4pF additional PA load capacitor */
+  LOAD_3_6_PF  = PA_POWER0_CWC_3_6P  /*!< 3.6pF additional PA load capacitor */
+
+}PALoadCapacitor;
+
+#define IS_PA_LOAD_CAP(CWC) (((CWC) == LOAD_0_PF) || \
+                             ((CWC) == LOAD_1_2_PF) || \
+                             ((CWC) == LOAD_2_4_PF) || \
+                             ((CWC) == LOAD_3_6_PF))
+
+
+/**
+ * @brief  SPIRIT AFC Mode selection
+ */
+typedef enum
+{
+  AFC_SLICER_CORRECTION  = AFC2_AFC_MODE_SLICER,    /*!< AFC loop closed on slicer */
+  AFC_2ND_IF_CORRECTION  = AFC2_AFC_MODE_MIXER      /*!< AFC loop closed on 2nd conversion stage */
+
+}AFCMode;
+
+#define IS_AFC_MODE(MODE)   ((MODE) == AFC_SLICER_CORRECTION || (MODE) == AFC_2ND_IF_CORRECTION)
+
+
+/**
+ * @brief  SPIRIT AGC Mode selection
+ */
+typedef enum
+{
+  AGC_LINEAR_MODE  = AGCCTRL0_AGC_MODE_LINEAR,    /*!< AGC works in linear mode */
+  AGC_BINARY_MODE  = AGCCTRL0_AGC_MODE_BINARY     /*!< AGC works in binary mode */
+
+}AGCMode;
+
+#define IS_AGC_MODE(MODE)   ((MODE) == AGC_LINEAR_MODE || (MODE) == AGC_BINARY_MODE)
+
+
+/**
+ * @brief  SPIRIT Clock Recovery Mode selection
+ */
+typedef enum
+{
+  CLK_REC_PLL  = FDEV0_CLOCK_REG_ALGO_SEL_PLL,    /*!< PLL alogrithm for clock recovery */
+  CLK_REC_DLL  = FDEV0_CLOCK_REG_ALGO_SEL_DLL     /*!< DLL alogrithm for clock recovery */
+
+}ClkRecMode;
+
+#define IS_CLK_REC_MODE(MODE)   ((MODE) == CLK_REC_PLL || (MODE) == CLK_REC_DLL)
+
+
+/**
+ * @brief  SPIRIT Postfilter length
+ */
+typedef enum
+{
+  PSTFLT_LENGTH_8   = 0x00,    /*!< Postfilter length is 8 symbols */
+  PSTFLT_LENGTH_16  = 0x10     /*!< Postfilter length is 16 symbols */
+
+}PstFltLength;
+
+#define IS_PST_FLT_LENGTH(LENGTH)   ((LENGTH) == PSTFLT_LENGTH_8 || (LENGTH) == PSTFLT_LENGTH_16)
+
+
+/**
+ * @brief  SPIRIT OOK Peak Decay
+ */
+typedef enum
+{
+  FAST_DECAY   = 0x00,        /*!< Peak decay control for OOK: fast decay */
+  MEDIUM_FAST_DECAY  = 0x01,  /*!< Peak decay control for OOK: medium_fast decay */
+  MEDIUM_SLOW_DECAY = 0x02,   /*!< Peak decay control for OOK: medium_fast decay */
+  SLOW_DECAY = 0x03           /*!< Peak decay control for OOK: slow decay */
+
+}OokPeakDecay;
+
+#define IS_OOK_PEAK_DECAY(DECAY)   (((DECAY) == FAST_DECAY) ||\
+                                    ((DECAY) == MEDIUM_FAST_DECAY) ||\
+                                    ((DECAY) == MEDIUM_SLOW_DECAY) ||\
+                                    ((DECAY) == SLOW_DECAY))
+
+
+/**
+ * @brief  SPIRIT Radio Init structure definition
+ */
+typedef struct
+{
+  int16_t           nXtalOffsetPpm;     /*!< Specifies the offset frequency (in ppm)
+                                             to compensate crystal inaccuracy expressed
+                                             as signed value.*/
+
+  uint32_t          lFrequencyBase;     /*!< Specifies the base carrier frequency (in Hz),
+                                             i.e. the carrier frequency of channel #0.
+                                             This parameter can be in one of the following ranges:
+                                             High_Band: from 779 MHz to 915 MHz
+                                             Middle Band: from 387 MHz to 470 MHz
+                                             Low Band: from 300 MHz to 348 MHz */
+  uint32_t          nChannelSpace;      /*!< Specifies the channel spacing expressed in Hz.
+                                             The channel spacing is expressed as:
+                                             NxFREQUENCY_STEPS, where FREQUENCY STEPS
+                                             is F_Xo/2^15.
+                                             This parameter can be in the range: [0, F_Xo/2^15*255] Hz */
+  uint8_t           cChannelNumber;      /*!< Specifies the channel number. This value
+                                             is multiplied by the channel spacing and
+                                             added to synthesizer base frequency to
+                                             generate the actual RF carrier frequency */
+  ModulationSelect  xModulationSelect;   /*!< Specifies the modulation. This
+                                             parameter can be any value of
+                                             @ref ModulationSelect */
+  uint32_t          lDatarate;          /*!< Specifies the datarate expressed in bps.
+                                             This parameter can be in the range between
+                                             100 bps and 500 kbps */
+  uint32_t          lFreqDev;           /*!< Specifies the frequency deviation expressed in Hz.
+                                             This parameter can be in the range: [F_Xo*8/2^18, F_Xo*7680/2^18] Hz */
+  uint32_t          lBandwidth;          /*!< Specifies the channel filter bandwidth
+                                             expressed in Hz. This parameter can be
+                                             in the range between 1100 and 800100 Hz */
+
+}SRadioInit;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Radio_Exported_Constants       Radio Exported Constants
+ * @{
+ */
+
+/** @defgroup Radio_Band
+ * @{
+ */
+
+#define FBASE_DIVIDER           262144           /*!< 2^18 factor dividing fxo in fbase formula */
+
+#define HIGH_BAND_FACTOR      6       /*!< Band select factor for high band. Factor B in the equation 2 */
+#define MIDDLE_BAND_FACTOR    12      /*!< Band select factor for middle band. Factor B in the equation 2 */
+#define LOW_BAND_FACTOR       16      /*!< Band select factor for low band. Factor B in the equation 2 */
+#define VERY_LOW_BAND_FACTOR  32      /*!< Band select factor for very low band. Factor B in the equation 2 */
+
+#define HIGH_BAND_LOWER_LIMIT         778000000   /*!< Lower limit of the high band: 779 MHz */
+#define HIGH_BAND_UPPER_LIMIT         957100000   /*!< Upper limit of the high band: 956 MHz */
+#define MIDDLE_BAND_LOWER_LIMIT       386000000   /*!< Lower limit of the middle band: 387 MHz */
+#define MIDDLE_BAND_UPPER_LIMIT       471100000   /*!< Upper limit of the middle band: 470 MHz */
+#define LOW_BAND_LOWER_LIMIT          299000000   /*!< Lower limit of the low band: 300 MHz */
+#define LOW_BAND_UPPER_LIMIT          349100000   /*!< Upper limit of the low band: 348 MHz */
+#define VERY_LOW_BAND_LOWER_LIMIT     149000000   /*!< Lower limit of the very low band: 150 MHz */
+#define VERY_LOW_BAND_UPPER_LIMIT     175100000   /*!< Upper limit of the very low band: 174 MHz */
+
+#define IS_FREQUENCY_BAND_HIGH(FREQUENCY) ((FREQUENCY)>=HIGH_BAND_LOWER_LIMIT && \
+                                           (FREQUENCY)<=HIGH_BAND_UPPER_LIMIT)
+
+#define IS_FREQUENCY_BAND_MIDDLE(FREQUENCY) ((FREQUENCY)>=MIDDLE_BAND_LOWER_LIMIT && \
+                                             (FREQUENCY)<=MIDDLE_BAND_UPPER_LIMIT)
+
+#define IS_FREQUENCY_BAND_LOW(FREQUENCY) ((FREQUENCY)>=LOW_BAND_LOWER_LIMIT && \
+                                          (FREQUENCY)<=LOW_BAND_UPPER_LIMIT)
+
+#define IS_FREQUENCY_BAND_VERY_LOW(FREQUENCY) ((FREQUENCY)>=VERY_LOW_BAND_LOWER_LIMIT && \
+                                          (FREQUENCY)<=VERY_LOW_BAND_UPPER_LIMIT)
+
+#define IS_FREQUENCY_BAND(FREQUENCY) (IS_FREQUENCY_BAND_HIGH(FREQUENCY)|| \
+                                      IS_FREQUENCY_BAND_MIDDLE(FREQUENCY)|| \
+                                      IS_FREQUENCY_BAND_LOW(FREQUENCY)|| \
+                                      IS_FREQUENCY_BAND_VERY_LOW(FREQUENCY))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_IF_Offset           Radio IF Offset
+ * @{
+ */
+#define IF_OFFSET_ANA(F_Xo) (lroundf(480140.0/(F_Xo)*12288-64.0))      /*!< It represents the IF_OFFSET_ANA in order
+                                                                               to have an intermediate frequency of 480 kHz */
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_FC_Offset                   Radio FC Offset
+ * @{
+ */
+#define F_OFFSET_DIVIDER           262144             /*!< 2^18 factor dividing fxo in foffset formula */
+#define PPM_FACTOR                 1000000            /*!< 10^6 factor to use with Xtal_offset_ppm */
+
+
+#define F_OFFSET_LOWER_LIMIT(F_Xo)			((-(int32_t)F_Xo)/F_OFFSET_DIVIDER*2048)
+#define F_OFFSET_UPPER_LIMIT(F_Xo)			((int32_t)(F_Xo/F_OFFSET_DIVIDER*2047))
+
+#define IS_FREQUENCY_OFFSET(OFFSET, F_Xo) (OFFSET>=F_OFFSET_LOWER_LIMIT(F_Xo) && OFFSET<=F_OFFSET_UPPER_LIMIT(F_Xo))
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Channel_Space          Radio Channel Space
+ * @{
+ */
+
+
+#define CHSPACE_DIVIDER         32768              /*!< 2^15 factor dividing fxo in channel space formula */
+
+#define IS_CHANNEL_SPACE(CHANNELSPACE, F_Xo)    (CHANNELSPACE<=(F_Xo/32768*255))
+
+
+
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Datarate                    Radio Datarate
+ * @{
+ */
+#define MINIMUM_DATARATE                 100  /*!< Minimum datarate supported by SPIRIT1 100 bps */
+#define MAXIMUM_DATARATE                 510000  /*!< Maximum datarate supported by SPIRIT1 500 kbps */
+
+#define IS_DATARATE(DATARATE)           (DATARATE>=MINIMUM_DATARATE && DATARATE<=MAXIMUM_DATARATE)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Frequency_Deviation         Radio Frequency Deviation
+ * @{
+ */
+#define F_DEV_MANTISSA_UPPER_LIMIT      7  /*!< Maximum value for the mantissa in frequency deviation formula */
+#define F_DEV_EXPONENT_UPPER_LIMIT      9  /*!< Maximum value for the exponent in frequency deviation formula */
+
+#define F_DEV_LOWER_LIMIT(F_Xo)		(F_Xo>>16)
+#define F_DEV_UPPER_LIMIT(F_Xo)		((F_Xo*15)>>10)
+
+#define IS_F_DEV(FDEV,F_Xo)             (FDEV>=F_DEV_LOWER_LIMIT(F_Xo) && FDEV<=F_DEV_UPPER_LIMIT(F_Xo))
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Channel_Bandwidth           Radio Channel Bandwidth
+ * @{
+ */
+#define CH_BW_LOWER_LIMIT(F_Xo)      1100*(F_Xo/1000000)/26  /*!< Minimum value of the channel filter bandwidth */
+#define CH_BW_UPPER_LIMIT(F_Xo)    800100*(F_Xo/1000000)/26  /*!< Maximum value of the channel filter bandwidth */
+
+#define IS_CH_BW(BW,F_Xo)         ((BW)>=CH_BW_LOWER_LIMIT(F_Xo) && (BW)<=CH_BW_UPPER_LIMIT(F_Xo))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Power_Amplifier                     Radio Power Amplifier
+ * @{
+ */
+
+#define IS_PA_MAX_INDEX(INDEX)       ((INDEX)<=7)
+#define IS_PAPOWER_DBM(PATABLE)      ((PATABLE)>= (-31) && (PATABLE)<=(12))
+#define IS_PAPOWER(PATABLE)          ((PATABLE)<=90)
+#define IS_PA_STEP_WIDTH(WIDTH)      ((WIDTH)>=1 && (WIDTH)<=4)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Automatic_Frequency_Correction              Radio Automatic Frequency Correction
+ * @{
+ */
+
+#define IS_AFC_FAST_GAIN(GAIN)      	((GAIN)<=15)
+#define IS_AFC_SLOW_GAIN(GAIN)      	((GAIN)<=15)
+#define IS_AFC_PD_LEAKAGE(LEAKAGE)      ((LEAKAGE)<=31)
+
+/**
+ * @}
+ */
+
+/** @defgroup Radio_Automatic_Gain_Control                      Radio Automatic Gain Control
+ * @{
+ */
+
+#define AGC_MEASURE_TIME_UPPER_LIMIT_US(F_Xo)		(393216.0/F_Xo)
+
+#define IS_AGC_MEASURE_TIME_US(TIME, F_Xo)              (TIME<=AGC_MEASURE_TIME_UPPER_LIMIT_US(F_Xo))
+
+#define IS_AGC_MEASURE_TIME(TIME)                       (TIME<=15)
+
+#define AGC_HOLD_TIME_UPPER_LIMIT_US(F_Xo)		(756.0/F_Xo)
+
+#define IS_AGC_HOLD_TIME_US(TIME,F_Xo)                  (TIME<=AGC_HOLD_TIME_UPPER_LIMIT_US(F_Xo))
+
+
+#define IS_AGC_HOLD_TIME(TIME)                          (TIME<=63)
+
+#define IS_AGC_THRESHOLD(THRESHOLD)                     (THRESHOLD<=15)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Clock_Recovery                      Radio Clock Recovery
+ * @{
+ */
+
+#define IS_CLK_REC_P_GAIN(GAIN)       ((GAIN)<=7)
+#define IS_CLK_REC_I_GAIN(GAIN)       ((GAIN)<=15)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Radio_Exported_Macros                             Radio Exported Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup Radio_Exported_Functions                          Radio Exported Functions
+ * @{
+ */
+
+uint8_t SpiritRadioInit(SRadioInit* pxSRadioInitStruct);
+void SpiritRadioGetInfo(SRadioInit* pxSRadioInitStruct);
+void SpiritRadioSetXtalFlag(XtalFlag xXtal);
+XtalFlag SpiritRadioGetXtalFlag(void);
+uint8_t SpiritRadioSearchWCP(uint32_t lFc);
+void SpiritRadioSetSynthWord(uint32_t lSynthWord);
+uint32_t SpiritRadioGetSynthWord(void);
+void SpiritRadioSetBand(BandSelect xBand);
+BandSelect SpiritRadioGetBand(void);
+void SpiritRadioSetChannel(uint8_t cChannel);
+uint8_t SpiritRadioGetChannel(void);
+void SpiritRadioSetChannelSpace(uint32_t lChannelSpace);
+uint32_t SpiritRadioGetChannelSpace(void);
+void SpiritRadioSetFrequencyOffsetPpm(int16_t nXtalPpm);
+void SpiritRadioSetFrequencyOffset(int32_t lFOffset);
+int32_t SpiritRadioGetFrequencyOffset(void);
+void SpiritRadioVcoCalibrationWAFB(SpiritFunctionalState xNewstate);
+uint8_t SpiritRadioSetFrequencyBase(uint32_t lFBase);
+uint32_t SpiritRadioGetFrequencyBase(void);
+uint32_t SpiritRadioGetCenterFrequency(void);
+void SpiritRadioSearchDatarateME(uint32_t lDatarate, uint8_t* pcM, uint8_t* pcE);
+void SpiritRadioSearchFreqDevME(uint32_t lFDev, uint8_t* pcM, uint8_t* pcE);
+void SpiritRadioSearchChannelBwME(uint32_t lBandwidth, uint8_t* pcM, uint8_t* pcE);
+void SpiritRadioSetDatarate(uint32_t lDatarate);
+uint32_t SpiritRadioGetDatarate(void);
+void SpiritRadioSetFrequencyDev(uint32_t lFDev);
+uint32_t SpiritRadioGetFrequencyDev(void);
+void SpiritRadioSetChannelBW(uint32_t lBandwidth);
+uint32_t SpiritRadioGetChannelBW(void);
+void SpiritRadioSetModulation(ModulationSelect xModulation);
+ModulationSelect SpiritRadioGetModulation(void);
+void SpiritRadioCWTransmitMode(SpiritFunctionalState xNewState);
+void SpiritRadioSetOokPeakDecay(OokPeakDecay xOokDecay);
+OokPeakDecay SpiritRadioGetOokPeakDecay(void);
+uint8_t SpiritRadioGetdBm2Reg(uint32_t lFBase, float fPowerdBm);
+float SpiritRadioGetReg2dBm(uint32_t lFBase, uint8_t cPowerReg);
+void SpiritRadioSetPATabledBm(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, float* pfPAtabledBm);
+void SpiritRadioGetPATabledBm(uint8_t* pcPALevelMaxIndex, float* pfPAtabledBm);
+void SpiritRadioSetPATable(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, uint8_t* pcPAtable);
+void SpiritRadioGetPATable(uint8_t* pcPALevelMaxIndex, uint8_t* pcPAtable);
+void SpiritRadioSetPALeveldBm(uint8_t cIndex, float fPowerdBm);
+float SpiritRadioGetPALeveldBm(uint8_t cIndex);
+void SpiritRadioSetPALevel(uint8_t cIndex, uint8_t cPower);
+uint8_t SpiritRadioGetPALevel(uint8_t cIndex);
+void SpiritRadioSetPACwc(PALoadCapacitor xCLoad);
+PALoadCapacitor SpiritRadioGetPACwc(void);
+void SpiritRadioSetPALevelMaxIndex(uint8_t cIndex);
+uint8_t SpiritRadioGetPALevelMaxIndex(void);
+void SpiritRadioSetPAStepWidth(uint8_t cWidth);
+uint8_t SpiritRadioGetPAStepWidth(void);
+void SpiritRadioPARamping(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritRadioGetPARamping(void);
+void SpiritRadioAFC(SpiritFunctionalState xNewState);
+void SpiritRadioAFCFreezeOnSync(SpiritFunctionalState xNewState);
+void SpiritRadioSetAFCMode(AFCMode xMode);
+AFCMode SpiritRadioGetAFCMode(void);
+void SpiritRadioSetAFCPDLeakage(uint8_t cLeakage);
+uint8_t SpiritRadioGetAFCPDLeakage(void);
+void SpiritRadioSetAFCFastPeriod(uint8_t cLength);
+uint8_t SpiritRadioGetAFCFastPeriod(void);
+void SpiritRadioSetAFCFastGain(uint8_t cGain);
+uint8_t SpiritRadioGetAFCFastGain(void);
+void SpiritRadioSetAFCSlowGain(uint8_t cGain);
+uint8_t SpiritRadioGetAFCSlowGain(void);
+int8_t SpiritRadioGetAFCCorrectionReg(void);
+int32_t SpiritRadioGetAFCCorrectionHz(void);
+void SpiritRadioAGC(SpiritFunctionalState xNewState);
+void SpiritRadioSetAGCMode(AGCMode xMode);
+AGCMode SpiritRadioGetAGCMode(void);
+void SpiritRadioAGCFreezeOnSteady(SpiritFunctionalState xNewState);
+void SpiritRadioAGCFreezeOnSync(SpiritFunctionalState xNewState);
+void SpiritRadioAGCStartMaxAttenuation(SpiritFunctionalState xNewState);
+void SpiritRadioSetAGCMeasureTimeUs(uint16_t nTime);
+uint16_t SpiritRadioGetAGCMeasureTimeUs(void);
+void SpiritRadioSetAGCMeasureTime(uint8_t cTime);
+uint8_t SpiritRadioGetAGCMeasureTime(void);
+void SpiritRadioSetAGCHoldTimeUs(uint8_t cTime);
+uint8_t SpiritRadioGetAGCHoldTimeUs(void);
+void SpiritRadioSetAGCHoldTime(uint8_t cTime);
+uint8_t SpiritRadioGetAGCHoldTime(void);
+void SpiritRadioSetAGCHighThreshold(uint8_t cHighThreshold);
+uint8_t SpiritRadioGetAGCHighThreshold(void);
+void SpiritRadioSetAGCLowThreshold(uint8_t cLowThreshold);
+uint8_t SpiritRadioGetAGCLowThreshold(void);
+void SpiritRadioSetClkRecMode(ClkRecMode xMode);
+ClkRecMode SpiritRadioGetClkRecMode(void);
+void SpiritRadioSetClkRecPGain(uint8_t cPGain);
+uint8_t SpiritRadioGetClkRecPGain(void);
+void SpiritRadioSetClkRecIGain(uint8_t cIGain);
+uint8_t SpiritRadioGetClkRecIGain(void);
+void SpiritRadioSetClkRecPstFltLength(PstFltLength xLength);
+PstFltLength SpiritRadioGetClkRecPstFltLength(void);
+void SpiritRadioCsBlanking(SpiritFunctionalState xNewState);
+void SpiritRadioPersistenRx(SpiritFunctionalState xNewState);
+uint32_t SpiritRadioGetXtalFrequency(void);
+void SpiritRadioSetXtalFrequency(uint32_t lXtalFrequency);
+void SpiritRadioSetRefDiv(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritRadioGetRefDiv(void);
+void SpiritRadioSetDigDiv(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritRadioGetDigDiv(void);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Regs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Regs.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3244 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Regs.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   This file contains all the SPIRIT registers address and masks.
+ * @details
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT1_REGS_H
+#define __SPIRIT1_REGS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ * @addtogroup SPIRIT_Registers         SPIRIT Registers
+ * @brief Header file containing all the SPIRIT registers address and masks.
+ * @details See the file <i>@ref SPIRIT_Regs.h</i> for more details.
+ * @{
+ */
+
+/** @defgroup General_Configuration_Registers
+  * @{
+  */
+
+/** @defgroup ANA_FUNC_CONF_1_Register
+  * @{
+  */
+
+/**
+ *  \brief ANA_FUNC_CONF register 1
+ *  \code
+ *   Read Write
+ *   Default value: 0x0C
+ *   7:5 NUM_EN_PIPES: Number of enabled pipes (starting from Data Pipe 0).
+ *   4:2 GM_CONF[2:0]: Sets the driver gm of the XO at start-up:
+ *       GM_CONF2 | GM_CONF1 | GM_CONF0 | GM [mS]
+ *       ------------------------------------------
+ *           0    |    0     |     0    |  13.2
+ *           0    |    0     |     1    |  18.2
+ *           0    |    1     |     0    |  21.5
+ *           0    |    1     |     1    |  25.6
+ *           1    |    0     |     0    |  28.8
+ *           1    |    0     |     1    |  33.9
+ *           1    |    1     |     0    |  38.5
+ *           1    |    1     |     1    |  43.0
+ *   1:0 SET_BLD_LVL[1:0]: Sets the Battery Level Detector threshold:
+ *       SET_BLD_LVL1 | SET_BLD_LVL0 | Threshold [V]
+ *       ------------------------------------------
+ *             0      |      0       |     2.7
+ *             0      |      1       |     2.5
+ *             1      |      0       |     2.3
+ *             1      |      1       |     2.1
+ *   \endcode
+ */
+
+#define ANA_FUNC_CONF1_BASE					((uint8_t)0x00) /*!< ANA_FUNC_CONF1 Address (R/W) */
+
+#define ANA_FUNC_CONF1_NUM_PIPES_MASK                           ((uint8_t)0xE0) /*!< Mask for number of enabled pipes*/
+
+#define ANA_FUNC_CONF1_GMCONF_MASK		        	((uint8_t)0x1C) /*!< Mask of the GmConf field of ANA_FUNC_CONF1 register (R/W) */
+
+#define GM_13_2				                        ((uint8_t)0x00) /*!< Transconducatance Gm at start-up 13.2 mS */
+#define GM_18_2				                        ((uint8_t)0x04) /*!< Transconducatance Gm at start-up 18.2 mS */
+#define GM_21_5				                        ((uint8_t)0x08) /*!< Transconducatance Gm at start-up 21.5 mS */
+#define GM_25_6				                        ((uint8_t)0x0C) /*!< Transconducatance Gm at start-up 25.6 mS */
+#define GM_28_8				                        ((uint8_t)0x10) /*!< Transconducatance Gm at start-up 28.8 mS */
+#define GM_33_9				                        ((uint8_t)0x14) /*!< Transconducatance Gm at start-up 33.9 mS */
+#define GM_38_5				                        ((uint8_t)0x18) /*!< Transconducatance Gm at start-up 38.5 mS */
+#define GM_43_0				                        ((uint8_t)0x1C) /*!< Transconducatance Gm at start-up 43.0 mS */
+
+#define ANA_FUNC_CONF1_SET_BLD_LVL_MASK		        	((uint8_t)0x03) /*!< Mask of the SET_BLD_LV field of ANA_FUNC_CONF1 register (R/W) */
+
+#define BLD_LVL_2_7				                ((uint8_t)0x00) /*!< Sets the Battery Level Detector threshold to 2.7V */
+#define BLD_LVL_2_5				                ((uint8_t)0x01) /*!< Sets the Battery Level Detector threshold to 2.5V */
+#define BLD_LVL_2_3				                ((uint8_t)0x02) /*!< Sets the Battery Level Detector threshold to 2.3V */
+#define BLD_LVL_2_1				                ((uint8_t)0x03) /*!< Sets the Battery Level Detector threshold to 2.1V */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ANA_FUNC_CONF_0_Register
+ * @{
+ */
+
+/**
+ *  \brief ANA_FUNC_CONF register 0
+ *  \code
+ *   Read Write
+ *   Default value: 0xC0
+ *   7 Reserved.
+ *   6 24_26_MHz_SELECT: 1 - 26 MHz configuration
+ *                       0 - 24 MHz configuration
+ *   5 AES_ON:           1 - AES engine enabled
+ *                       0 - AES engine disabled
+ *   4 EXT_REF:          1 - Reference signal from XIN pin
+ *                       0 - Reference signal from XO circuit
+ *   3 HIGH_POWER_MODE:  1 - SET_SMPS_LEVEL word will be set to the value to
+ *                           PM_TEST register in RX state, while in TX state it
+ *                           will be fixed to 111 (which programs the SMPS output
+ *                           at max value 1.8V)
+ *                       0 - SET_SMPS_LEVEL word will hold the value written in the
+ *                           PM_TEST register both in RX and TX state
+ *   2 BROWN_OUT:        1 - Brown_Out Detection enabled
+ *                       0 - Brown_Out Detection disabled
+ *   1 BATTERY_LEVEL:    1 - Battery level detector enabled
+ *                       0 - Battery level detector disabled
+ *   0 TS:               1 - Enable the "Temperature Sensor" function
+ *                       0 - Disable the "Temperature Sensor" function
+ *   \endcode
+ */
+
+
+#define ANA_FUNC_CONF0_BASE					((uint8_t)0x01) /*!< ANA_FUNC_CONF0 Address (R/W) */
+
+#define SELECT_24_26_MHZ_MASK              			((uint8_t)0x40) /*!< Configure the RCO if using 26 MHz or 24 MHz master clock/reference signal */
+#define AES_MASK                				((uint8_t)0x20) /*!< AES engine on/off */
+#define EXT_REF_MASK          				        ((uint8_t)0x10) /*!< Reference signal from XIN pin (oscillator external) or from XO circuit (oscillator internal)*/
+#define HIGH_POWER_MODE_MASK	                		((uint8_t)0x08) /*!< SET_SMPS_LEVEL word will be set to the value to PM_TEST register
+                                                                                     in RX state, while in TX state it will be fixed to 111
+                                                                                     (which programs the SMPS output at max value, 1.8V) */
+#define BROWN_OUT_MASK  			          	((uint8_t)0x04) /*!< Accurate Brown-Out detection on/off */
+#define BATTERY_LEVEL_MASK  	                		((uint8_t)0x02) /*!< Battery level detector circuit on/off */
+#define TEMPERATURE_SENSOR_MASK 	        		((uint8_t)0x01) /*!< The Temperature Sensor (available on GPIO0) on/off */
+
+/**
+ * @}
+ */
+
+/** @defgroup ANT_SELECT_CONF_Register
+ * @{
+ */
+
+/**
+ *  \brief ANT_SELECT_CONF register
+ *  \code
+ *   Read Write
+ *   Default value: 0x05
+ *
+ *   7:5   Reserved.
+ *
+ *   4   CS_BLANKING: Blank received data if signal is below the CS threshold
+ *
+ *   3   AS_ENABLE: Enable antenna switching
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   2:0 AS_MEAS_TIME[2:0]: Measurement time according to the formula Tmeas = 24*2^(EchFlt)*2^AS_MEAS_TIME/fxo
+ *   \endcode
+ */
+#define	ANT_SELECT_CONF_BASE					((uint8_t)0x27) /*!< Antenna diversity (works only in static carrier sense mode) */
+#define ANT_SELECT_CS_BLANKING_MASK                             ((uint8_t)0x10) /*!< CS data blanking on/off */
+#define ANT_SELECT_CONF_AS_MASK           			((uint8_t)0x08) /*!< Antenna diversity on/off */
+
+/**
+ * @}
+ */
+
+/** @defgroup DEVICE_INFO1_Register
+ * @{
+ */
+
+/**
+ *  \brief DEVICE_INFO1[7:0]  registers
+ *  \code
+ *   Default value: 0x01
+ *   Read
+ *
+ *   7:0       PARTNUM[7:0]:   Device part number
+ *   \endcode
+ */
+#define	DEVICE_INFO1_PARTNUM					((uint8_t)(0xF0)) /*!< Device part number [7:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup DEVICE_INFO0_Register
+ * @{
+ */
+
+/**
+ *  \brief DEVICE_INFO0[7:0]  registers
+ *  \code
+ *   Read
+ *
+ *   7:0       VERSION[7:0]:  Device version number
+ *   \endcode
+ */
+#define	DEVICE_INFO0_VERSION					((uint8_t)(0xF1)) /*!< Device version [7:0]; (0x55 in CUT1.0) */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup GPIO_Registers
+ * @{
+ */
+
+/** @defgroup GPIOx_CONF_Registers
+ * @{
+ */
+
+/**
+ *  \brief GPIOx registers
+ *  \code
+ *   Read Write
+ *   Default value: 0x03
+ *   7:3 GPIO_SELECT[4:0]: Specify the I/O signal.
+ *       GPIO_SELECT[4:0] |    I/O    |      Signal
+ *       ------------------------------------------------
+ *               0        |  Output   |  nIRQ
+ *               0        |  Input    |  TX command
+ *               1        |  Output   |  POR inverted
+ *               1        |  Input    |  RX command
+ *               2        |  Output   |  Wake-Up timer expiration
+ *               2        |  Input    |  TX data for direct modulation
+ *               3        |  Output   |  Low Battery Detection
+ *               3        |  Input    |  Wake-up from external input
+ *               4        |  Output   |  TX clock output
+ *               5        |  Output   |  TX state
+ *               6        |  Output   |  TX FIFO Almost Empty Flag
+ *               7        |  Output   |  TX FIFO ALmost Full Flag
+ *               8        |  Output   |  RX data output
+ *               9        |  Output   |  RX clock output
+ *               10       |  Output   |  RX state
+ *               11       |  Output   |  RX FIFO Almost Full Flag
+ *               12       |  Output   |  RX FIFO Almost Empty Flag
+ *               13       |  Output   |  Antenna switch
+ *               14       |  Output   |  Valid preamble detected
+ *               15       |  Output   |  Sync word detected
+ *               16       |  Output   |  RSSI above threshold
+ *               17       |  Output   |  MCU clock
+ *               18       |  Output   |  TX or RX mode indicator
+ *               19       |  Output   |  VDD
+ *               20       |  Output   |  GND
+ *               21       |  Output   |  External SMPS enable signal
+ *               22-31    |  Not Used |  Not Used
+ *   2 Reserved
+ *   1:0 GpioMode[1:0]: Specify the mode:
+ *        GPIO_MODE1  |  GPIO_MODE0  |               MODE
+ *       ------------------------------------------------------------
+ *             0      |      0       |    Analog (valid only for GPIO_0)
+ *             0      |      1       |    Digital Input
+ *             1      |      0       |    Digital Output Low Power
+ *             1      |      1       |    Digital Output High Power
+ *
+ *   Note: The Analog mode is used only for temperature sensor indication. This is available only
+ *         on GPIO_0 by setting the TS bit in the ANA_FUNC_CONF_0_Register.
+ *   \endcode
+ */
+
+
+#define GPIO3_CONF_BASE						((uint8_t)0x02) /*!< GPIO_3 register address */
+#define GPIO2_CONF_BASE						((uint8_t)0x03) /*!< GPIO_3 register address */
+#define GPIO1_CONF_BASE						((uint8_t)0x04) /*!< GPIO_3 register address */
+#define GPIO0_CONF_BASE						((uint8_t)0x05) /*!< GPIO_3 register address */
+
+#define CONF_GPIO_IN_TX_Command				        ((uint8_t)0x00) /*!< TX command direct from PIN (rising edge, width min=50ns) */
+#define CONF_GPIO_IN_RX_Command				        ((uint8_t)0x08) /*!< RX command direct from PIN (rising edge, width min=50ns)*/
+#define CONF_GPIO_IN_TX_Data				        ((uint8_t)0x10) /*!< TX data input for direct modulation */
+#define CONF_GPIO_IN_WKUP_Ext				        ((uint8_t)0x18) /*!< Wake up from external input */
+
+#define CONF_GPIO_OUT_nIRQ				        ((uint8_t)0x00) /*!< nIRQ (Interrupt Request, active low) , default configuration after POR */
+#define CONF_GPIO_OUT_POR_Inv				        ((uint8_t)0x08) /*!< POR inverted (active low) */
+#define CONF_GPIO_OUT_WUT_Exp				        ((uint8_t)0x10) /*!< Wake-Up Timer expiration: ‘1’ when WUT has expired */
+#define CONF_GPIO_OUT_LBD				        ((uint8_t)0x18) /*!< Low battery detection: ‘1’ when battery is below threshold setting */
+#define CONF_GPIO_OUT_TX_Data				        ((uint8_t)0x20) /*!< TX data internal clock output (TX data are sampled on the rising edge of it) */
+#define CONF_GPIO_OUT_TX_State				        ((uint8_t)0x28) /*!< TX state indication: ‘1’ when Spirit1 is transiting in the TX state */
+#define CONF_GPIO_OUT_TX_FIFO_Almost_Empty			((uint8_t)0x30) /*!< TX FIFO Almost Empty Flag */
+#define CONF_GPIO_OUT_TX_FIFO_Amost_Full			((uint8_t)0x38) /*!< TX FIFO Almost Full Flag */
+#define CONF_GPIO_OUT_RX_Data				        ((uint8_t)0x40) /*!< RX data output */
+#define CONF_GPIO_OUT_RX_Clock				        ((uint8_t)0x48) /*!< RX clock output (recovered from received data) */
+#define CONF_GPIO_OUT_RX_State				        ((uint8_t)0x50) /*!< RX state indication: ‘1’ when Spirit1 is transiting in the RX state */
+#define CONF_GPIO_OUT_RX_FIFO_Almost_Full			((uint8_t)0x58) /*!< RX FIFO Almost Full Flag */
+#define CONF_GPIO_OUT_RX_FIFO_Almost_Empty			((uint8_t)0x60) /*!< RX FIFO Almost Empty Flag */
+#define CONF_GPIO_OUT_Antenna_Switch				((uint8_t)0x68) /*!< Antenna switch used for antenna diversity */
+#define CONF_GPIO_OUT_Valid_Preamble				((uint8_t)0x70) /*!< Valid Preamble Detected Flag */
+#define CONF_GPIO_OUT_Sync_Detected				((uint8_t)0x78) /*!< Sync WordSync Word Detected Flag */
+#define CONF_GPIO_OUT_RSSI_Threshold				((uint8_t)0x80) /*!< CCA Assessment Flag */
+#define CONF_GPIO_OUT_MCU_Clock				        ((uint8_t)0x88) /*!< MCU Clock */
+#define CONF_GPIO_OUT_TX_RX_Mode				((uint8_t)0x90) /*!< TX or RX mode indicator (to enable an external range extender) */
+#define CONF_GPIO_OUT_VDD				        ((uint8_t)0x98) /*!< VDD (to emulate an additional GPIO of the MCU, programmable by SPI) */
+#define CONF_GPIO_OUT_GND				        ((uint8_t)0xA0) /*!< GND (to emulate an additional GPIO of the MCU, programmable by SPI) */
+#define CONF_GPIO_OUT_SMPS_Ext				        ((uint8_t)0xA8) /*!< External SMPS enable signal (active high) */
+
+#define CONF_GPIO_MODE_ANALOG				        ((uint8_t)0x00) /*!< Analog test BUS on GPIO; used only in test mode (except for temperature sensor) */
+#define CONF_GPIO_MODE_DIG_IN				        ((uint8_t)0x01) /*!< Digital Input on GPIO */
+#define CONF_GPIO_MODE_DIG_OUTL				        ((uint8_t)0x02) /*!< Digital Output on GPIO (low current) */
+#define CONF_GPIO_MODE_DIG_OUTH				        ((uint8_t)0x03) /*!< Digital Output on GPIO (high current) */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MCU_CK_CONF_Register
+ * @{
+ */
+
+/**
+ *  \brief MCU_CK_CONF  register
+ *  \code
+ *   Read Write
+ *   Default value: 0x00
+ *   7   Reserved.
+ *   6:5 CLOCK_TAIL[1:0]: Specifies the number of extra cylces provided before entering in STANDBY state.
+ *       CLOCK_TAIL1   |   CLOCK_TAIL0    |  Number of Extra Cycles
+ *       ------------------------------------------------------------
+ *            0        |        0         |           0
+ *            0        |        1         |           64
+ *            1        |        0         |           256
+ *            1        |        1         |           512
+ *   4:1 XO_RATIO[3:0]: Specifies the division ratio when XO oscillator is the clock source
+ *       XO_RATIO[3:0] |   Division Ratio
+ *       -----------------------------------
+ *               0     |        1
+ *               1     |       2/3
+ *               2     |       1/2
+ *               3     |       1/3
+ *               4     |       1/4
+ *               5     |       1/6
+ *               6     |       1/8
+ *               7     |       1/12
+ *               8     |       1/16
+ *               9     |       1/24
+ *               10    |       1/36
+ *               11    |       1/48
+ *               12    |       1/64
+ *               13    |       1/96
+ *               14    |       1/128
+ *               15    |       1/256
+ *   0   RCO_RATIO: Specifies the divsion ratio when RC oscillator is the clock source
+ *                0 - Division Ratio equal to 0
+ *                1 - Division Ratio equal to 1/128
+ *   \endcode
+ */
+
+
+#define MCU_CK_CONF_BASE					((uint8_t)0x06) /*!< MCU Clock Config register address */
+
+#define MCU_CK_ENABLE                                           ((uint8_t)0x80) /*!< MCU clock enable bit */
+
+#define MCU_CK_CONF_CLOCK_TAIL_0				((uint8_t)0x00) /*!< 0   extra clock cycles provided to the MCU before switching to STANDBY state */
+#define MCU_CK_CONF_CLOCK_TAIL_64				((uint8_t)0x20) /*!< 64  extra clock cycles provided to the MCU before switching to STANDBY state */
+#define MCU_CK_CONF_CLOCK_TAIL_256				((uint8_t)0x40) /*!< 256 extra clock cycles provided to the MCU before switching to STANDBY state */
+#define MCU_CK_CONF_CLOCK_TAIL_512				((uint8_t)0x60) /*!< 512 extra clock cycles provided to the MCU before switching to STANDBY state */
+#define MCU_CK_CONF_XO_RATIO_1					((uint8_t)0x00) /*!< XO Clock signal available on the GPIO divided by 1     */
+#define MCU_CK_CONF_XO_RATIO_2_3				((uint8_t)0x02) /*!< XO Clock signal available on the GPIO divided by 2/3   */
+#define MCU_CK_CONF_XO_RATIO_1_2				((uint8_t)0x04) /*!< XO Clock signal available on the GPIO divided by 1/2   */
+#define MCU_CK_CONF_XO_RATIO_1_3				((uint8_t)0x06) /*!< XO Clock signal available on the GPIO divided by 1/3   */
+#define MCU_CK_CONF_XO_RATIO_1_4				((uint8_t)0x08) /*!< XO Clock signal available on the GPIO divided by 1/4   */
+#define MCU_CK_CONF_XO_RATIO_1_6				((uint8_t)0x0A) /*!< XO Clock signal available on the GPIO divided by 1/6   */
+#define MCU_CK_CONF_XO_RATIO_1_8				((uint8_t)0x0C) /*!< XO Clock signal available on the GPIO divided by 1/8   */
+#define MCU_CK_CONF_XO_RATIO_1_12				((uint8_t)0x0E) /*!< XO Clock signal available on the GPIO divided by 1/12  */
+#define MCU_CK_CONF_XO_RATIO_1_16				((uint8_t)0x10) /*!< XO Clock signal available on the GPIO divided by 1/16  */
+#define MCU_CK_CONF_XO_RATIO_1_24				((uint8_t)0x12) /*!< XO Clock signal available on the GPIO divided by 1/24  */
+#define MCU_CK_CONF_XO_RATIO_1_36				((uint8_t)0x14) /*!< XO Clock signal available on the GPIO divided by 1/36  */
+#define MCU_CK_CONF_XO_RATIO_1_48				((uint8_t)0x16) /*!< XO Clock signal available on the GPIO divided by 1/48  */
+#define MCU_CK_CONF_XO_RATIO_1_64				((uint8_t)0x18) /*!< XO Clock signal available on the GPIO divided by 1/64  */
+#define MCU_CK_CONF_XO_RATIO_1_96				((uint8_t)0x1A) /*!< XO Clock signal available on the GPIO divided by 1/96  */
+#define MCU_CK_CONF_XO_RATIO_1_128				((uint8_t)0x1C) /*!< XO Clock signal available on the GPIO divided by 1/128 */
+#define MCU_CK_CONF_XO_RATIO_1_192				((uint8_t)0x1E) /*!< XO Clock signal available on the GPIO divided by 1/196 */
+#define MCU_CK_CONF_RCO_RATIO_1					((uint8_t)0x00) /*!< RCO Clock signal available on the GPIO divided by 1    */
+#define MCU_CK_CONF_RCO_RATIO_1_128				((uint8_t)0x01) /*!< RCO Clock signal available on the GPIO divided by 1/128*/
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Radio_Configuration_Registers
+ * @{
+ */
+
+
+
+/** @defgroup SYNT3_Register
+ * @{
+ */
+
+/**
+ *  \brief SYNT3  register
+ *  \code
+ *   Read Write
+ *   Default value: 0x0C
+ *
+ *   7:5 WCP[2:0]: Set the charge pump current according to the VCO frequency in RX mode.
+ *
+ *         VCO Frequency    |        WCP2      |       WCP1       |       WCP0        |    Charge Pump Current (uA)
+ *       ------------------------------------------------------------------------------------------------------------
+ *          4644-4678       |         0        |        0         |        0          |             378.4
+ *          4708-4772       |         0        |        0         |        1          |             368.9
+ *          4772-4836       |         0        |        1         |        0          |             359.5
+ *          4836-4902       |         0        |        1         |        1          |             350
+ *          4902-4966       |         1        |        0         |        0          |             340.5
+ *          4966-5030       |         1        |        0         |        1          |             331.1
+ *          5030-5095       |         1        |        1         |        0          |             321.6
+ *          5095-5161       |         1        |        1         |        1          |             312.2
+ *          5161-5232       |         0        |        0         |        0          |             378.4
+ *          5232-5303       |         0        |        0         |        1          |             368.9
+ *          5303-5375       |         0        |        1         |        0          |             359.5
+ *          5375-5448       |         0        |        1         |        1          |             350
+ *          5448-5519       |         1        |        0         |        0          |             340.5
+ *          5519-5592       |         1        |        0         |        1          |             331.1
+ *          5592-5663       |         1        |        1         |        0          |             321.6
+ *          5663-5736       |         1        |        1         |        1          |             312.2
+ *
+ *
+ *   4:0  SYNT[25:21]: highest 5 bits of the PLL programmable divider
+ *                     The valid range depends on fXO and REFDIV settings; for
+ *                     fXO=26MHz
+ *                     REFDIV = 0 - SYNT[25:21] = 11...13
+ *                     REFDIV = 1 - SYNT[25:21] = 22…27
+ *
+ *
+ *   \endcode
+ */
+#define	SYNT3_BASE						((uint8_t)0x08) /*!< [4:0] -> SYNT[25:21], highest 5 bits of the PLL programmable divider */
+
+#define WCP_CONF_WCP_378UA                                      ((uint8_t)0x00) /*!< Charge pump current nominal value = 378uA [VCO 4644-4708]&[VCO 5161-5232] */
+#define WCP_CONF_WCP_369UA                                      ((uint8_t)0x01) /*!< Charge pump current nominal value = 369uA [VCO 4708-4772]&[VCO 5232-5303] */
+#define WCP_CONF_WCP_359UA                                      ((uint8_t)0x02) /*!< Charge pump current nominal value = 359uA [VCO 4772-4836]&[VCO 5303-5375] */
+#define WCP_CONF_WCP_350UA                                      ((uint8_t)0x03) /*!< Charge pump current nominal value = 350uA [VCO 4836-4902]&[VCO 5375-5448] */
+#define WCP_CONF_WCP_340UA                                      ((uint8_t)0x04) /*!< Charge pump current nominal value = 340uA [VCO 4902-4966]&[VCO 5448-5519] */
+#define WCP_CONF_WCP_331UA                                      ((uint8_t)0x05) /*!< Charge pump current nominal value = 331uA [VCO 4966-5030]&[VCO 5519-5592] */
+#define WCP_CONF_WCP_321UA                                      ((uint8_t)0x06) /*!< Charge pump current nominal value = 321uA [VCO 5030-5095]&[VCO 5592-5563] */
+#define WCP_CONF_WCP_312UA                                      ((uint8_t)0x07) /*!< Charge pump current nominal value = 312uA [VCO 5095-5160]&[VCO 5563-5736] */
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup SYNT2_Register
+ * @{
+ */
+
+/**
+ *  \brief SYNT2  register
+ *  \code
+ *   Read Write
+ *   Default value: 0x84
+ *   7:0  SYNT[20:13]: intermediate bits of the PLL programmable divider.
+ *
+ *   \endcode
+ */
+
+#define	SYNT2_BASE						((uint8_t)0x09) /*!< SYNT[20:13], intermediate bits of the PLL programmable divider */
+
+/**
+ * @}
+ */
+
+/** @defgroup SYNT1_Register
+ * @{
+ */
+
+/**
+ *  \brief SYNT1  register
+ *  \code
+ *   Read Write
+ *   Default value: 0xEC
+ *   7:0  SYNT[12:5]: intermediate bits of the PLL programmable divider.
+ *
+ *   \endcode
+ */
+
+#define	SYNT1_BASE						((uint8_t)0x0A) /*!< SYNT[12:5], intermediate bits of the PLL programmable divider */
+
+/**
+ * @}
+ */
+
+/** @defgroup SYNT0_Register
+ * @{
+ */
+
+/**
+ *  \brief SYNT0  register
+ *  \code
+ *   Read Write
+ *   Default value: 0x51
+ *   7:3  SYNT[4:0]: lowest bits of the PLL programmable divider.
+ *   2:0  BS[2:0]:   Synthesizer band select. This parameter selects the out-of-loop divide factor of the synthesizer
+ *                   according to the formula fxo/(B/2)/D*SYNT/2^18
+ *
+ *              BS2        |       BS1       |       BS0        |     value of B
+ *       ---------------------------------------------------------------------------
+ *               0         |        0        |        1         |       6
+ *               0         |        1        |        0         |       8
+ *               0         |        1        |        1         |       12
+ *               1         |        0        |        0         |       16
+ *               1         |        0        |        1         |       32
+ *
+ *   \endcode
+ */
+#define	SYNT0_BASE						((uint8_t)0x0B) /*!< [7:3] -> SYNT[4:0], lowest bits of the PLL programmable divider */
+
+#define	SYNT0_BS_6						((uint8_t)0x01) /*!< Synthesizer band select (out-of-loop divide factor of the synthesizer)=6  (779-956MHz) */
+#define	SYNT0_BS_8						((uint8_t)0x02) /*!< Synthesizer band select (out-of-loop divide factor of the synthesizer)=8  (387-470MHz)*/
+#define	SYNT0_BS_12						((uint8_t)0x03) /*!< Synthesizer band select (out-of-loop divide factor of the synthesizer)=12 (387-470MHz)*/
+#define	SYNT0_BS_16						((uint8_t)0x04) /*!< Synthesizer band select (out-of-loop divide factor of the synthesizer)=16 (300-348MHz)*/
+#define	SYNT0_BS_32						((uint8_t)0x05) /*!< Synthesizer band select (out-of-loop divide factor of the synthesizer)=32 (150-174MHz)*/
+
+/**
+ * @}
+ */
+
+/** @defgroup CHSPACE_Register
+ * @{
+ */
+
+/**
+ *  \brief CHSPACE  register
+ *  \code
+ *   Read Write
+ *   Default value: 0xFC
+ *   7:0  CH_SPACING[7:0]: Channel spacing. From ~793Hz to ~200KHz in 793Hz steps
+ *                         (in general, frequency step is fXO/215=26MHz/215~793Hz).
+ *
+ *   \endcode
+ */
+
+#define	CHSPACE_BASE						((uint8_t)0x0C) /*!< Channel spacing. From ~0.8KHz to ~200KHz in (fXO/2^15)Hz (793Hz for 26MHz XO) steps */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup IF_OFFSET_DIG_Register
+ * @{
+ */
+
+/**
+ *  \brief IF_OFFSET_DIG  register
+ *  \code
+ *   Read Write
+ *   Default value: 0xA3
+ *   7:0  IF_OFFSET_DIG[7:0]: Intermediate frequency setting for the digital shift-to-baseband circuits. According to the formula: fIF=fXO*(IF_OFFSET_ANA+64)/(12*2^10)=fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz.
+ *
+ *   \endcode
+ */
+#define	IF_OFFSET_DIG_BASE						((uint8_t)0x0D) /*!< Intermediate frequency fIF=fXO*(IF_OFFSET_ANA+64)/(12*2^10)=fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz */
+
+/**
+ * @}
+ */
+
+/** @defgroup IF_OFFSET_ANA_Register
+ * @{
+ */
+
+/**
+ *  \brief IF_OFFSET_ANA  register
+ *  \code
+ *   Read Write
+ *   Default value: 0xA3
+ *   7:0  IF_OFFSET_ANA[7:0]: Intermediate frequency setting for the digital shift-to-baseband circuits. According to the formula: fIF=fXO*(IF_OFFSET_ANA+64)/(12*2^10)=fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz.
+ *
+ *   \endcode
+ */
+#define	IF_OFFSET_ANA_BASE						((uint8_t)0x07) /*!< Intermediate frequency fIF=fXO*(IF_OFFSET_ANA+64)/(12*2^10)=fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup FC_OFFSET1_Register
+ * @{
+ */
+
+/**
+ *  \brief FC_OFFSET1  registers
+ *  \code
+ *   Read Write
+ *   Default value: 0xA3
+ *   7:4  Reserved.
+ *   3:0  FC_OFFSET[11:8]: Carrier offset. This value is the higher part of a 12-bit 2’s complement integer
+ *                         representing an offset in 99Hz(2) units added/subtracted to the
+ *                         carrier frequency set by registers SYNT3…SYNT0.
+ *                         This register can be used to set a fixed correction value
+ *                         obtained e.g. from crystal measurements.
+ *
+ *   \endcode
+ */
+#define	FC_OFFSET1_BASE						((uint8_t)0x0E) /*!< [3:0] -> [11:8] Carrier offset (upper part) */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FC_OFFSET0_Register
+ * @{
+ */
+
+/**
+ *  \brief FC_OFFSET0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0  FC_OFFSET[7:0]: Carrier offset. This value is the lower part of a 12-bit 2’s complement integer
+ *                         representing an offset in 99Hz(2) units added/subtracted to the
+ *                         carrier frequency set by registers SYNT3…SYNT0.
+ *                         This register can be used to set a fixed correction value
+ *                         obtained e.g. from crystal measurements.
+ *
+ *   \endcode
+ */
+#define	FC_OFFSET0_BASE						((uint8_t)0x0F) /*!< [7:0] -> [7:0] Carrier offset (lower part). This value is a 12-bit 2’s complement integer
+																	representing an offset in fXO/2^18 (99Hz for 26 MHz XO) units added/subtracted to the carrier frequency
+															set by registers SYNT3…SYNT0. Range is +/-200kHz with 26 MHz XO */
+/**
+ * @}
+ */
+
+
+/** @defgroup PA_LEVEL_x_Registers
+ * @{
+ */
+
+/**
+ *  \brief PA_POWER_x[8:1]  registers
+ *  \code
+ *   Default values from 8 to 1: [0x03, 0x0E, 0x1A, 0x25, 0x35, 0x40, 0x4E, 0x00]
+ *   Read Write
+ *
+ *   7    Reserved.
+ *   6:0  PA_LEVEL_(x-1)[6:0]: Output power level for x-th slot.
+ *   \endcode
+ */
+
+#define	PA_POWER8_BASE						((uint8_t)0x10) /*!< PA Power level for 8th slot of PA ramping or ASK modulation */
+#define	PA_POWER7_BASE						((uint8_t)0x11) /*!< PA Power level for 7th slot of PA ramping or ASK modulation */
+#define	PA_POWER6_BASE						((uint8_t)0x12) /*!< PA Power level for 6th slot of PA ramping or ASK modulation */
+#define	PA_POWER5_BASE						((uint8_t)0x13) /*!< PA Power level for 5th slot of PA ramping or ASK modulation */
+#define	PA_POWER4_BASE						((uint8_t)0x14) /*!< PA Power level for 4th slot of PA ramping or ASK modulation */
+#define	PA_POWER3_BASE						((uint8_t)0x15) /*!< PA Power level for 3rd slot of PA ramping or ASK modulation */
+#define	PA_POWER2_BASE						((uint8_t)0x16) /*!< PA Power level for 2nd slot of PA ramping or ASK modulation */
+#define	PA_POWER1_BASE						((uint8_t)0x17) /*!< PA Power level for 1st slot of PA ramping or ASK modulation */
+
+/**
+ * @}
+ */
+
+/** @defgroup PA_POWER_CONF_Registers
+ * @{
+ */
+
+/**
+ *  \brief PA_POWER_CONF_Registers
+ *  \code
+ *   Default value:0x07
+ *   Read Write
+ *
+ *   7:6  CWC[1:0]: Output stage additional load capacitors bank (to be used to
+ *                      optimize the PA for different sub-bands).
+ *
+ *         CWC1       |        CWC0      |     Total capacity in pF
+ *       ---------------------------------------------------------
+ *          0         |         0        |        0
+ *          0         |         1        |        1.2
+ *          1         |         0        |        2.4
+ *          1         |         1        |        3.6
+ *
+ *   5   PA_RAMP_ENABLE:
+ *                       1 - Enable the power ramping
+ *                       0 - Disable the power ramping
+ *   4:3 PA_RAMP_STEP_WIDTH[1:0]: Step width in bit period
+ *
+ *         PA_RAMP_STEP_WIDTH1       |        PA_RAMP_STEP_WIDTH0       |     PA ramping time step
+ *       -------------------------------------------------------------------------------------------
+ *                 0                 |                0                 |        1/8 Bit period
+ *                 0                 |                1                 |        2/8 Bit period
+ *                 1                 |                0                 |        3/8 Bit period
+ *                 1                 |                1                 |        4/8 Bit period
+ *
+ *   2:0 PA_LEVEL_MAX_INDEX[2:0]: Fixes the MAX PA LEVEL in PA ramping or ASK modulation
+ *
+ *   \endcode
+ */
+#define	PA_POWER0_BASE						((uint8_t)0x18) /*!< PA ramping settings and additional load capacitor banks used
+																	for PA optimization in different sub bands*/
+#define PA_POWER0_CWC_MASK                                      ((uint8_t)0x20) /*!< Output stage additional load capacitors bank */
+#define PA_POWER0_CWC_0						((uint8_t)0x00) /*!< No additional PA load capacitor */
+#define PA_POWER0_CWC_1_2P					((uint8_t)0x40) /*!< 1.2pF additional PA load capacitor */
+#define PA_POWER0_CWC_2_4P					((uint8_t)0x80) /*!< 2.4pF additional PA load capacitor */
+#define PA_POWER0_CWC_3_6P					((uint8_t)0xC0) /*!< 3.6pF additional PA load capacitor */
+#define PA_POWER0_PA_RAMP_MASK  				((uint8_t)0x20) /*!< The PA power ramping */
+#define PA_POWER0_PA_RAMP_STEP_WIDTH_MASK                       ((uint8_t)0x20) /*!< The step width */
+#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_8			((uint8_t)0x00) /*!< PA ramping time step = 1/8 Bit period*/
+#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_4			((uint8_t)0x08) /*!< PA ramping time step = 2/8 Bit period*/
+#define PA_POWER0_PA_RAMP_STEP_WIDTH_3TB_8			((uint8_t)0x10) /*!< PA ramping time step = 3/8 Bit period*/
+#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_2			((uint8_t)0x18) /*!< PA ramping time step = 4/8 Bit period*/
+#define PA_POWER0_PA_LEVEL_MAX_INDEX                            ((uint8_t)0x20) /*!< Final level for power ramping */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_0				((uint8_t)0x00) /*!<                                                           */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_1				((uint8_t)0x01) /*!<  Fixes the MAX PA LEVEL in PA ramping or ASK modulation   */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_2				((uint8_t)0x02) /*!<                                                           */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_3				((uint8_t)0x03) /*!<                     _________                             */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_4				((uint8_t)0x04) /*!<     PA_LVL2       _|                 <--|                 */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_5				((uint8_t)0x05) /*!<                 _|                      |                 */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_6				((uint8_t)0x06) /*!<     PA_LVL1   _|                        |                 */
+#define PA_POWER0_PA_LEVEL_MAX_INDEX_7				((uint8_t)0x07) /*!<     PA_LVL0 _|                 MAX_INDEX-                 */
+
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MOD1_Register
+ * @{
+ */
+
+/**
+ *  \brief MOD1 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x83
+ *   7:0  DATARATE_M[7:0]: The Mantissa of the specified data rate
+ *
+ *   \endcode
+ */
+#define	MOD1_BASE					        ((uint8_t)0x1A) /*!< The Mantissa of the specified data rate */
+
+/**
+ * @}
+ */
+
+/** @defgroup MOD0_Register
+ * @{
+ */
+
+/**
+ *  \brief MOD0 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x1A
+ *   7  CW:              1 - CW Mode enabled - enables the generation of a continous wave carrier without any modulation
+ *                       0 - CW Mode disabled
+ *
+ *   6 BT_SEL:  Select BT value for GFSK
+ *                       1 - BT=0.5
+ *                       0 - BT=1
+ *
+ *   5:4 MOD_TYPE[1:0]: Modulation type
+ *
+ *
+ *         MOD_TYPE1       |        MOD_TYPE0      |     Modulation
+ *       ---------------------------------------------------------
+ *             0           |           0           |        2-FSK,MSK
+ *             0           |           1           |        GFSK,GMSK
+ *             1           |           0           |        ASK/OOK
+ *
+ *   3:0  DATARATE_E[3:0]: The Exponent of the specified data rate
+ *
+ *   \endcode
+ */
+#define	MOD0_BASE						((uint8_t)0x1B) /*!< Modulation Settings, Exponent of the specified data rate, CW mode*/
+
+#define MOD0_MOD_TYPE_2_FSK					((uint8_t)0x00) /*!< Modulation type 2-FSK (MSK if the frequency deviation is identical to a quarter of the data rate) */
+#define MOD0_MOD_TYPE_GFSK					((uint8_t)0x10) /*!< Modulation type GFSK (GMSK if the frequency deviation is identical to a quarter of the data rate) */
+#define MOD0_MOD_TYPE_ASK					((uint8_t)0x20) /*!< Modulation type ASK (OOK the PA is switched off for symbol "0") */
+#define MOD0_MOD_TYPE_MSK					((uint8_t)0x00) /*!< Modulation type MSK (the frequency deviation must be identical to a quarter of the data rate) */
+#define MOD0_MOD_TYPE_GMSK					((uint8_t)0x10) /*!< Modulation type GMSK (the frequency deviation must be identical to a quarter of the data rate) */
+#define MOD0_BT_SEL_BT_MASK       				((uint8_t)0x00) /*!< Select the BT = 1 or BT = 0.5 valid only for GFSK or GMSK modulation*/
+#define MOD0_CW							((uint8_t)0x80) /*!< Set the Continous Wave (no modulation) transmit mode */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FDEV0_Register
+ * @{
+ */
+
+/**
+ *  \brief FDEV0 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x45
+ *   7:4  FDEV_E[3:0]:       Exponent of the frequency deviation (allowed values from 0 to 9)
+ *
+ *   3 CLOCK_REC_ALGO_SEL:  Select PLL or DLL mode for clock recovery
+ *                       1 - DLL mode
+ *                       0 - PLL mode
+ *
+ *   2:0 FDEV_M[1:0]: Mantissa of the frequency deviation (allowed values from 0 to 7)
+ *
+ *
+ *   \endcode
+ */
+#define	FDEV0_BASE						((uint8_t)0x1C) /*!< Sets the Mantissa and exponent of frequency deviation (frequency separation/2)
+																and PLL or DLL alogrithm from clock recovery in RX digital demod*/
+#define FDEV0_CLOCK_REG_ALGO_SEL_MASK			        ((uint8_t)0x08) /*!< Can be DLL or PLL algorithm for clock recovery in RX digital demod (see CLOCKREC reg) */
+#define FDEV0_CLOCK_REG_ALGO_SEL_PLL				((uint8_t)0x00) /*!< Sets PLL alogrithm for clock recovery in RX digital demod (see CLOCKREC reg) */
+#define FDEV0_CLOCK_REG_ALGO_SEL_DLL				((uint8_t)0x08) /*!< Sets DLL alogrithm for clock recovery in RX digital demod (see CLOCKREC reg) */
+   
+/**
+ * @}
+ */
+
+/** @defgroup CHFLT_Register
+ * @{
+ */
+
+/**
+ *  \brief CHFLT register
+ *  \code
+ *   Read Write
+ *   Default value: 0x23
+ *   7:4  CHFLT_M[3:0]:       Mantissa of the channel filter BW (allowed values from 0 to 8)
+ *
+ *   3:0  CHFLT_E[3:0]:       Exponent of the channel filter BW (allowed values from 0 to 9)
+ *
+ *         M\E |   0   |   1   |   2   |   3   |   4  |   5  |  6   |   7 |  8  |  9  |
+ *        -----+-------+-------+-------+-------+------+------+------+-----+-----+-----+
+ *         0   | 800.1 | 450.9 | 224.7 | 112.3 | 56.1 | 28.0 | 14.0 | 7.0 | 3.5 | 1.8 |
+ *         1   | 795.1 | 425.9 | 212.4 | 106.2 | 53.0 | 26.5 | 13.3 | 6.6 | 3.3 | 1.7 |
+ *         2   | 768.4 | 403.2 | 201.1 | 100.5 | 50.2 | 25.1 | 12.6 | 6.3 | 3.1 | 1.6 |
+ *         3   | 736.8 | 380.8 | 190.0 | 95.0  | 47.4 | 23.7 | 11.9 | 5.9 | 3.0 | 1.5 |
+ *         4   | 705.1 | 362.1 | 180.7 | 90.3  | 45.1 | 22.6 | 11.3 | 5.6 | 2.8 | 1.4 |
+ *         5   | 670.9 | 341.7 | 170.6 | 85.3  | 42.6 | 21.3 | 10.6 | 5.3 | 2.7 | 1.3 |
+ *         6   | 642.3 | 325.4 | 162.4 | 81.2  | 40.6 | 20.3 | 10.1 | 5.1 | 2.5 | 1.3 |
+ *         7   | 586.7 | 294.5 | 147.1 | 73.5  | 36.7 | 18.4 | 9.2  | 4.6 | 2.3 | 1.2 |
+ *         8   | 541.4 | 270.3 | 135.0 | 67.5  | 33.7 | 16.9 | 8.4  | 4.2 | 2.1 | 1.1 |
+ *
+ *   \endcode
+ */
+#define	CHFLT_BASE						((uint8_t)0x1D) /*!< RX Channel Filter Bandwidth */
+
+#define CHFLT_800_1						((uint8_t)0x00) /*!< RX Channel Filter Bandwidth = 800.1 kHz */
+#define CHFLT_795_1						((uint8_t)0x10) /*!< RX Channel Filter Bandwidth = 795.1 kHz */
+#define CHFLT_768_4						((uint8_t)0x20) /*!< RX Channel Filter Bandwidth = 768.4 kHz */
+#define CHFLT_736_8						((uint8_t)0x30) /*!< RX Channel Filter Bandwidth = 736.8 kHz */
+#define CHFLT_705_1						((uint8_t)0x40) /*!< RX Channel Filter Bandwidth = 705.1 kHz */
+#define CHFLT_670_9						((uint8_t)0x50) /*!< RX Channel Filter Bandwidth = 670.9 kHz */
+#define CHFLT_642_3						((uint8_t)0x60) /*!< RX Channel Filter Bandwidth = 642.3 kHz */
+#define CHFLT_586_7						((uint8_t)0x70) /*!< RX Channel Filter Bandwidth = 586.7 kHz */
+#define CHFLT_541_4						((uint8_t)0x80) /*!< RX Channel Filter Bandwidth = 541.4 kHz */
+#define CHFLT_450_9						((uint8_t)0x01) /*!< RX Channel Filter Bandwidth = 450.9 kHz */
+#define CHFLT_425_9						((uint8_t)0x11) /*!< RX Channel Filter Bandwidth = 425.9 kHz */
+#define CHFLT_403_2						((uint8_t)0x21) /*!< RX Channel Filter Bandwidth = 403.2 kHz */
+#define CHFLT_380_8						((uint8_t)0x31) /*!< RX Channel Filter Bandwidth = 380.8 kHz */
+#define CHFLT_362_1						((uint8_t)0x41) /*!< RX Channel Filter Bandwidth = 362.1 kHz */
+#define CHFLT_341_7						((uint8_t)0x51) /*!< RX Channel Filter Bandwidth = 341.7 kHz */
+#define CHFLT_325_4						((uint8_t)0x61) /*!< RX Channel Filter Bandwidth = 325.4 kHz */
+#define CHFLT_294_5						((uint8_t)0x71) /*!< RX Channel Filter Bandwidth = 294.5 kHz */
+#define CHFLT_270_3						((uint8_t)0x81) /*!< RX Channel Filter Bandwidth = 270.3 kHz */
+#define CHFLT_224_7						((uint8_t)0x02) /*!< RX Channel Filter Bandwidth = 224.7 kHz */
+#define CHFLT_212_4						((uint8_t)0x12) /*!< RX Channel Filter Bandwidth = 212.4 kHz */
+#define CHFLT_201_1						((uint8_t)0x22) /*!< RX Channel Filter Bandwidth = 201.1 kHz */
+#define CHFLT_190						((uint8_t)0x32) /*!< RX Channel Filter Bandwidth = 190.0 kHz */
+#define CHFLT_180_7						((uint8_t)0x42) /*!< RX Channel Filter Bandwidth = 180.7 kHz */
+#define CHFLT_170_6						((uint8_t)0x52) /*!< RX Channel Filter Bandwidth = 170.6 kHz */
+#define CHFLT_162_4						((uint8_t)0x62) /*!< RX Channel Filter Bandwidth = 162.4 kHz */
+#define CHFLT_147_1						((uint8_t)0x72) /*!< RX Channel Filter Bandwidth = 147.1 kHz */
+#define CHFLT_135						((uint8_t)0x82) /*!< RX Channel Filter Bandwidth = 135.0 kHz */
+#define CHFLT_112_3						((uint8_t)0x03) /*!< RX Channel Filter Bandwidth = 112.3 kHz */
+#define CHFLT_106_2						((uint8_t)0x13) /*!< RX Channel Filter Bandwidth = 106.2 kHz */
+#define CHFLT_100_5						((uint8_t)0x23) /*!< RX Channel Filter Bandwidth = 100.5 kHz */
+#define CHFLT_95						((uint8_t)0x33) /*!< RX Channel Filter Bandwidth = 95.0 kHz */
+#define CHFLT_90_3						((uint8_t)0x43) /*!< RX Channel Filter Bandwidth = 90.3 kHz */
+#define CHFLT_85_3						((uint8_t)0x53) /*!< RX Channel Filter Bandwidth = 85.3 kHz */
+#define CHFLT_81_2						((uint8_t)0x63) /*!< RX Channel Filter Bandwidth = 81.2 kHz */
+#define CHFLT_73_5						((uint8_t)0x73) /*!< RX Channel Filter Bandwidth = 73.5 kHz */
+#define CHFLT_67_5						((uint8_t)0x83) /*!< RX Channel Filter Bandwidth = 67.5 kHz */
+#define CHFLT_56_1						((uint8_t)0x04) /*!< RX Channel Filter Bandwidth = 56.1 kHz */
+#define CHFLT_53						((uint8_t)0x14) /*!< RX Channel Filter Bandwidth = 53.0 kHz */
+#define CHFLT_50_2						((uint8_t)0x24) /*!< RX Channel Filter Bandwidth = 50.2 kHz */
+#define CHFLT_47_4						((uint8_t)0x34) /*!< RX Channel Filter Bandwidth = 47.4 kHz */
+#define CHFLT_45_1						((uint8_t)0x44) /*!< RX Channel Filter Bandwidth = 45.1 kHz */
+#define CHFLT_42_6						((uint8_t)0x54) /*!< RX Channel Filter Bandwidth = 42.6 kHz */
+#define CHFLT_40_6						((uint8_t)0x64) /*!< RX Channel Filter Bandwidth = 40.6 kHz */
+#define CHFLT_36_7						((uint8_t)0x74) /*!< RX Channel Filter Bandwidth = 36.7 kHz */
+#define CHFLT_33_7						((uint8_t)0x84) /*!< RX Channel Filter Bandwidth = 33.7 kHz */
+#define CHFLT_28						((uint8_t)0x05) /*!< RX Channel Filter Bandwidth = 28.0 kHz */
+#define CHFLT_26_5						((uint8_t)0x15) /*!< RX Channel Filter Bandwidth = 26.5 kHz */
+#define CHFLT_25_1						((uint8_t)0x25) /*!< RX Channel Filter Bandwidth = 25.1 kHz */
+#define CHFLT_23_7						((uint8_t)0x35) /*!< RX Channel Filter Bandwidth = 23.7 kHz */
+#define CHFLT_22_6						((uint8_t)0x45) /*!< RX Channel Filter Bandwidth = 22.6 kHz */
+#define CHFLT_21_3						((uint8_t)0x55) /*!< RX Channel Filter Bandwidth = 21.3 kHz */
+#define CHFLT_20_3						((uint8_t)0x65) /*!< RX Channel Filter Bandwidth = 20.3 kHz */
+#define CHFLT_18_4						((uint8_t)0x75) /*!< RX Channel Filter Bandwidth = 18.4 kHz */
+#define CHFLT_16_9						((uint8_t)0x85) /*!< RX Channel Filter Bandwidth = 16.9 kHz */
+#define CHFLT_14						((uint8_t)0x06) /*!< RX Channel Filter Bandwidth = 14.0 kHz */
+#define CHFLT_13_3						((uint8_t)0x16) /*!< RX Channel Filter Bandwidth = 13.3 kHz */
+#define CHFLT_12_6						((uint8_t)0x26) /*!< RX Channel Filter Bandwidth = 12.6 kHz */
+#define CHFLT_11_9						((uint8_t)0x36) /*!< RX Channel Filter Bandwidth = 11.9 kHz */
+#define CHFLT_11_3						((uint8_t)0x46) /*!< RX Channel Filter Bandwidth = 11.3 kHz */
+#define CHFLT_10_6						((uint8_t)0x56) /*!< RX Channel Filter Bandwidth = 10.6 kHz */
+#define CHFLT_10_1						((uint8_t)0x66) /*!< RX Channel Filter Bandwidth = 10.1 kHz */
+#define CHFLT_9_2						((uint8_t)0x76) /*!< RX Channel Filter Bandwidth = 9.2 kHz */
+#define CHFLT_8_4						((uint8_t)0x86) /*!< RX Channel Filter Bandwidth = 8.4 kHz */
+#define CHFLT_7							((uint8_t)0x07) /*!< RX Channel Filter Bandwidth = 7.0 kHz */
+#define CHFLT_6_6						((uint8_t)0x17) /*!< RX Channel Filter Bandwidth = 6.6 kHz */
+#define CHFLT_6_3						((uint8_t)0x27) /*!< RX Channel Filter Bandwidth = 6.3 kHz */
+#define CHFLT_5_9						((uint8_t)0x37) /*!< RX Channel Filter Bandwidth = 5.9 kHz */
+#define CHFLT_5_6						((uint8_t)0x47) /*!< RX Channel Filter Bandwidth = 5.6 kHz */
+#define CHFLT_5_3						((uint8_t)0x57) /*!< RX Channel Filter Bandwidth = 5.3 kHz */
+#define CHFLT_5_1						((uint8_t)0x67) /*!< RX Channel Filter Bandwidth = 5.1 kHz */
+#define CHFLT_4_6						((uint8_t)0x77) /*!< RX Channel Filter Bandwidth = 4.6 kHz */
+#define CHFLT_4_2						((uint8_t)0x87) /*!< RX Channel Filter Bandwidth = 4.2 kHz */
+#define CHFLT_3_5						((uint8_t)0x08) /*!< RX Channel Filter Bandwidth = 3.5 kHz */
+#define CHFLT_3_3						((uint8_t)0x18) /*!< RX Channel Filter Bandwidth = 3.3 kHz */
+#define CHFLT_3_1						((uint8_t)0x28) /*!< RX Channel Filter Bandwidth = 3.1 kHz */
+#define CHFLT_3							((uint8_t)0x38) /*!< RX Channel Filter Bandwidth = 3.0 kHz */
+#define CHFLT_2_8						((uint8_t)0x48) /*!< RX Channel Filter Bandwidth = 2.8 kHz */
+#define CHFLT_2_7						((uint8_t)0x58) /*!< RX Channel Filter Bandwidth = 2.7 kHz */
+#define CHFLT_2_5						((uint8_t)0x68) /*!< RX Channel Filter Bandwidth = 2.5 kHz */
+#define CHFLT_2_3						((uint8_t)0x78) /*!< RX Channel Filter Bandwidth = 2.3 kHz */
+#define CHFLT_2_1						((uint8_t)0x88) /*!< RX Channel Filter Bandwidth = 2.1 kHz */
+#define CHFLT_1_8						((uint8_t)0x09) /*!< RX Channel Filter Bandwidth = 1.8 kHz */
+#define CHFLT_1_7						((uint8_t)0x19) /*!< RX Channel Filter Bandwidth = 1.7 kHz */
+#define CHFLT_1_6						((uint8_t)0x29) /*!< RX Channel Filter Bandwidth = 1.6 kHz */
+#define CHFLT_1_5						((uint8_t)0x39) /*!< RX Channel Filter Bandwidth = 1.5 kHz */
+#define CHFLT_1_4						((uint8_t)0x49) /*!< RX Channel Filter Bandwidth = 1.4 kHz */
+#define CHFLT_1_3a						((uint8_t)0x59) /*!< RX Channel Filter Bandwidth = 1.3 kHz */
+#define CHFLT_1_3						((uint8_t)0x69) /*!< RX Channel Filter Bandwidth = 1.3 kHz */
+#define CHFLT_1_2						((uint8_t)0x79) /*!< RX Channel Filter Bandwidth = 1.2 kHz */
+#define CHFLT_1_1						((uint8_t)0x89) /*!< RX Channel Filter Bandwidth = 1.1 kHz */
+
+/**
+ * @}
+ */
+
+/** @defgroup AFC2_Register
+ * @{
+ */
+
+/**
+ *  \brief AFC2 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x48
+ *   7  AFC Freeze on Sync: Freeze AFC correction upon sync word detection.
+ *                       1 - AFC Freeze enabled
+ *                       0 - AFC Freeze disabled
+ *
+ *   6  AFC Enabled:  Enable AFC
+ *                       1 - AFC enabled
+ *                       0 - AFC disabled
+ *
+ *   5  AFC Mode:    Select AFC mode
+ *                       1 - AFC Loop closed on 2nd conversion stage.
+ *                       0 - AFC Loop closed on slicer
+ *
+ *   4:0  AFC PD leakage[4:0]: Peak detector leakage. This parameter sets the decay speed of the min/max frequency peak detector (AFC2 register),
+ *                             the range allowed is 0..31 (0 - no leakage, 31 - high leakage). The recommended value for this parameter is 4.
+ *
+ *   \endcode
+ */
+#define	AFC2_BASE						((uint8_t)0x1E) /*!< Automatic frequency compensation algorithm parameters (FSK/GFSK/MSK)*/
+
+#define AFC2_AFC_FREEZE_ON_SYNC_MASK				((uint8_t)0x80) /*!< The frequency correction value is frozen when SYNC word is detected */
+#define AFC2_AFC_MASK			        		((uint8_t)0x40) /*!< Mask of Automatic Frequency Correction */
+#define AFC2_AFC_MODE_MASK					((uint8_t)0x20) /*!< Automatic Frequency Correction can be in Main MODE or Auxiliary MODE*/
+#define AFC2_AFC_MODE_SLICER					((uint8_t)0x00) /*!< Automatic Frequency Correction Main MODE */
+#define AFC2_AFC_MODE_MIXER					((uint8_t)0x20) /*!< Automatic Frequency Correction Auxiliary MODE */
+   
+/**
+ * @}
+ */
+
+/** @defgroup AFC1_Register
+ * @{
+ */
+
+/**
+ *  \brief AFC1 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x18
+ *   7:0  AFC_FAST_PERIOD: Length of the AFC fast period. this parameter sets the length of the fast period in number of samples (AFC1 register), the range allowed
+ *                         is 0..255. The recommended setting for this parameter is such that the fast period equals the preamble length. Since the
+ *                         algorithm operates typically on 2 samples per symbol, the programmed value should be twice the number of preamble
+ *                         symbols.
+ *
+ *   \endcode
+ */
+#define	AFC1_BASE						((uint8_t)0x1F) /*!< Length of the AFC fast period */
+
+/**
+ * @}
+ */
+
+/** @defgroup AFC0_Register
+ * @{
+ */
+
+/**
+ *  \brief AFC0 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x25
+ *   7:4  AFC_FAST_GAIN_LOG2[3:0]: AFC loop gain in fast mode (2's log)
+ *
+ *   3:0  AFC_SLOW_GAIN_LOG2[3:0]: AFC loop gain in slow mode (2's log)
+ *
+ *   \endcode
+ */
+#define	AFC0_BASE						((uint8_t)0x20) /*!< AFC loop gain in fast and slow modes (2's log) */
+
+/**
+ * @}
+ */
+
+/** @defgroup CLOCKREC_Register
+ * @{
+ */
+
+/**
+ *  \brief CLOCKREC register
+ *  \code
+ *   Read Write
+ *   Default value: 0x58
+ *
+ *   7:5 CLK_REC_P_GAIN [2:0]: Clock recovery loop gain (log2)
+ *
+ *   4   PSTFLT_LEN: Set Postfilter length
+ *                       1 - 16 symbols
+ *                       0 - 8 symbols
+ *
+ *   3:0 CLK_REC_I_GAIN[3:0]: Integral gain for the clock recovery loop
+ *   \endcode
+ */
+
+#define	CLOCKREC_BASE						((uint8_t)0x23) /*!< Gain of clock recovery loop - Postfilter length 0-8 symbols, 1-16 symbols */
+
+/**
+ * @}
+ */
+
+/** @defgroup AGCCTRL2_Register
+ * @{
+ */
+
+/**
+ *  \brief AGCCTRL2 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x22
+ *
+ *   7   Reserved
+ *
+ *   6   FREEZE_ON_STEADY: Enable freezing on steady state
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   5   FREEZE_ON_SYNC: Enable freezing on sync detection
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   4   START_MAX_ATTENUATION: Start with max attenuation
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   3:0  MEAS_TIME[3:0]: Measure time during which the signal peak is detected (according to the formula 12/fxo*2^MEAS_TIME)
+ *   \endcode
+ */
+#define	AGCCTRL2_BASE						((uint8_t)0x24) /*!< AGC freeze strategy, AGC attenuation  strategy, AGC measure time */
+
+#define AGCCTRL2_FREEZE_ON_STEADY_MASK			        ((uint8_t)0x40) /*!< The attenuation settings will be frozen as soon as signal level
+										     is betweeen min and max treshold (see AGCCTRL1) */
+#define AGCCTRL2_FREEZE_ON_SYNC_MASK				((uint8_t)0x20) /*!< The attenuation settings will be frozen as soon sync word is detected */
+#define AGCCTRL2_START_MAX_ATTENUATION_MASK			((uint8_t)0x10) /*!< The AGC algorithm can start with MAX attenuation or MIN attenuation */
+
+/**
+ * @}
+ */
+
+/** @defgroup AGCCTRL1_Register
+ * @{
+ */
+
+/**
+ *  \brief AGCCTRL1 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x65
+ *
+ *   7:4   THRESHOLD_HIGH[3:0]: High threshold for the AGC
+ *
+ *   3:0   THRESHOLD_LOW[3:0]: Low threshold for the AGC
+ *   \endcode
+ */
+#define	AGCCTRL1_BASE						((uint8_t)0x25) /*!< Sets low and high threshold for AGC */
+
+/**
+ * @}
+ */
+
+/** @defgroup AGCCTRL0_Register
+ * @{
+ */
+
+/**
+ *  \brief AGCCTRL0 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x8A
+ *
+ *   7   AGC S_ENABLE: Enable AGC
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   6   AGC_MODE: Set linear-Binary AGC mode
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   5:0 HOLD_TIME[5:0]: Hold time after gain adjustment according to formula 12/fxo*HOLD_TIME
+ *   \endcode
+ */
+#define	AGCCTRL0_BASE						((uint8_t)0x26) /*!< Enables AGC, set AGC algo between linear/binary mode, set hold time
+																	to account signal propagation through RX chain */
+#define AGCCTRL0_AGC_MASK				        ((uint8_t)0x80) /*!< AGC on/off */
+#define AGCCTRL0_AGC_MODE_MASK  				((uint8_t)0x40) /*!< AGC search correct attenuation in binary mode or sequential mode */
+#define AGCCTRL0_AGC_MODE_LINEAR				((uint8_t)0x00) /*!< AGC search correct attenuation in sequential mode (recommended) */
+#define AGCCTRL0_AGC_MODE_BINARY				((uint8_t)0x40) /*!< AGC search correct attenuation in binary mode */
+
+/**
+ * @}
+ */
+
+/** @defgroup CHNUM_Register
+ * @{
+ */
+
+/**
+ *  \brief CHNUM  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0     CH_NUM[7:0]: Channel number. This value is multiplied by the channel spacing and added to the
+ *                        synthesizer base frequency to generate the actual RF carrier frequency.
+ *   \endcode
+ */
+#define	CHNUM_BASE						((uint8_t)0x6C) /*!< Channel number. This value is multiplied by the channel
+										spacing and added to the synthesizer base frequency to generate the actual RF carrier frequency */
+/**
+ * @}
+ */
+
+/** @defgroup AFC_CORR_Register
+ * @{
+ */
+
+/**
+ *  \brief AFC_CORR  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   AFC_CORR[7:0]: AFC word of the received packet
+ *   \endcode
+ */
+#define	AFC_CORR_BASE						((uint8_t)(0xC4)) /*!< AFC word of the received packet */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Packet_Configuration_Registers
+ * @{
+ */
+
+/** @defgroup PCKTCTRL4_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTCTRL4 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x00
+ *
+ *   7:5   NOT_USED.
+ *
+ *   4:3   ADDRESS_LEN[1:0]: length of address field in bytes
+ *
+ *   2:0   control_len[2:0]: length of control field in bytes
+ *   \endcode
+ */
+#define	PCKTCTRL4_BASE						((uint8_t)0x30) /*!< lenghts of address and control field */
+
+#define PCKTCTRL4_ADDRESS_LEN_MASK                              ((uint8_t)0x18)
+#define PCKTCTRL4_CONTROL_LEN_MASK                              ((uint8_t)0x07)
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKTCTRL3_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTCTRL3 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x07
+ *
+ *   7:6   PCKT_FRMT[1:0]: format of packet
+ *
+ *          PCKT_FRMT1       |        PCKT_FRMT0       |        Format
+ *       ----------------------------------------------------------------------
+ *             0             |           0             |        BASIC
+ *             1             |           0             |        MBUS
+ *             1             |           1             |        STACK
+ *
+ *   5:4   RX_MODE[1:0]: length of address 0x30 field in bytes
+ *
+ *          RX_MODE1       |        RX_MODE0       |            Rx Mode
+ *       --------------------------------------------------------------------
+ *             0           |           0           |              normal
+ *             0           |           1           |       direct through FIFO
+ *             1           |           0           |       direct through GPIO
+ *
+ *   3:0   LEN_WID[3:0]: length of length field in bits
+ *   \endcode
+ */
+#define	PCKTCTRL3_BASE						((uint8_t)0x31) /*!< packet format, RX mode, lenght of length field */
+
+#define	PCKTCTRL3_PCKT_FRMT_BASIC				((uint8_t)0x00) /*!< Basic Packet Format */
+#define	PCKTCTRL3_PCKT_FRMT_MBUS				((uint8_t)0x80) /*!< Wireless M-BUS Packet Format */
+#define	PCKTCTRL3_PCKT_FRMT_STACK				((uint8_t)0xC0) /*!< STack Packet Format */
+
+#define	PCKTCTRL3_RX_MODE_NORMAL				((uint8_t)0x00) /*!< Normal RX Mode */
+#define	PCKTCTRL3_RX_MODE_DIRECT_FIFO				((uint8_t)0x10) /*!< RX Direct Mode; data available through FIFO */
+#define	PCKTCTRL3_RX_MODE_DIRECT_GPIO				((uint8_t)0x20) /*!< RX Direct Mode; data available through selected GPIO */
+
+#define PCKTCTRL3_PKT_FRMT_MASK                                 ((uint8_t)0xC0)
+#define PCKTCTRL3_RX_MODE_MASK                                  ((uint8_t)0x30)
+#define PCKTCTRL3_LEN_WID_MASK                                  ((uint8_t)0x0F)
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKTCTRL2_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTCTRL2 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x1E
+ *
+ *   7:3   PREAMBLE_LENGTH[4:0]: length of preamble field in bytes (0..31)
+ *
+ *
+ *   2:1   SYNC_LENGTH[1:0]: length of sync field in bytes
+ *
+ *
+ *   0     FIX_VAR_LEN: fixed/variable packet length
+ *                       1 - Variable
+ *                       0 - Fixed
+ *   \endcode
+ */
+#define	PCKTCTRL2_BASE						((uint8_t)0x32) /*!< length of preamble and sync fields (in bytes), fix or variable packet length */
+   
+#define	PCKTCTRL2_FIX_VAR_LEN_MASK				((uint8_t)0x01) /*!< Enable/disable the length mode */
+#define PCKTCTRL2_PREAMBLE_LENGTH_MASK                          ((uint8_t)0xF8)
+#define PCKTCTRL2_SYNC_LENGTH_MASK                              ((uint8_t)0x06)
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKTCTRL1_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTCTRL1 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x20
+ *
+ *   7:5   CRC_MODE[2:0]: CRC type (0, 8, 16, 24 bits)
+ *
+ *          CRC_MODE2     |       CRC_MODE1     |        CRC_MODE0     |       CRC Mode  (n. bits - poly)
+ *       -------------------------------------------------------------------------------------------------
+ *             0           |         0          |          1           |       8 - 0x07
+ *             0           |         1          |          0           |       16 -  0x8005
+ *             0           |         1          |          1           |       16 - 0x1021
+ *             1           |         0          |          0           |       24 - 0x864CBF
+ *
+ *   4     WHIT_EN[0]: Enable Whitening
+ *                       1 - Enable
+ *                       0 - Disable
+ *
+ *   3:2   TX_SOURCE[1:0]: length of sync field in bytes
+ *
+ *          TX_SOURCE1     |        TX_SOURCE0     |        Tx Mode
+ *       --------------------------------------------------------------------
+ *             0           |           0           |       normal
+ *             0           |           1           |       direct through FIFO
+ *             1           |           0           |       direct through GPIO
+ *             1           |           1           |       pn9
+ *
+ *   1   NOT_USED
+ *
+ *   0   FEC_EN: enable FEC
+ *                       1 - FEC in TX , Viterbi decoding in RX
+ *                       0 - Disabled
+ *   \endcode
+ */
+#define	PCKTCTRL1_BASE						((uint8_t)0x33) /*!< CRC type, whitening enable, TX mode */
+
+#define	PCKTCTRL1_FEC_MASK					((uint8_t)0x01) /*!< Enable/disable the Forward Error Correction */
+#define PCKTCTRL1_TX_SOURCE_MASK                                ((uint8_t)0x0C) /*!< TX source mode */
+#define PCKTCTRL1_CRC_MODE_MASK                                 ((uint8_t)0xE0) /*!< CRC type */
+#define PCKTCTRL1_WHIT_MASK                                     ((uint8_t)0x10) /*!< Enable/disable the Whitening */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup PCKTLEN1_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTLEN1 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x00
+ *
+ *   7:0   pktlen1[7:0]: lenght of packet in bytes (upper field) LENGHT/256
+ *   \endcode
+ */
+#define	PCKTLEN1_BASE						((uint8_t)0x34) /*!< lenght of packet in bytes (upper field) */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKTLEN0_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKTLEN0 register
+ *  \code
+ *   Read Write
+ *   Default value: 0x14
+ *
+ *   7:0   pktlen0[7:0]: lenght of packet in bytes (lower field) LENGHT%256
+ *   \endcode
+ */
+#define	PCKTLEN0_BASE						((uint8_t)0x35) /*!< lenght of packet in bytes (lower field) [PCKTLEN=PCKTLEN1x256+PCKTLEN0]*/
+
+/**
+ * @}
+ */
+
+/** @defgroup SYNCx_Registers
+ * @{
+ */
+/**
+ *  \brief SYNCx[4:1] Registers
+ *  \code
+ *   Read Write
+ *   Default value: 0x88
+ *
+ *   7:0   SYNCx[7:0]: xth sync word
+ *   \endcode
+ */
+#define	SYNC4_BASE						((uint8_t)0x36) /*!< Sync word 4 */
+#define	SYNC3_BASE						((uint8_t)0x37) /*!< Sync word 3 */
+#define	SYNC2_BASE						((uint8_t)0x38) /*!< Sync word 2 */
+#define	SYNC1_BASE						((uint8_t)0x39) /*!< Sync word 1 */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MBUS_PRMBL_Register
+ * @{
+ */
+
+/**
+ *  \brief MBUS_PRMBL register
+ *  \code
+ *   Read Write
+ *   Default value: 0x20
+ *
+ *   7:0 MBUS_PRMBL[7:0]: MBUS preamble control
+ *   \endcode
+ */
+#define	MBUS_PRMBL_BASE						((uint8_t)0x3B) /*!< MBUS preamble lenght (in 01 bit pairs) */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MBUS_PSTMBL_Register
+ * @{
+ */
+
+/**
+ *  \brief MBUS_PSTMBL register
+ *  \code
+ *   Read Write
+ *   Default value: 0x20
+ *
+ *   7:0 MBUS_PSTMBL[7:0]: MBUS postamble control
+ *   \endcode
+ */
+#define	MBUS_PSTMBL_BASE					((uint8_t)0x3C) /*!< MBUS postamble length (in 01 bit pairs) */
+
+/**
+ * @}
+ */
+
+/** @defgroup MBUS_CTRL_Register
+ * @{
+ */
+
+/**
+ *  \brief MBUS_CTRL register
+ *  \code
+ *   Read Write
+ *   Default value: 0x00
+ *
+ *   7:4   NOT_USED
+ *
+ *   3:1   MBUS_SUBMODE[2:0]: MBUS submode (allowed values are 0,1,3,5)
+ *
+ *   0     NOT_USED
+ *   \endcode
+ */
+#define	MBUS_CTRL_BASE						((uint8_t)0x3D) /*!< MBUS sub-modes (S1, S2 short/long header, T1, T2, R2) */
+
+#define	MBUS_CTRL_MBUS_SUBMODE_S1_S2L				((uint8_t)0x00) /*!< MBUS sub-modes S1 & S2L, header lenght min 279, sync 0x7696, Manchester */
+#define	MBUS_CTRL_MBUS_SUBMODE_S2_S1M_T2_OTHER			((uint8_t)0x02) /*!< MBUS sub-modes S2, S1-m, T2 (only other to meter) short header, header lenght min 15, sync 0x7696, Manchester */
+#define	MBUS_CTRL_MBUS_SUBMODE_T1_T2_METER			((uint8_t)0x06) /*!< MBUS sub-modes T1, T2 (only meter to other), header lenght min 19, sync 0x3D, 3 out of 6 */
+#define	MBUS_CTRL_MBUS_SUBMODE_R2				((uint8_t)0x0A) /*!< MBUS sub-mode R2, header lenght min 39, sync 0x7696, Manchester */
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup PCKT_FLT_GOALS_CONTROLx_MASK_Registers
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_CONTROLx_MASK  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    CONTROLx_MASK[7:0]:   All 0s - no filtering
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_CONTROL0_MASK_BASE			((uint8_t)0x42) /*!< Packet control field #3 mask, all 0s -> no filtering */
+
+#define	PCKT_FLT_GOALS_CONTROL1_MASK_BASE			((uint8_t)0x43) /*!< Packet control field #2 mask, all 0s -> no filtering */
+
+#define	PCKT_FLT_GOALS_CONTROL2_MASK_BASE			((uint8_t)0x44) /*!< Packet control field #1 mask, all 0s -> no filtering */
+
+#define	PCKT_FLT_GOALS_CONTROL3_MASK_BASE			((uint8_t)0x45) /*!< Packet control field #0 mask, all 0s -> no filtering */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_CONTROLx_FIELD_Registers
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_CONTROLx_FIELD  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    CONTROLx_FIELD[7:0]:   Control field (byte x) to be used as reference
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_CONTROL0_FIELD_BASE			((uint8_t)0x46) /*!< Control field (byte #3) */
+
+#define	PCKT_FLT_GOALS_CONTROL1_FIELD_BASE			((uint8_t)0x47) /*!< Control field (byte #2) */
+
+#define	PCKT_FLT_GOALS_CONTROL2_FIELD_BASE			((uint8_t)0x48) /*!< Control field (byte #1) */
+
+#define	PCKT_FLT_GOALS_CONTROL3_FIELD_BASE			((uint8_t)0x49) /*!< Control field (byte #0) */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_SOURCE_MASK_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_SOURCE_MASK  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    RX_SOURCE_MASK[7:0]:   For received packet only: all 0s - no filtering
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_SOURCE_MASK_BASE				((uint8_t)0x4A) /*!< Source address mask, valid in RX mode */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_SOURCE_ADDR_Register
+ * @{
+ */
+/**
+ *  \brief PCKT_FLT_GOALS_SOURCE_ADDR  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    RX_SOURCE_ADDR[7:0]:  RX packet source / TX packet destination fields
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_SOURCE_ADDR_BASE				((uint8_t)0x4B) /*!< Source address */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_BROADCAST_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_BROADCAST  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    BROADCAST[7:0]:  Address shared for broadcast communication link
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_BROADCAST_BASE				((uint8_t)0x4C) /*!< Address shared for broadcast communication links */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_MULTICAST_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_MULTICAST  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    MULTICAST[7:0]:  Address shared for multicast communication links
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_MULTICAST_BASE				((uint8_t)0x4D) /*!< Address shared for multicast communication links */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_GOALS_TX_SOURCE_ADDR_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_GOALS_TX_SOURCE_ADDR  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0    TX_SOURCE_ADDR[7:0]:  TX packet source / RX packet destination fields
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_GOALS_TX_ADDR_BASE				((uint8_t)0x4E) /*!< Address of the destination (also device own address) */
+
+/**
+ * @}
+ */
+
+/** @defgroup PCKT_FLT_OPTIONS_Register
+ * @{
+ */
+
+/**
+ *  \brief PCKT_FLT_OPTIONS  register
+ *  \code
+ *   Default value: 0x70
+ *   Read Write
+ *   7   Reserved.
+ *
+ *   6   RX_TIMEOUT_AND_OR_SELECT[0]:  1 - ‘OR’ logical function applied to CS/SQI/PQI
+ *                                     values (masked by 7:5 bits in PROTOCOL register)
+ *   5   CONTROL_FILTERING[0]:         1 - RX packet accepted if its control fields matches
+ *                                     with masked CONTROLx_FIELD registers.
+ *   4   SOURCE_FILTERING[0]:          1 - RX packet accepted if its source field
+ *                                     matches w/ masked RX_SOURCE_ADDR register.
+ *   3   DEST_VS_ SOURCE _ADDR[0]:   1 - RX packet accepted if its destination
+ *                                   address matches with TX_SOURCE_ADDR reg.
+ *   2   DEST_VS_MULTICAST_ADDR[0]:  1 - RX packet accepted if its destination
+ *                                   address matches with MULTICAST register
+ *   1   DEST_VS_BROADCAST_ADDR[0]:  1 - RX packet accepted if its destination
+ *                                   address matches with BROADCAST register.
+ *   0   CRC_CHECK[0]:               1 - packet discarded if CRC not valid.
+ *
+ *   \endcode
+ */
+#define	PCKT_FLT_OPTIONS_BASE					((uint8_t)0x4F) /*!< Options relative to packet filtering */
+
+#define	PCKT_FLT_OPTIONS_CRC_CHECK_MASK 			((uint8_t)0x01) /*!< Enable/disable of CRC check: packet is discarded if CRC is not valid [RX] */
+#define	PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK		((uint8_t)0x02) /*!< Packet discarded if destination address differs from BROADCAST register [RX] */
+#define	PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK		((uint8_t)0x04) /*!< Packet discarded if destination address differs from MULTICAST register [RX] */
+#define	PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK			((uint8_t)0x08) /*!< Packet discarded if destination address differs from TX_ADDR register [RX] */
+#define	PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK		        ((uint8_t)0x10) /*!< Packet discarded if source address (masked by the SOURCE_MASK register)
+                                                                                     differs from SOURCE_ADDR register [RX] */
+#define	PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK		        ((uint8_t)0x20) /*!< Packet discarded if the x-byte (x=1¸4) control field  (masked by the CONTROLx_MASK register)
+                                                                                     differs from CONTROLx_FIELD register [RX] */
+#define	PCKT_FLT_OPTIONS_RX_TIMEOUT_AND_OR_SELECT		((uint8_t)0x40) /*!< Logical function applied to CS/SQI/PQI values (masked by [7:5] bits in PROTOCOL[2]
+                                                                                     register) */
+
+/**
+ * @}
+ */
+
+/** @defgroup TX_CTRL_FIELD_Registers
+ * @{
+ */
+
+/**
+ *  \brief TX_CTRL_FIELDx  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0     TX_CTRLx[7:0]: Control field value to be used in TX packet as byte n.x
+ *   \endcode
+ */
+#define	TX_CTRL_FIELD3_BASE					((uint8_t)0x68) /*!< Control field value to be used in TX packet as byte n.3 */
+
+#define	TX_CTRL_FIELD2_BASE					((uint8_t)0x69) /*!< Control field value to be used in TX packet as byte n.2 */
+
+#define	TX_CTRL_FIELD1_BASE					((uint8_t)0x6A) /*!< Control field value to be used in TX packet as byte n.1 */
+
+#define	TX_CTRL_FIELD0_BASE					((uint8_t)0x6B) /*!< Control field value to be used in TX packet as byte n.0 */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup TX_PCKT_INFO_Register
+ * @{
+ */
+
+/**
+ *  \brief TX_PCKT_INFO  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:6     Not used.
+ *
+ *   5:4     TX_SEQ_NUM:   Current TX packet sequence number
+ *
+ *   0       N_RETX[3:0]:  Number of retransmissions done on the
+ *                        last TX packet
+ *   \endcode
+ */
+#define	TX_PCKT_INFO_BASE					((uint8_t)(0xC2)) /*!< Current TX packet sequence number [5:4];
+                                                                                        Number of retransmissions done on the last TX packet [3:0]*/
+/**
+ * @}
+ */
+
+/** @defgroup RX_PCKT_INFO_Register
+ * @{
+ */
+
+/**
+ *  \brief RX_PCKT_INFO  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:3     Not used.
+ *
+ *   2       NACK_RX:   NACK field of the received packet
+ *
+ *   1:0     RX_SEQ_NUM[1:0]:  Sequence number of the received packet
+ *   \endcode
+ */
+#define	RX_PCKT_INFO_BASE					((uint8_t)(0xC3)) /*!< NO_ACK field of the received packet [2];
+                                                                                       sequence number of the received packet [1:0]*/
+
+#define	TX_PCKT_INFO_NACK_RX					((uint8_t)(0x04)) /*!< NACK field of the received packet */
+
+/**
+ * @}
+ */
+
+/** @defgroup RX_PCKT_LEN1
+ * @{
+ */
+
+/**
+ *  \brief RX_PCKT_LEN1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   RX_PCKT_LEN1[7:0]:  Length (number of bytes) of the received packet: RX_PCKT_LEN=RX_PCKT_LEN1 × 256 + RX_PCKT_LEN0
+ *                             This value is packet_length/256
+ *   \endcode
+ */
+#define	RX_PCKT_LEN1_BASE					((uint8_t)(0xC9)) /*!< Length (number of  bytes) of the received packet: */
+
+/**
+ * @}
+ */
+
+/** @defgroup RX_PCKT_LEN0
+ * @{
+ */
+
+/**
+ *  \brief RX_PCKT_LEN0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   RX_PCKT_LEN0[7:0]:  Length (number of bytes) of the received packet: RX_PCKT_LEN=RX_PCKT_LEN1 × 256 + RX_PCKT_LEN0
+ *                             This value is packet_length%256
+ *   \endcode
+ */
+#define	RX_PCKT_LEN0_BASE					((uint8_t)(0xCA)) /*!< RX_PCKT_LEN=RX_PCKT_LEN1 × 256 + RX_PCKT_LEN0 */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup CRC_FIELD_Register
+ * @{
+ */
+
+/**
+ *  \brief CRC_FIELD[2:0]  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   CRC_FIELDx[7:0]:    upper(x=2), middle(x=1) and lower(x=0) part of the crc field of the received packet
+ *  \endcode
+ */
+#define	CRC_FIELD2_BASE						((uint8_t)(0xCB)) /*!< CRC2 field of the received packet */
+
+#define	CRC_FIELD1_BASE						((uint8_t)(0xCC)) /*!< CRC1 field of the received packet */
+
+#define	CRC_FIELD0_BASE						((uint8_t)(0xCD)) /*!< CRC0 field of the received packet */
+
+/**
+ * @}
+ */
+
+/** @defgroup RX_CTRL_FIELD_Register
+ * @{
+ */
+
+/**
+ *  \brief RX_CTRL_FIELD[3:0]  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   RX_CTRL_FIELDx[7:0]:    upper(x=3), middle(x=2), middle(x=1) and lower(x=0) part of the control field of the received packet
+ *   \endcode
+ */
+#define	RX_CTRL_FIELD0_BASE					((uint8_t)(0xCE)) /*!< CRTL3 Control field of the received packet */
+
+#define	RX_CTRL_FIELD1_BASE					((uint8_t)(0xCF)) /*!< CRTL2 Control field of the received packet */
+
+#define	RX_CTRL_FIELD2_BASE					((uint8_t)(0xD0)) /*!< CRTL1 Control field of the received packet */
+
+#define	RX_CTRL_FIELD3_BASE					((uint8_t)(0xD1)) /*!< CRTL0 Control field of the received packet */
+
+/**
+ * @}
+ */
+
+/** @defgroup RX_ADDR_FIELD_Register
+ * @{
+ */
+
+/**
+ *  \brief RX_ADDR_FIELD[1:0]  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   RX_ADDR_FIELDx[7:0]:    source(x=1) and destination(x=0) address field of the received packet
+ *   \endcode
+ */
+#define	RX_ADDR_FIELD1_BASE					((uint8_t)(0xD2)) /*!< ADDR1 Address field of the received packet */
+
+#define	RX_ADDR_FIELD0_BASE					((uint8_t)(0xD3)) /*!< ADDR0 Address field of the received packet */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Protocol_Registers
+ * @{
+ */
+
+/** @defgroup PROTOCOL2_Register
+ * @{
+ */
+
+/**
+ *  \brief PROTOCOL2  register
+ *  \code
+ *   Default value: 0x06
+ *   Read Write
+ *   7   CS_TIMEOUT_MASK:              1 - CS value contributes to timeout disabling
+ *
+ *   6   SQI_TIMEOUT_MASK:             1 - SQI value contributes to timeout disabling
+ *
+ *   5   PQI_TIMEOUT_MASK:             1 - PQI value contributes to timeout disabling
+ *
+ *   4:3  TX_SEQ_NUM_RELOAD[1:0]:      TX sequence number to be used when counting reset is required using the related command.
+ *
+ *   2   RCO_CALIBRATION[0]:           1 - Enables the automatic RCO calibration
+ *
+ *   1   VCO_CALIBRATION[0]:           1 - Enables the automatic VCO calibration
+ *
+ *   0   LDCR_MODE[0]:                 1 - LDCR mode enabled
+ *
+ *   \endcode
+ */
+#define	PROTOCOL2_BASE						((uint8_t)0x50) /*!< Protocol2 regisetr address */
+
+#define	PROTOCOL2_LDC_MODE_MASK				        ((uint8_t)0x01) /*!< Enable/disable Low duty Cycle mode */
+#define	PROTOCOL2_VCO_CALIBRATION_MASK			        ((uint8_t)0x02) /*!< Enable/disable VCO automatic calibration */
+#define	PROTOCOL2_RCO_CALIBRATION_MASK			        ((uint8_t)0x04) /*!< Enable/disable RCO automatic calibration */
+#define	PROTOCOL2_PQI_TIMEOUT_MASK			        ((uint8_t)0x20) /*!< PQI value contributes to timeout disabling */
+#define	PROTOCOL2_SQI_TIMEOUT_MASK			        ((uint8_t)0x40) /*!< SQI value contributes to timeout disabling */
+#define	PROTOCOL2_CS_TIMEOUT_MASK			        ((uint8_t)0x80) /*!< CS value contributes to timeout disabling */
+  
+/**
+ * @}
+ */
+
+/** @defgroup PROTOCOL1_Register
+ * @{
+ */
+
+/**
+ *  \brief PROTOCOL1  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7   LDCR_RELOAD_ON_SYNC:          1 - LDCR timer will be reloaded with the value stored in the LDCR_RELOAD registers
+ *
+ *   6   PIGGYBACKING:                 1 - PIGGYBACKING enabled
+ *
+ *   5:4   Reserved.
+ *
+ *   3   SEED_RELOAD[0]:               1 - Reload the back-off random generator
+ *                                        seed using the value written in the
+ *                                        BU_COUNTER_SEED_MSByte / LSByte registers
+ *
+ *   2   CSMA_ON   [0]:                1 - CSMA channel access mode enabled
+ *
+ *   1   CSMA_PERS_ON[0]:              1 - CSMA persistent (no back-off) enabled
+ *
+ *   0   AUTO_PCKT_FLT[0]:             1 - automatic packet filtering mode enabled
+ *
+ *   \endcode
+ */
+#define	PROTOCOL1_BASE						((uint8_t)0x51) /*!< Protocol1 regisetr address */
+
+#define	PROTOCOL1_AUTO_PCKT_FLT_MASK				((uint8_t)0x01) /*!< Enable/disable automatic packet filtering mode */
+#define	PROTOCOL1_CSMA_PERS_ON_MASK				((uint8_t)0x02) /*!< Enable/disable CSMA persistent (no back-off)  */
+#define	PROTOCOL1_CSMA_ON_MASK				        ((uint8_t)0x04) /*!< Enable/disable CSMA channel access mode */
+#define	PROTOCOL1_SEED_RELOAD_MASK				((uint8_t)0x08) /*!< Reloads the seed of the PN generator for CSMA procedure */
+#define	PROTOCOL1_PIGGYBACKING_MASK				((uint8_t)0x40) /*!< Enable/disable Piggybacking */
+#define	PROTOCOL1_LDC_RELOAD_ON_SYNC_MASK			((uint8_t)0x80) /*!< LDC timer will be reloaded with the value stored in the LDC_RELOAD registers */
+
+/**
+ * @}
+ */
+
+/** @defgroup PROTOCOL0_Register
+ * @{
+ */
+
+/**
+ *  \brief PROTOCOL0  register
+ *  \code
+ *   Default value: 0x08
+ *   Read Write
+ *   7:4   NMAX_RETX[3:0]:             Max number of re-TX.  0 - re-transmission is not performed
+ *
+ *   3     NACK_TX[0]:                 1 - field NO_ACK=1 on transmitted packet
+ *
+ *   2     AUTO_ACK[0]:                1 - automatic ack after RX
+ *
+ *   1     PERS_RX[0]:                 1 - persistent reception enabled
+ *
+ *   0     PERS_TX[0]:                 1 - persistent transmission enabled
+ *
+ *   \endcode
+ */
+#define	PROTOCOL0_BASE						((uint8_t)0x52) /*!< Persistent RX/TX, autoack, Max number of retransmissions */
+
+#define	PROTOCOL0_PERS_TX_MASK				        ((uint8_t)0x01) /*!< Enables persistent transmission */
+#define	PROTOCOL0_PERS_RX_MASK				        ((uint8_t)0x02) /*!< Enables persistent reception */
+#define	PROTOCOL0_AUTO_ACK_MASK				        ((uint8_t)0x04) /*!< Enables auto acknowlegment */
+#define	PROTOCOL0_NACK_TX_MASK				        ((uint8_t)0x08) /*!< Writes field NO_ACK=1 on transmitted packet */
+#define	PROTOCOL0_NMAX_RETX_MASK                                ((uint8_t)0xF0) /*!< Retransmission mask */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS5_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS5  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   RX_TIMEOUT_PRESCALER[7:0] :             RX operation timeout: prescaler value
+ *   \endcode
+ */
+#define	TIMERS5_RX_TIMEOUT_PRESCALER_BASE			((uint8_t)0x53) /*!< RX operation timeout: prescaler value */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS4_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS4  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   RX_TIMEOUT_COUNTER[7:0] :               RX operation timeout: counter value
+ *   \endcode
+ */
+#define	TIMERS4_RX_TIMEOUT_COUNTER_BASE				((uint8_t)0x54) /*!< RX operation timeout: counter value */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS3_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS3  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   LDCR_PRESCALER[7:0] :                   LDC Mode: Prescaler part of the wake-up value
+ *   \endcode
+ */
+#define	TIMERS3_LDC_PRESCALER_BASE				((uint8_t)0x55) /*!< LDC Mode: Prescaler of the wake-up timer */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS2_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS2  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   LDCR_COUNTER[7:0] :                    LDC Mode: counter part of the wake-up value
+ *   \endcode
+ */
+#define	TIMERS2_LDC_COUNTER_BASE				((uint8_t)0x56) /*!< LDC Mode: counter of the wake-up timer */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS1_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS1  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   LDCR_RELOAD_PRESCALER[7:0] :           LDC Mode: Prescaler part of the reload value
+ *   \endcode
+ */
+#define	TIMERS1_LDC_RELOAD_PRESCALER_BASE			((uint8_t)0x57) /*!< LDC Mode: Prescaler part of the reload value */
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMERS0_Register
+ * @{
+ */
+
+/**
+ *  \brief TIMERS0  register
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0   LDCR_RELOAD_COUNTER[7:0] :           LDC Mode: Counter part of the reload value
+ *   \endcode
+ */
+#define	TIMERS0_LDC_RELOAD_COUNTER_BASE				((uint8_t)0x58) /*!< LDC Mode: Counter part of the reload value */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup CSMA_CONFIG3_Register
+ * @{
+ */
+
+/**
+ *  \brief CSMA_CONFIG3  registers
+ *  \code
+ *   Default value: 0xFF
+ *   Read Write
+ *   7:0     BU_COUNTER_SEED_MSByte: Seed of the random number generator used to apply the BEB (Binary Exponential Backoff) algorithm (MSB)
+ *   \endcode
+ */
+#define	CSMA_CONFIG3_BASE		                      ((uint8_t)0x64) /*!< CSMA/CA: Seed of the random number generator used to apply the BEB (Binary Exponential Backoff) algorithm (MSB) */
+
+/**
+ * @}
+ */
+
+/** @defgroup CSMA_CONFIG2_Register
+ * @{
+ */
+
+/**
+ *  \brief CSMA_CONFIG2  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:0     BU_COUNTER_SEED_LSByte: Seed of the random number generator used to apply the BEB (Binary Exponential Backoff) algorithm (LSB)
+ *   \endcode
+ */
+#define	CSMA_CONFIG2_BASE		                      ((uint8_t)0x65) /*!< CSMA/CA: Seed of the random number generator used to apply the BEB (Binary Exponential Backoff) algorithm (LSB) */
+
+/**
+ * @}
+ */
+
+/** @defgroup CSMA_CONFIG1_Register
+ * @{
+ */
+
+/**
+ *  \brief CSMA_CONFIG1  registers
+ *  \code
+ *   Default value: 0x04
+ *   Read Write
+ *   7:2     BU_PRESCALER[5:0]: Used to program the back-off unit BU
+ *
+ *   1:0     CCA_PERIOD[1:0]: Used to program the Tcca time (64 / 128 /256 / 512 × Tbit.
+ *   \endcode
+ */
+#define	CSMA_CONFIG1_BASE				      ((uint8_t)0x66) /*!< CSMA/CA: Prescaler of the back-off time unit (BU); CCA period */
+
+#define	CSMA_CCA_PERIOD_64TBIT				      ((uint8_t)0x00) /*!< CSMA/CA: Sets CCA period to 64*TBIT */
+#define	CSMA_CCA_PERIOD_128TBIT				      ((uint8_t)0x01) /*!< CSMA/CA: Sets CCA period to 128*TBIT */
+#define	CSMA_CCA_PERIOD_256TBIT				      ((uint8_t)0x02) /*!< CSMA/CA: Sets CCA period to 256*TBIT */
+#define	CSMA_CCA_PERIOD_512TBIT				      ((uint8_t)0x03) /*!< CSMA/CA: Sets CCA period to 512*TBIT */
+
+/**
+ * @}
+ */
+
+/** @defgroup CSMA_CONFIG0_Register
+ * @{
+ */
+
+/**
+ *  \brief CSMA_CONFIG0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *   7:4     CCA_LENGTH[3:0]: Used to program the Tlisten time
+ *
+ *   3       Reserved.
+ *
+ *   2:0     NBACKOFF_MAX[2:0]: Max number of back-off cycles.
+ *   \endcode
+ */
+#define	CSMA_CONFIG0_BASE				      ((uint8_t)0x67) /*!< CSMA/CA: CCA lenght; Max number of backoff cycles */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Link_Quality_Registers
+ * @{
+ */
+
+/** @defgroup QI_Register
+ * @{
+ */
+
+/**
+ *  \brief QI register
+ *  \code
+ *   Read Write
+ *   Default value: 0x02
+ *
+ *   7:6   SQI_TH[1:0]: SQI threshold according to the formula: 8*SYNC_LEN - 2*SQI_TH
+ *
+ *   5:2   PQI_TH[3:0]: PQI threshold according to the formula: 4*PQI_THR
+ *
+ *
+ *   1     SQI_EN[0]:  SQI enable
+ *                 1 - Enable
+ *                 0 - Disable
+ *
+ *   0     PQI_EN[0]: PQI enable
+ *                 1 - Enable
+ *                 0 - Disable
+ *   \endcode
+ */
+#define	QI_BASE							((uint8_t)0x3A) /*!< QI register */
+
+#define	QI_PQI_MASK					        ((uint8_t)0x01) /*!< PQI enable/disable  */
+#define	QI_SQI_MASK					        ((uint8_t)0x02) /*!< SQI enable/disable  */
+
+/**
+ * @}
+ */
+
+/** @defgroup LINK_QUALIF2
+ * @{
+ */
+
+/**
+ *  \brief LINK_QUALIF2  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   PQI[7:0]: PQI value of the received packet
+ *   \endcode
+ */
+#define	LINK_QUALIF2_BASE					((uint8_t)(0xC5)) /*!< PQI value of the received packet */
+
+/**
+ * @}
+ */
+
+/** @defgroup LINK_QUALIF1
+ * @{
+ */
+
+/**
+ *  \brief LINK_QUALIF1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7 CS:  Carrier Sense indication
+ *
+ *   6:0   SQI[6:0]: SQI value of the received packet
+ *   \endcode
+ */
+#define	LINK_QUALIF1_BASE					((uint8_t)(0xC6)) /*!< Carrier sense indication [7]; SQI value of the received packet */
+
+#define	LINK_QUALIF1_CS						((uint8_t)(0x80)) /*!< Carrier sense indication [7] */
+
+/**
+ * @}
+ */
+
+/** @defgroup LINK_QUALIF0
+ * @{
+ */
+
+/**
+ *  \brief LINK_QUALIF0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:4   LQI [3:0]:  LQI value of the received packet
+ *
+ *   3:0   AGC_WORD[3:0]: AGC word of the received packet
+ *   \endcode
+ */
+#define	LINK_QUALIF0_BASE					((uint8_t)(0xC7)) /*!< LQI value of the received packet [7:4]; AGC word of the received packet [3:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup RSSI_LEVEL
+ * @{
+ */
+
+/**
+ *  \brief RSSI_LEVEL  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   RSSI_LEVEL[7:0]:  RSSI level of the received packet
+ *   \endcode
+ */
+#define	RSSI_LEVEL_BASE						((uint8_t)(0xC8)) /*!< RSSI level of the received packet */
+
+/**
+ * @}
+ */
+
+/** @defgroup RSSI_FLT_Register
+ * @{
+ */
+
+/**
+ *  \brief RSSI register
+ *  \code
+ *   Read Write
+ *   Default value: 0xF3
+ *   7:4  RSSI_FLT[3:0]: Gain of the RSSI filter
+ *
+ *   3:2  CS_MODE[1:0]: AFC loop gain in slow mode (2's log)
+ *
+ *          CS_MODE1       |        CS_MODE0       |                     CS Mode
+ *       -----------------------------------------------------------------------------------------
+ *             0           |           0           |        Static CS
+ *             0           |           1           |        Dynamic CS with 6dB dynamic threshold
+ *             1           |           0           |        Dynamic CS with 12dB dynamic threshold
+ *             1           |           1           |        Dynamic CS with 18dB dynamic threshold
+ *
+ *   1:0   OOK_PEAK_DECAY[1:0]: Peak decay control for OOK: 3 slow decay; 0 fast decay
+ *
+ *   \endcode
+ */
+#define	RSSI_FLT_BASE						((uint8_t)0x21) /*!< Gain of the RSSI filter; lower value is fast but inaccurate,
+																	higher value is slow and more accurate */
+#define RSSI_FLT_CS_MODE_MASK					((uint8_t)0x0C) /*!< Carrier sense mode mask */
+#define RSSI_FLT_CS_MODE_STATIC					((uint8_t)0x00) /*!< Carrier sense mode;  static carrier sensing */
+#define RSSI_FLT_CS_MODE_DYNAMIC_6				((uint8_t)0x04) /*!< Carrier sense mode;  dynamic carrier sensing with 6dB threshold */
+#define RSSI_FLT_CS_MODE_DYNAMIC_12				((uint8_t)0x08) /*!< Carrier sense mode;  dynamic carrier sensing with 12dB threshold */
+#define RSSI_FLT_CS_MODE_DYNAMIC_18				((uint8_t)0x0C) /*!< Carrier sense mode;  dynamic carrier sensing with 18dB threshold */
+#define RSSI_FLT_OOK_PEAK_DECAY_MASK			        ((uint8_t)0x03) /*!< Peak decay control for OOK mask */
+#define RSSI_FLT_OOK_PEAK_DECAY_FAST			        ((uint8_t)0x00) /*!< Peak decay control for OOK: fast decay */
+#define RSSI_FLT_OOK_PEAK_DECAY_MEDIUM_FAST		        ((uint8_t)0x01) /*!< Peak decay control for OOK: medium_fast decay */
+#define RSSI_FLT_OOK_PEAK_DECAY_MEDIUM_SLOW		        ((uint8_t)0x02) /*!< Peak decay control for OOK: medium_fast decay */
+#define RSSI_FLT_OOK_PEAK_DECAY_SLOW			        ((uint8_t)0x03) /*!< Peak decay control for OOK: slow decay */
+
+/**
+ * @}
+ */
+
+/** @defgroup RSSI_TH_Register
+ * @{
+ */
+
+/**
+ *  \brief RSSI_TH register
+ *  \code
+ *   Read Write
+ *   Default value: 0x24
+ *
+ *   7:0 RSSI_THRESHOLD [7:0]:    Signal detect threshold in 0.5dB.  -120dBm corresponds to 20
+ *   \endcode
+ */
+#define	RSSI_TH_BASE						((uint8_t)0x22) /*!< Signal detect threshold in 0.5dB stp. 20 correspond to -120 dBm */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup FIFO_Registers
+ * @{
+ */
+
+/** @defgroup FIFO_CONFIG3_Register
+ * @{
+ */
+
+/**
+ *  \brief FIFO_CONFIG3  registers
+ *  \code
+ *   Default value: 0x30
+ *   Read Write
+ *   7    Reserved.
+ *
+ *   6:0  rxafthr [6:0]: FIFO Almost Full threshold for rx fifo.
+ *
+ *   \endcode
+ */
+#define	FIFO_CONFIG3_RXAFTHR_BASE				((uint8_t)0x3E) /*!< FIFO Almost Full threshold for rx fifo [6:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup FIFO_CONFIG2_Register
+ * @{
+ */
+
+/**
+ *  \brief FIFO_CONFIG2  registers
+ *  \code
+ *   Default value: 0x30
+ *   Read Write
+ *   7    Reserved.
+ *
+ *   6:0  rxaethr [6:0]: FIFO Almost Empty threshold for rx fifo.
+ *
+ *   \endcode
+ */
+#define	FIFO_CONFIG2_RXAETHR_BASE				((uint8_t)0x3F) /*!< FIFO Almost Empty threshold for rx fifo [6:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup FIFO_CONFIG1_Register
+ * @{
+ */
+
+/**
+ *  \brief FIFO_CONFIG1  registers
+ *  \code
+ *   Default value: 0x30
+ *   Read Write
+ *   7    Reserved.
+ *
+ *   6:0  txafthr [6:0]: FIFO Almost Full threshold for tx fifo.
+ *
+ *   \endcode
+ */
+#define	FIFO_CONFIG1_TXAFTHR_BASE				((uint8_t)0x40) /*!< FIFO Almost Full threshold for tx fifo [6:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup FIFO_CONFIG0_Register
+ * @{
+ */
+
+/**
+ *  \brief FIFO_CONFIG0  registers
+ *  \code
+ *   Default value: 0x30
+ *   Read Write
+ *   7    Reserved.
+ *
+ *   6:0  txaethr [6:0]: FIFO Almost Empty threshold for tx fifo.
+ *
+ *   \endcode
+ */
+#define	FIFO_CONFIG0_TXAETHR_BASE				((uint8_t)0x41) /*!< FIFO Almost Empty threshold for tx fifo [6:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup LINEAR_FIFO_STATUS1_Register
+ * @{
+ */
+
+/**
+ *  \brief LINEAR_FIFO_STATUS1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7     Reserved.
+ *
+ *   6:0   elem_txfifo[6:0]:     Number of elements in the linear TXFIFO (<=96)
+ *   \endcode
+ */
+#define	LINEAR_FIFO_STATUS1_BASE				((uint8_t)(0xE6)) /*!< Number of elements in the linear TX FIFO [6:0] (<=96) */
+
+/**
+ * @}
+ */
+
+/** @defgroup LINEAR_FIFO_STATUS0_Register
+ * @{
+ */
+
+/**
+ *  \brief LINEAR_FIFO_STATUS0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7     Reserved.
+ *
+ *   6:0   elem_rxfifo[6:0]:     Number of elements in the linear RXFIFO (<=96)
+ *   \endcode
+ */
+#define	LINEAR_FIFO_STATUS0_BASE				((uint8_t)(0xE7)) /*!< Number of elements in the linear RX FIFO [6:0] (<=96) */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Calibration_Registers
+ * @{
+ */
+
+/** @defgroup RCO_VCO_CALIBR_IN2_Register
+ * @{
+ */
+
+/**
+ *  \brief RCO_VCO_CALIBR_IN2  registers
+ *  \code
+ *   Default value: 0x70
+ *   Read Write
+ *   7:4     RWT_IN[3:0]: RaWThermometric word value for the RCO [7:4]
+ *
+ *   3:0     RFB_IN[4:1]: ResistorFineBit word value for the RCO (first 4 bits)
+ *   \endcode
+ */
+#define	RCO_VCO_CALIBR_IN2_BASE					((uint8_t)0x6D) /*!< RaWThermometric word value for the RCO [7:4]; ResistorFineBit word value for the RCO [3:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCO_VCO_CALIBR_IN1_Register
+ * @{
+ */
+
+/**
+ *  \brief RCO_VCO_CALIBR_IN1  registers
+ *  \code
+ *   Default value: 0x48
+ *   Read Write
+ *
+ *   7     RFB_IN[0]: ResistorFineBit word value for the RCO (LSb)
+ *
+ *   6:0   VCO_CALIBR_TX[6:0]:  Word value for the VCO to be used in TX mode
+ *   \endcode
+ */
+#define	RCO_VCO_CALIBR_IN1_BASE					((uint8_t)0x6E) /*!< ResistorFineBit word value for the RCO [7]; Word value for the VCO to be used in TX mode  [6:0]*/
+
+/**
+ * @}
+ */
+
+/** @defgroup RCO_VCO_CALIBR_IN0_Register
+ * @{
+ */
+
+/**
+ *  \brief RCO_VCO_CALIBR_IN0  registers
+ *  \code
+ *   Default value: 0x48
+ *   Read Write
+ *
+ *   7     Reserved.
+ *
+ *   6:0   VCO_CALIBR_RX[6:0]:  Word value for the VCO to be used in RX mode
+ *   \endcode
+ */
+#define	RCO_VCO_CALIBR_IN0_BASE					((uint8_t)0x6F) /*!< Word value for the VCO to be used in RX mode [6:0] */
+
+/**
+ * @}
+ */
+
+/** @defgroup RCO_VCO_CALIBR_OUT1_Register
+ * @{
+ */
+
+/**
+ *  \brief RCO_VCO_CALIBR_OUT1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:4   RWT_OUT[3:0]:    RWT word from internal RCO calibrator
+ *
+ *   3:0   RFB_OUT[4:1]:     RFB word from internal RCO calibrator (upper part)
+ *   \endcode
+ */
+#define	RCO_VCO_CALIBR_OUT1_BASE				((uint8_t)(0xE4)) /*!< RaWThermometric RWT word from internal RCO calibrator [7];
+                                                                                       ResistorFineBit RFB word from internal RCO oscillator [6:0] */
+/**
+ * @}
+ */
+
+/** @defgroup RCO_VCO_CALIBR_OUT0_Register
+ * @{
+ */
+
+/**
+ *  \brief RCO_VCO_CALIBR_OUT0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7     RFB_OUT[0]:    RFB word from internal RCO calibrator (last bit LSB)
+ *
+ *   6:0   VCO_CALIBR_DATA[6:0]:     Output word from internal VCO calibrator
+ *   \endcode
+ */
+#define	RCO_VCO_CALIBR_OUT0_BASE				((uint8_t)(0xE5)) /*!< ResistorFineBit RFB word from internal RCO oscillator [0];
+                                                                                       Output word from internal calibrator [6:0]; */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup AES_Registers
+ * @{
+ */
+
+/** @defgroup AES_KEY_IN_Register
+ * @{
+ */
+
+/**
+ *  \brief AES_KEY_INx  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   AES_KEY_INx[7:0]:  AES engine key input (total - 128 bits)
+ *   \endcode
+ */
+#define	AES_KEY_IN_15_BASE					((uint8_t)0x70) /*!< AES engine key input 15 */
+   
+#define	AES_KEY_IN_14_BASE					((uint8_t)0x71) /*!< AES engine key input 14 */
+
+#define	AES_KEY_IN_13_BASE					((uint8_t)0x72) /*!< AES engine key input 13 */
+
+#define	AES_KEY_IN_12_BASE					((uint8_t)0x73) /*!< AES engine key input 12 */
+
+#define	AES_KEY_IN_11_BASE					((uint8_t)0x74) /*!< AES engine key input 11 */
+
+#define	AES_KEY_IN_10_BASE					((uint8_t)0x75) /*!< AES engine key input 10 */
+
+#define	AES_KEY_IN_9_BASE					((uint8_t)0x76) /*!< AES engine key input 9 */
+
+#define	AES_KEY_IN_8_BASE					((uint8_t)0x77) /*!< AES engine key input 8 */
+
+#define	AES_KEY_IN_7_BASE					((uint8_t)0x78) /*!< AES engine key input 7 */
+
+#define	AES_KEY_IN_6_BASE					((uint8_t)0x79) /*!< AES engine key input 6 */
+
+#define	AES_KEY_IN_5_BASE					((uint8_t)0x7A) /*!< AES engine key input 5 */
+
+#define	AES_KEY_IN_4_BASE					((uint8_t)0x7B) /*!< AES engine key input 4 */
+
+#define	AES_KEY_IN_3_BASE					((uint8_t)0x7C) /*!< AES engine key input 3 */
+
+#define	AES_KEY_IN_2_BASE					((uint8_t)0x7D) /*!< AES engine key input 2 */
+
+#define	AES_KEY_IN_1_BASE					((uint8_t)0x7E) /*!< AES engine key input 1 */
+
+#define	AES_KEY_IN_0_BASE					((uint8_t)0x7F) /*!< AES engine key input 0 */
+
+/**
+ * @}
+ */
+
+/** @defgroup AES_DATA_IN_Register
+ * @{
+ */
+
+/**
+ *  \brief AES_DATA_INx  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   AES_DATA_INx[7:0]:  AES engine data input (total - 128 bits)
+ *   \endcode
+ */
+#define	AES_DATA_IN_15_BASE					((uint8_t)0x80) /*!< AES engine data input 15
+                                                                                     Take care: Address is in reverse order respect data numbering; eg.: 0x81 -> AES_data14[7:0] */
+#define	AES_DATA_IN_14_BASE					((uint8_t)0x81) /*!< AES engine data input 14 */
+
+#define	AES_DATA_IN_13_BASE					((uint8_t)0x82) /*!< AES engine data input 13 */
+
+#define	AES_DATA_IN_12_BASE					((uint8_t)0x83) /*!< AES engine data input 12 */
+
+#define	AES_DATA_IN_11_BASE					((uint8_t)0x84) /*!< AES engine data input 11 */
+
+#define	AES_DATA_IN_10_BASE					((uint8_t)0x85) /*!< AES engine data input 10 */
+
+#define	AES_DATA_IN_9_BASE					((uint8_t)0x86) /*!< AES engine data input 9 */
+
+#define	AES_DATA_IN_8_BASE					((uint8_t)0x87) /*!< AES engine data input 8 */
+
+#define	AES_DATA_IN_7_BASE					((uint8_t)0x88) /*!< AES engine data input 7 */
+
+#define	AES_DATA_IN_6_BASE					((uint8_t)0x89) /*!< AES engine data input 6 */
+
+#define	AES_DATA_IN_5_BASE					((uint8_t)0x8A) /*!< AES engine data input 5 */
+
+#define	AES_DATA_IN_4_BASE					((uint8_t)0x8B) /*!< AES engine data input 4 */
+
+#define	AES_DATA_IN_3_BASE					((uint8_t)0x8C) /*!< AES engine data input 3 */
+
+#define	AES_DATA_IN_2_BASE					((uint8_t)0x8D) /*!< AES engine data input 2 */
+
+#define	AES_DATA_IN_1_BASE					((uint8_t)0x8E) /*!< AES engine data input 1 */
+
+#define	AES_DATA_IN_0_BASE					((uint8_t)0x8F) /*!< AES engine data input 0 */
+
+/**
+ * @}
+ */
+
+/** @defgroup AES_DATA_OUT_Register
+ * @{
+ */
+
+/**
+ *  \brief AES_DATA_OUT[15:0]  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:0   AES_DATA_OUTx[7:0]:    AES engine data output (128 bits)
+ *   \endcode
+ */
+#define	AES_DATA_OUT_15_BASE					((uint8_t)(0xD4)) /*!< AES engine data output 15 */
+
+#define	AES_DATA_OUT_14_BASE					((uint8_t)(0xD5)) /*!< AES engine data output 14 */
+
+#define	AES_DATA_OUT_13_BASE					((uint8_t)(0xD6)) /*!< AES engine data output 13 */
+
+#define	AES_DATA_OUT_12_BASE					((uint8_t)(0xD7)) /*!< AES engine data output 12 */
+
+#define	AES_DATA_OUT_11_BASE					((uint8_t)(0xD8)) /*!< AES engine data output 11 */
+
+#define	AES_DATA_OUT_10_BASE					((uint8_t)(0xD9)) /*!< AES engine data output 10 */
+
+#define	AES_DATA_OUT_9_BASE					((uint8_t)(0xDA)) /*!< AES engine data output 9 */
+
+#define	AES_DATA_OUT_8_BASE					((uint8_t)(0xDB)) /*!< AES engine data output 8 */
+
+#define	AES_DATA_OUT_7_BASE					((uint8_t)(0xDC)) /*!< AES engine data output 7 */
+
+#define	AES_DATA_OUT_6_BASE					((uint8_t)(0xDD)) /*!< AES engine data output 6 */
+
+#define	AES_DATA_OUT_5_BASE					((uint8_t)(0xDE)) /*!< AES engine data output 5 */
+
+#define	AES_DATA_OUT_4_BASE					((uint8_t)(0xDF)) /*!< AES engine data output 4 */
+
+#define	AES_DATA_OUT_3_BASE					((uint8_t)(0xE0)) /*!< AES engine data output 3 */
+
+#define	AES_DATA_OUT_2_BASE					((uint8_t)(0xE1)) /*!< AES engine data output 2 */
+
+#define	AES_DATA_OUT_1_BASE					((uint8_t)(0xE2)) /*!< AES engine data output 1 */
+
+#define	AES_DATA_OUT_0_BASE					((uint8_t)(0xE3)) /*!< AES engine data output 0 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_Registers
+ * @{
+ */
+
+/** @defgroup IRQ_MASK0_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_MASK0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_MASK0:  IRQ mask, if the correspondent bit is set and IRQ can be generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            0   |       RX data ready
+ *            1   |       RX data discarded (upon filtering)
+ *            2   |       TX data sent
+ *            3   |       Max re-TX reached
+ *            4   |       CRC error
+ *            5   |       TX FIFO underflow/overflow error
+ *            6   |       RX FIFO underflow/overflow error
+ *            7   |       TX FIFO almost full
+ *    \endcode
+ */
+
+
+#define	IRQ_MASK0_BASE						((uint8_t)0x93) /*!< IRQ_MASK is split into 4 registers*/
+
+#define IRQ_MASK0_RX_DATA_READY					((uint8_t)0x01) /*!< IRQ: RX data ready */
+#define IRQ_MASK0_RX_DATA_DISC					((uint8_t)0x02) /*!< IRQ: RX data discarded (upon filtering) */
+#define IRQ_MASK0_TX_DATA_SENT					((uint8_t)0x04) /*!< IRQ: TX data sent */
+#define IRQ_MASK0_MAX_RE_TX_REACH				((uint8_t)0x08) /*!< IRQ: Max re-TX reached */
+#define IRQ_MASK0_CRC_ERROR					((uint8_t)0x10) /*!< IRQ: CRC error */
+#define IRQ_MASK0_TX_FIFO_ERROR					((uint8_t)0x20) /*!< IRQ: TX FIFO underflow/overflow error */
+#define IRQ_MASK0_RX_FIFO_ERROR					((uint8_t)0x40) /*!< IRQ: RX FIFO underflow/overflow error */
+#define IRQ_MASK0_TX_FIFO_ALMOST_FULL				((uint8_t)0x80) /*!< IRQ: TX FIFO almost full */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_MASK1_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_MASK1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_MASK1:  IRQ mask, if the correspondent bit is set and IRQ can be generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            8   |       TX FIFO almost empty
+ *            9   |       RX FIFO almost full
+ *            10  |       RX FIFO almost empty
+ *            11  |       Max number of back-off during CCA
+ *            12  |       Valid preamble detected
+ *            13  |       Sync word detected
+ *            14  |       RSSI above threshold (Carrier Sense)
+ *            15  |       Wake-up timeout in LDCR mode13
+ *     \endcode
+ */
+
+#define	IRQ_MASK1_BASE						((uint8_t)0x92) /*!< IRQ_MASK is split into 4 registers*/
+
+#define IRQ_MASK1_TX_FIFO_ALMOST_EMPTY				((uint8_t)0x01) /*!< IRQ: TX FIFO almost empty */
+#define IRQ_MASK1_RX_FIFO_ALMOST_FULL				((uint8_t)0x02) /*!< IRQ: RX FIFO almost full */
+#define IRQ_MASK1_RX_FIFO_ALMOST_EMPTY				((uint8_t)0x04) /*!< IRQ: RX FIFO almost empty  */
+#define IRQ_MASK1_MAX_BO_CCA_REACH				((uint8_t)0x08) /*!< IRQ: Max number of back-off during CCA */
+#define IRQ_MASK1_VALID_PREAMBLE				((uint8_t)0x10) /*!< IRQ: Valid preamble detected */
+#define IRQ_MASK1_VALID_SYNC					((uint8_t)0x20) /*!< IRQ: Sync word detected */
+#define IRQ_MASK1_RSSI_ABOVE_TH					((uint8_t)0x40) /*!< IRQ: RSSI above threshold */
+#define IRQ_MASK1_WKUP_TOUT_LDC					((uint8_t)0x80) /*!< IRQ: Wake-up timeout in LDC mode */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_MASK2_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_MASK2  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_MASK2:  IRQ mask, if the correspondent bit is set and IRQ can be generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            16  |       READY state in steady condition14
+ *            17  |       STANDBY state switching in progress
+ *            18  |       Low battery level
+ *            19  |       Power-On reset
+ *            20  |       Brown-Out event
+ *            21  |       LOCK state in steady condition
+ *            22  |       PM start-up timer expiration
+ *            23  |       XO settling timeout
+ *   \endcode
+ */
+#define	IRQ_MASK2_BASE						((uint8_t)0x91) /*!< IRQ_MASK is split into 4 registers*/
+
+#define IRQ_MASK2_READY						((uint8_t)0x01) /*!< IRQ: READY state */
+#define IRQ_MASK2_STANDBY_DELAYED				((uint8_t)0x02) /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */
+#define IRQ_MASK2_LOW_BATT_LVL					((uint8_t)0x04) /*!< IRQ: Battery level below threshold*/
+#define IRQ_MASK2_POR						((uint8_t)0x08) /*!< IRQ: Power On Reset */
+#define IRQ_MASK2_BOR						((uint8_t)0x10) /*!< IRQ: Brown out event (both accurate and inaccurate)*/
+#define IRQ_MASK2_LOCK						((uint8_t)0x20) /*!< IRQ: LOCK state */
+#define IRQ_MASK2_PM_COUNT_EXPIRED				((uint8_t)0x40) /*!< IRQ: only for debug; Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */
+#define IRQ_MASK2_XO_COUNT_EXPIRED				((uint8_t)0x80) /*!< IRQ: only for debug; Crystal oscillator settling time counter expired */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_MASK3_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_MASK3  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_MASK3:  IRQ mask, if the correspondent bit is set and IRQ can be generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            24  |       SYNTH locking timeout
+ *            25  |       SYNTH calibration start-up time
+ *            26  |       SYNTH calibration timeout
+ *            27  |       TX circuitry start-up time
+ *            28  |       RX circuitry start-up time
+ *            29  |       RX operation timeout
+ *            30  |       Others AES End–of –Operation
+ *            31  |       Reserved
+ *   \endcode
+ */
+#define	IRQ_MASK3_BASE						((uint8_t)0x90) /*!< IRQ_MASK is split into 4 registers*/
+
+#define IRQ_MASK3_SYNTH_LOCK_TIMEOUT			        ((uint8_t)0x01) /*!< IRQ: only for debug; LOCK state timeout */
+#define IRQ_MASK3_SYNTH_LOCK_STARTUP			        ((uint8_t)0x02) /*!< IRQ: only for debug; see CALIBR_START_COUNTER */
+#define IRQ_MASK3_SYNTH_CAL_TIMEOUT				((uint8_t)0x04) /*!< IRQ: only for debug; SYNTH calibration timeout */
+#define IRQ_MASK3_TX_START_TIME					((uint8_t)0x08) /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */
+#define IRQ_MASK3_RX_START_TIME					((uint8_t)0x10) /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */
+#define IRQ_MASK3_RX_TIMEOUT					((uint8_t)0x20) /*!< IRQ: RX operation timeout */
+#define IRQ_MASK3_AES_END					((uint8_t)0x40) /*!< IRQ: AES End of operation */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup IRQ_STATUS0_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_STATUS0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_STATUS0:  IRQ status, if the correspondent bit is set and IRQ has been generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            0   |       RX data ready
+ *            1   |       RX data discarded (upon filtering)
+ *            2   |       TX data sent
+ *            3   |       Max re-TX reached
+ *            4   |       CRC error
+ *            5   |       TX FIFO underflow/overflow error
+ *            6   |       RX FIFO underflow/overflow error
+ *            7   |       TX FIFO almost full
+ *   \endcode
+ */
+
+#define IRQ_STATUS0_BASE					((uint8_t)(0xFD)) /*!< IRQ Events(RR, split into 4 registers) */
+
+#define IRQ_STATUS0_SYNTH_LOCK_TIMEOUT				((uint8_t)(0x01)) /*!< IRQ: LOCK state timeout */
+#define IRQ_STATUS0_SYNTH_LOCK_STARTUP				((uint8_t)(0x02)) /*!< IRQ: only for debug; see CALIBR_START_COUNTER */
+#define IRQ_STATUS0_SYNTH_CAL_TIMEOUT				((uint8_t)(0x04)) /*!< IRQ: SYNTH locking timeout */
+#define IRQ_STATUS0_TX_START_TIME				((uint8_t)(0x08)) /*!< IRQ: only for debug; TX circuitry startup time; see TX_START_COUNTER */
+#define IRQ_STATUS0_RX_START_TIME				((uint8_t)(0x10)) /*!< IRQ: only for debug; RX circuitry startup time; see TX_START_COUNTER */
+#define IRQ_STATUS0_RX_TIMEOUT					((uint8_t)(0x20)) /*!< IRQ: RX operation timeout expiration */
+#define IRQ_STATUS0_AES_END					((uint8_t)(0x40)) /*!< IRQ: AES End of operation */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_STATUS1_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_STATUS1  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_STATUS1:  IRQ status, if the correspondent bit is set and IRQ has been generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            8   |       TX FIFO almost empty
+ *            9   |       RX FIFO almost full
+ *            10  |       RX FIFO almost empty
+ *            11  |       Max number of back-off during CCA
+ *            12  |       Valid preamble detected
+ *            13  |       Sync word detected
+ *            14  |       RSSI above threshold (Carrier Sense)
+ *            15  |       Wake-up timeout in LDCR mode13
+ *   \endcode
+ */
+
+#define IRQ_STATUS1_BASE					((uint8_t)(0xFC)) /*!< IRQ Events(RR, split into 4 registers) */
+
+#define IRQ_STATUS1_READY					((uint8_t)(0x01)) /*!< IRQ: READY state in steady condition*/
+#define IRQ_STATUS1_STANDBY_DELAYED				((uint8_t)(0x02)) /*!< IRQ: STANDBY state after MCU_CK_CONF_CLOCK_TAIL_X clock cycles */
+#define IRQ_STATUS1_LOW_BATT_LVL				((uint8_t)(0x04)) /*!< IRQ: Battery level below threshold*/
+#define IRQ_STATUS1_POR						((uint8_t)(0x08)) /*!< IRQ: Power On Reset */
+#define IRQ_STATUS1_BOR						((uint8_t)(0x10)) /*!< IRQ: Brown out event (both accurate and inaccurate)*/
+#define IRQ_STATUS1_LOCK					((uint8_t)(0x20)) /*!< IRQ: LOCK state in steady condition */
+#define IRQ_STATUS1_PM_COUNT_EXPIRED				((uint8_t)(0x40)) /*!< IRQ: Power Management startup timer expiration (see reg PM_START_COUNTER, 0xB5) */
+#define IRQ_STATUS1_XO_COUNT_EXPIRED				((uint8_t)(0x80)) /*!< IRQ: Crystal oscillator settling time counter expired */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_STATUS2_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_STATUS2  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_STATUS2:  IRQ status, if the correspondent bit is set and IRQ has been generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            16  |       READY state in steady condition14
+ *            17  |       STANDBY state switching in progress
+ *            18  |       Low battery level
+ *            19  |       Power-On reset
+ *            20  |       Brown-Out event
+ *            21  |       LOCK state in steady condition
+ *            22  |       PM start-up timer expiration
+ *            23  |       XO settling timeout
+ *   \endcode
+ */
+
+#define IRQ_STATUS2_BASE					((uint8_t)0xFB) /*!< IRQ Events(RR, split into 4 registers) */
+
+#define IRQ_STATUS2_TX_FIFO_ALMOST_EMPTY			((uint8_t)0x01) /*!< IRQ: TX FIFO almost empty */
+#define IRQ_STATUS2_RX_FIFO_ALMOST_FULL				((uint8_t)0x02) /*!< IRQ: RX FIFO almost full */
+#define IRQ_STATUS2_RX_FIFO_ALMOST_EMPTY			((uint8_t)0x04) /*!< IRQ: RX FIFO almost empty */
+#define IRQ_STATUS2_MAX_BO_CCA_REACH				((uint8_t)0x08) /*!< IRQ: Max number of back-off during CCA */
+#define IRQ_STATUS2_VALID_PREAMBLE				((uint8_t)0x10) /*!< IRQ: Valid preamble detected */
+#define IRQ_STATUS2_VALID_SYNC					((uint8_t)0x20) /*!< IRQ: Sync word detected */
+#define IRQ_STATUS2_RSSI_ABOVE_TH				((uint8_t)(0x40)) /*!< IRQ: RSSI above threshold */
+#define IRQ_STATUS2_WKUP_TOUT_LDC				((uint8_t)(0x80)) /*!< IRQ: Wake-up timeout in LDC mode */
+
+/**
+ * @}
+ */
+
+/** @defgroup IRQ_STATUS3_Register
+ * @{
+ */
+
+/**
+ *  \brief IRQ_STATUS3  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read Write
+ *
+ *   7:0   INT_STATUS3:  IRQ status, if the correspondent bit is set and IRQ has been generated (according to the next table)
+ *
+ *            Bit |     Events Group Interrupt Event
+ *           -------------------------------------------------------
+ *            24  |       SYNTH locking timeout
+ *            25  |       SYNTH calibration start-up time
+ *            26  |       SYNTH calibration timeout
+ *            27  |       TX circuitry start-up time
+ *            28  |       RX circuitry start-up time
+ *            29  |       RX operation timeout
+ *            30  |       Others AES End–of –Operation
+ *            31  |       Reserved
+ *    \endcode
+ */
+#define IRQ_STATUS3_BASE					((uint8_t)0xFA) /*!< IRQ Events(RR, split into 4 registers) */
+
+#define IRQ_STATUS3_RX_DATA_READY				((uint8_t)0x01) /*!< IRQ: RX data ready */
+#define IRQ_STATUS3_RX_DATA_DISC				((uint8_t)0x02) /*!< IRQ: RX data discarded (upon filtering) */
+#define IRQ_STATUS3_TX_DATA_SENT				((uint8_t)0x04) /*!< IRQ: TX data sent */
+#define IRQ_STATUS3_MAX_RE_TX_REACH				((uint8_t)0x08) /*!< IRQ: Max re-TX reached */
+#define IRQ_STATUS3_CRC_ERROR					((uint8_t)0x10) /*!< IRQ: CRC error */
+#define IRQ_STATUS3_TX_FIFO_ERROR				((uint8_t)0x20) /*!< IRQ: TX FIFO underflow/overflow error */
+#define IRQ_STATUS3_RX_FIFO_ERROR				((uint8_t)0x40) /*!< IRQ: RX FIFO underflow/overflow error */
+#define IRQ_STATUS3_TX_FIFO_ALMOST_FULL				((uint8_t)0x80) /*!< IRQ: TX FIFO almost full */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MC_STATE_Registers
+ * @{
+ */
+
+/** @defgroup MC_STATE1_Register
+ * @{
+ */
+
+/**
+ *  \brief MC_STATE1  registers
+ *  \code
+ *   Default value: 0x50
+ *   Read
+ *
+ *   7:4     Reserved.
+ *
+ *   3       ANT_SELECT:  Currently selected antenna
+ *
+ *   2       TX_FIFO_Full:     1 - TX FIFO is full
+ *
+ *   1       RX_FIFO_Empty:    1 - RX FIFO is empty
+ *
+ *   0       ERROR_LOCK:       1 - RCO calibrator error
+ *   \endcode
+ */
+#define	MC_STATE1_BASE						((uint8_t)(0xC0)) /*!< MC_STATE1 register address (see the SpiritStatus struct */
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MC_STATE0_Register
+ * @{
+ */
+
+/**
+ *  \brief MC_STATE0  registers
+ *  \code
+ *   Default value: 0x00
+ *   Read
+ *
+ *   7:1     STATE[6:0]: Current MC state.
+ *
+ *      REGISTER VALUE |         STATE
+ *   --------------------------------------------
+ *            0x40     |         STANDBY
+ *            0x36     |         SLEEP
+ *            0x03     |         READY
+ *            0x3B     |         PM setup
+ *            0x23     |         XO settling
+ *            0x53     |         SYNTH setup
+ *            0x1F     |         PROTOCOL
+ *            0x4F     |         SYNTH calibration
+ *            0x0F     |         LOCK
+ *            0x33     |         RX
+ *            0x5F     |         TX
+ *
+ *   0       XO_ON:       1 - XO is operating
+ *   \endcode
+ */
+#define	MC_STATE0_BASE						((uint8_t)(0xC1)) /*!< MC_STATE0 register address. In this version ALL existing states have been inserted
+                                                                                       and are still to be verified */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+   
+/** @defgroup Engineering-Test_Registers
+ * @{
+ */
+
+#define	SYNTH_CONFIG1_BASE					((uint8_t)(0x9E)) /*!< Synthesizier registers: M, A, K data sync on positive/negative clock edges [4],
+                                                                                       Enable Linearization of the charge pump [3], split time 1.75/3.45ns [2], VCO calibration window 16,32,64,128 clock cycles [1:0]*/
+#define	SYNTH_CONFIG0_BASE					((uint8_t)(0x9F)) /*!< Enable DSM randomizer [7], Window width 1.2-7.5ns (Down-up) of lock detector*/
+#define	VCOTH_BASE						((uint8_t)(0xA0)) /*!< Controls the threshold frequency between VCO low and VCO high [7:0]
+                                                                                       VCOth frequency=2*fXO*(96+VCO_TH/16), fmin=4992 MHz, fmax=5820 MHz*/
+#define	PM_CONFIG2_BASE						((uint8_t)(0xA4)) /*!< Enables high current buffer on Temperature sensor, sets SMPS options */
+#define	PM_CONFIG1_BASE						((uint8_t)(0xA5)) /*!< Set SMPS options */
+#define	PM_CONFIG0_BASE						((uint8_t)(0xA6)) /*!< Set SMPS options */
+#define	VCO_CONFIG_BASE						((uint8_t)(0xA1)) /*!< Set VCO current [5:2]part and [1:0] part */
+#define	XO_CONFIG_BASE						((uint8_t)(0xA7)) /*!< Clock management options from XO to digital part */
+
+#define	XO_RCO_TEST_BASE					((uint8_t)(0xB4)) /*!< Test of XO and RCO */
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup Commands
+ * @{
+ */
+
+#define	COMMAND_TX						((uint8_t)(0x60)) /*!< Start to transmit; valid only from READY */
+#define	COMMAND_RX						((uint8_t)(0x61)) /*!< Start to receive; valid only from READY */
+#define	COMMAND_READY					        ((uint8_t)(0x62)) /*!< Go to READY; valid only from STANDBY or SLEEP or LOCK */
+#define	COMMAND_STANDBY					        ((uint8_t)(0x63)) /*!< Go to STANDBY; valid only from READY */
+#define	COMMAND_SLEEP					        ((uint8_t)(0x64)) /*!< Go to SLEEP; valid only from READY */
+#define	COMMAND_LOCKRX					        ((uint8_t)(0x65)) /*!< Go to LOCK state by using the RX configuration of the synth; valid only from READY */
+#define	COMMAND_LOCKTX					        ((uint8_t)(0x66)) /*!< Go to LOCK state by using the TX configuration of the synth; valid only from READY */
+#define	COMMAND_SABORT					        ((uint8_t)(0x67)) /*!< Force exit form TX or RX states and go to READY state; valid only from TX or RX */
+#define	COMMAND_LDC_RELOAD				        ((uint8_t)(0x68)) /*!< LDC Mode: Reload the LDC timer with the value stored in the  LDC_PRESCALER / COUNTER
+                                                                                       registers; valid from all states  */
+#define	COMMAND_SEQUENCE_UPDATE			                ((uint8_t)(0x69)) /*!< Autoretransmission: Reload the Packet sequence counter with the value stored in the PROTOCOL[2] register
+                                                                                       valid from all states */
+#define	COMMAND_AES_ENC					        ((uint8_t)(0x6A)) /*!< AES: Start the encryption routine; valid from all states; valid from all states */
+#define	COMMAND_AES_KEY					        ((uint8_t)(0x6B)) /*!< AES: Start the procedure to compute the key for the decryption; valid from all states */
+#define	COMMAND_AES_DEC					        ((uint8_t)(0x6C)) /*!< AES: Start the decryption routine using the current key; valid from all states */
+#define	COMMAND_AES_KEY_DEC				        ((uint8_t)(0x6D)) /*!< AES: Compute the key and start the decryption; valid from all states */
+#define	COMMAND_SRES					        ((uint8_t)(0x70)) /*!< Reset of all digital part, except SPI registers */
+#define	COMMAND_FLUSHRXFIFO				        ((uint8_t)(0x71)) /*!< Clean the RX FIFO; valid from all states */
+#define	COMMAND_FLUSHTXFIFO				        ((uint8_t)(0x72)) /*!< Clean the TX FIFO; valid from all states */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Timer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Timer.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,239 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Timer.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT timers.
+ * @details
+ *
+ * This module provides API to configure the Spirit timing mechanisms.
+ * They allow the user to set the timer registers using raw values or
+ * compute them since the desired timer value is expressed in ms.
+ * Moreover the management of the Spirit LDCR mode can be done using
+ * these API.
+ *
+ * <b>Example:</b>
+ * @code
+ *   ...
+ *
+ *   SpiritTimerSetRxTimeoutMs(50.0);
+ *   SpiritTimerSetWakeUpTimerMs(150.0);
+ *
+ *   // IRQ configuration for RX_TIMEOUT and WAKEUP_TIMEOUT
+ *   ...
+ *
+ *   SpiritTimerLdcrMode(S_ENABLE);
+ *
+ *   ...
+ *
+ * @endcode
+ *
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT1_TIMER_H
+#define __SPIRIT1_TIMER_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "SPIRIT_Regs.h"
+#include "SPIRIT_Types.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Timer               Timer
+ * @brief Configuration and management of SPIRIT Timers.
+ * @details See the file <i>@ref SPIRIT_Timer.h</i> for more details.
+ * @{
+ */
+
+
+/**
+ * @defgroup Timer_Exported_Types       Timer Exported Types
+ * @{
+ */
+
+/**
+ * @brief  All the possible RX timeout stop conditions enumeration.
+ */
+typedef enum{
+
+     NO_TIMEOUT_STOP = 0x00,                /*!< Timeout never stopped */
+     TIMEOUT_ALWAYS_STOPPED = 0x08,         /*!< Timeout always stopped (default) */
+     RSSI_ABOVE_THRESHOLD = 0x04,           /*!< Timeout stopped on RSSI above threshold */
+     SQI_ABOVE_THRESHOLD = 0x02,            /*!< Timeout stopped on SQI above threshold */
+     PQI_ABOVE_THRESHOLD = 0x01,            /*!< Timeout stopped on PQI above threshold */
+     RSSI_AND_SQI_ABOVE_THRESHOLD = 0x06,   /*!< Timeout stopped on both RSSI and SQI above threshold */
+     RSSI_AND_PQI_ABOVE_THRESHOLD = 0x05,   /*!< Timeout stopped on both RSSI and PQI above threshold */
+     SQI_AND_PQI_ABOVE_THRESHOLD = 0x03,    /*!< Timeout stopped on both SQI and PQI above threshold */
+     ALL_ABOVE_THRESHOLD = 0x07,            /*!< Timeout stopped only if RSSI, SQI and PQI are above threshold */
+     RSSI_OR_SQI_ABOVE_THRESHOLD = 0x0E,    /*!< Timeout stopped if one between RSSI or SQI are above threshold */
+     RSSI_OR_PQI_ABOVE_THRESHOLD = 0x0D,    /*!< Timeout stopped if one between RSSI or PQI are above threshold */
+     SQI_OR_PQI_ABOVE_THRESHOLD = 0x0B,     /*!< Timeout stopped if one between SQI or PQI are above threshold */
+     ANY_ABOVE_THRESHOLD = 0x0F             /*!< Timeout stopped if one among RSSI, SQI or SQI are above threshold */
+
+} RxTimeoutStopCondition;
+
+
+#define IS_RX_TIMEOUT_STOP_CONDITION(COND)  ( COND == NO_TIMEOUT_STOP || \
+                                                COND == TIMEOUT_ALWAYS_STOPPED || \
+                                                COND == RSSI_ABOVE_THRESHOLD || \
+                                                COND == SQI_ABOVE_THRESHOLD || \
+                                                COND == PQI_ABOVE_THRESHOLD || \
+                                                COND == RSSI_AND_SQI_ABOVE_THRESHOLD || \
+                                                COND == RSSI_AND_PQI_ABOVE_THRESHOLD || \
+                                                COND == SQI_AND_PQI_ABOVE_THRESHOLD || \
+                                                COND == ALL_ABOVE_THRESHOLD || \
+                                                COND == RSSI_OR_SQI_ABOVE_THRESHOLD || \
+                                                COND == RSSI_OR_PQI_ABOVE_THRESHOLD || \
+                                                COND == SQI_OR_PQI_ABOVE_THRESHOLD || \
+                                                COND == ANY_ABOVE_THRESHOLD )
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Timer_Exported_Constants   Timer Exported Constants
+ * @{
+ */
+
+/**
+ * @brief  It represents the Time Step for RX_Timeout timer in case of 24 MHz Crystal, expressed in us.
+ *         It is equal to 1210/(24*10^6). With this time step it is possible to fix the RX_Timeout to
+ *         a minimum value of 50.417us to a maximum value of about 3.278 s.
+ *         Remember that it is possible to have infinite RX_Timeout writing 0 in the RX_Timeout_Counter and/or RX_Timeout_Prescaler registers.
+ */
+#define      RX_TCLK_24MHz           50.417f
+#define      IS_RX_TIMEOUT_24MHz(TIMEOUT)        (TIMEOUT*1000)>=RX_TCLK_24MHz
+
+/**
+ * @brief  It represents the Time Step for RX_Timeout timer in case of 26 MHz Crystal, expressed in us.
+ *         It is equal to 1210/(26*10^6). With this time step it is possible to fix the RX_Timeout to
+ *         a minimum value of 46.538us to a maximum value of about 3.026 s.
+ *         Remember that it is possible to have infinite RX_Timeout writing 0 in the RX_Timeout_Counter register.
+ */
+#define      RX_TCLK_26MHz           46.538f
+#define      IS_RX_TIMEOUT_26MHz(TIMEOUT)        (TIMEOUT*1000)>=RX_TCLK_26MHz
+
+/**
+ * @brief  It represents the Time Step for RX_Wakeup timer expressed in us. This timer is based on RCO (about 34.7 kHZ).
+ *         With this time step it is possible to fix the Wakeup_Timeout to a minimum value of 28.818us to a maximum
+ *         value of about 1.888 s.
+ */
+#define      WAKEUP_TCLK            28.818f
+#define      IS_WKUP_TIMEOUT(TIMEOUT)        (TIMEOUT*1000)>=WAKEUP_TCLK
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Timer_Exported_Macros              Timer Exported Macros
+ * @{
+ */
+
+#define SET_INFINITE_RX_TIMEOUT()     SpiritTimerSetRxTimeoutCounter(0)
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Timer_Exported_Functions           Timer Exported Functions
+ * @{
+ */
+
+void SpiritTimerLdcrMode(SpiritFunctionalState xNewState);
+void SpiritTimerLdcrAutoReload(SpiritFunctionalState xNewState);
+SpiritFunctionalState SpiritTimerLdcrGetAutoReload(void);
+void SpiritTimerSetRxTimeout(uint8_t cCounter , uint8_t cPrescaler);
+void SpiritTimerSetRxTimeoutMs(float fDesiredMsec);
+void SpiritTimerSetRxTimeoutCounter(uint8_t cCounter);
+void SpiritTimerSetRxTimeoutPrescaler(uint8_t cPrescaler);
+void SpiritTimerGetRxTimeout(float* pfTimeoutMsec, uint8_t* pcCounter , uint8_t* pcPrescaler);
+void SpiritTimerSetWakeUpTimer(uint8_t cCounter , uint8_t cPrescaler);
+void SpiritTimerSetWakeUpTimerMs(float fDesiredMsec);
+void SpiritTimerSetWakeUpTimerCounter(uint8_t cCounter);
+void SpiritTimerSetWakeUpTimerPrescaler(uint8_t cPrescaler);
+void SpiritTimerSetWakeUpTimerReloadMs(float fDesiredMsec);
+void SpiritTimerGetWakeUpTimer(float* pfWakeUpMsec, uint8_t* pcCounter , uint8_t* pcPrescaler);
+void SpiritTimerSetWakeUpTimerReload(uint8_t cCounter , uint8_t cPrescaler);
+void SpiritTimerSetWakeUpTimerReloadCounter(uint8_t cCounter);
+void SpiritTimerSetWakeUpTimerReloadPrescaler(uint8_t cPrescaler);
+void SpiritTimerGetWakeUpTimerReload(float* pfWakeUpReloadMsec, uint8_t* pcCounter , uint8_t* pcPrescaler);
+void SpiritTimerComputeWakeUpValues(float fDesiredMsec , uint8_t* pcCounter , uint8_t* pcPrescaler);
+void SpiritTimerComputeRxTimeoutValues(float fDesiredMsec , uint8_t* pcCounter , uint8_t* pcPrescaler);
+void SpiritTimerSetRxTimeoutStopCondition(RxTimeoutStopCondition xStopCondition);
+void SpiritTimerReloadStrobe(void);
+uint16_t SpiritTimerGetRcoFrequency(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Types.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Inc/SPIRIT_Types.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,276 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Types.h
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Header file for SPIRIT types.
+ * @details
+ *
+ * This module provide some types definitions which will be used in
+ * all the modules of this library. Here is defined also the global
+ * variable @ref g_xStatus which contains the status of Spirit and
+ * is updated every time an SPI transaction occurs.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (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 __SPIRIT_GENERICTYPES_H
+#define __SPIRIT_GENERICTYPES_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+/* Include all integer types definitions */
+#include <stdint.h>
+#include <stdio.h>
+#include "SPIRIT_Regs.h"
+
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @defgroup SPIRIT_Types       Types
+ * @brief Module for SPIRIT types definition.
+ * * @details See the file <i>@ref SPIRIT_Types.h</i> for more details.
+ * @{
+ */
+
+/**
+ * @defgroup Types_Exported_Types       Types Exported Types
+ * @{
+ */
+
+/**
+ * @brief  Spirit Functional state. Used to enable or disable a specific option.
+ */
+typedef enum
+{
+  S_DISABLE = 0,
+  S_ENABLE = !S_DISABLE
+
+} SpiritFunctionalState;
+
+#define IS_SPIRIT_FUNCTIONAL_STATE(STATE)   (STATE == S_DISABLE || STATE == S_ENABLE)
+
+/**
+ * @brief  Spirit Flag status. Used to control the state of a flag.
+ */
+typedef enum
+{
+  S_RESET = 0,
+  S_SET = !S_RESET
+
+} SpiritFlagStatus;
+
+#define IS_SPIRIT_FLAG_STATUS(STATUS)   (STATUS == S_RESET || STATUS == S_SET)
+
+
+/**
+ * @brief  boolean type enumeration.
+ */
+typedef enum
+{
+  S_FALSE = 0,
+  S_TRUE  = !S_FALSE
+
+} SpiritBool;
+
+
+/**
+ * @brief  SPIRIT States enumeration.
+ */
+typedef enum
+{
+  MC_STATE_STANDBY           =0x40,	/*!< STANDBY */
+  MC_STATE_SLEEP             =0x36,	/*!< SLEEP */
+  MC_STATE_READY             =0x03,	/*!< READY */
+  MC_STATE_PM_SETUP          =0x3D,	/*!< PM_SETUP */
+  MC_STATE_XO_SETTLING       =0x23,	/*!< XO_SETTLING */
+  MC_STATE_SYNTH_SETUP       =0x53,	/*!< SYNT_SETUP */
+  MC_STATE_PROTOCOL          =0x1F,	/*!< PROTOCOL */
+  MC_STATE_SYNTH_CALIBRATION =0x4F,	/*!< SYNTH */
+  MC_STATE_LOCK              =0x0F,	/*!< LOCK */
+  MC_STATE_RX                =0x33,	/*!< RX */
+  MC_STATE_TX                =0x5F	/*!< TX */
+
+} SpiritState;
+
+
+
+/**
+ * @brief SPIRIT Status. This definition represents the single field of the SPIRIT
+ *        status returned on each SPI transaction, equal also to the MC_STATE registers.
+ *        This field-oriented structure allows user to address in simple way the single
+ *        field of the SPIRIT status.
+ *        The user shall define a variable of SpiritStatus type to access on SPIRIT status fields.
+ * @note  The fields order in the structure depends on used endianness (little or big
+ *        endian). The actual definition is valid ONLY for LITTLE ENDIAN mode. Be sure to
+ *        change opportunely the fields order when use a different endianness.
+ */
+
+typedef struct
+{
+  uint8_t XO_ON:1;		/*!< This one bit field notifies if XO is operating
+  	  	  	  	     (XO_ON is 1) or not (XO_On is 0) */
+  SpiritState MC_STATE: 7;	/*!< This 7 bits field indicates the state of the
+   	   	   	   	     Main Controller of SPIRIT. The possible states
+   	   	   	   	     and their corresponding values are defined in
+   	   	   	   	     @ref SpiritState */
+  uint8_t ERROR_LOCK: 1;       /*!< This one bit field notifies if there is an
+   	   	   	   	     error on RCO calibration (ERROR_LOCK is 1) or
+   	   	   	   	     not (ERROR_LOCK is 0) */
+  uint8_t RX_FIFO_EMPTY: 1;    /*!< This one bit field notifies if RX FIFO is empty
+   	   	   	   	     (RX_FIFO_EMPTY is 1) or not (RX_FIFO_EMPTY is 0) */
+  uint8_t TX_FIFO_FULL: 1;	/*!< This one bit field notifies if TX FIFO is full
+  	  	  	  	     (TX_FIFO_FULL is 1) or not (TX_FIFO_FULL is 0) */
+  uint8_t ANT_SELECT: 1;       /*!< This one bit field notifies the currently selected
+   	   	   	   	     antenna */
+  uint8_t : 4;			/*!< This 4 bits field are reserved and equal to 5 */
+
+}SpiritStatus;
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Types_Exported_Constants   Types Exported Constants
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Types_Exported_Variables   Types Exported Variables
+ * @{
+ */
+
+extern volatile SpiritStatus g_xStatus;
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Types_Exported_Macros              Types Exported Macros
+ * @{
+ */
+
+#ifdef  SPIRIT_USE_FULL_ASSERT
+ /**
+   * @brief  The s_assert_param macro is used for function's parameters check.
+   * @param  expr If expr is false, it calls assert_failed function which reports
+   *         the name of the source file and the source line number of the call
+   *         that failed. If expr is true, it returns no value.
+   * @retval None
+   */
+  #define s_assert_param(expr) ((expr) ? (void)0 : s_assert_failed((uint8_t *)__FILE__, __LINE__))
+  void s_assert_failed(uint8_t* file, uint32_t line);
+#elif  SPIRIT_USE_VCOM_ASSERT
+  /**
+   * @brief  The s_assert_param macro is used for function's parameters check.
+   * @param  expr  If expr is false, it calls assert_failed function which reports
+   *         the name of the source file and the source line number of the call
+   *         that failed. If expr is true, it returns no value.
+   * @retval None
+   */
+  #define s_assert_param(expr) ((expr) ? (void)0 : s_assert_failed((uint8_t *)__FILE__, __LINE__,#expr))
+  void s_assert_failed(uint8_t* file, uint32_t line, char* expression);
+
+#elif SPIRIT_USE_FRAME_ASSERT
+   /**
+   * @brief  The s_assert_param macro is used for function's parameters check.
+   * @param  expr  If expr is false, it calls assert_failed function which reports
+   *         the name of the source file and the source line number of the call
+   *         that failed. If expr is true, it returns no value.
+   * @retval None
+   */
+#define s_assert_param(expr) ((expr) ? (void)0 : s_assert_failed(#expr))
+  void s_assert_failed(char* expression);
+#else
+#define s_assert_param(expr)        {}
+#endif
+
+/**
+ * @brief  Returns the absolute value.
+ */
+#define S_ABS(a) ((a)>0?(a):-(a))
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Types_Exported_Functions   Types Exported Functions
+ * @{
+ */
+
+void SpiritRefreshStatus(void);
+
+/**
+ *@}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Aes.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Aes.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,319 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Aes.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT AES Engine.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Aes.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Aes
+ * @{
+ */
+
+
+/**
+ * @defgroup Aes_Private_TypesDefinitions       AES Private Types Definitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Private_Defines                AES Private Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Private_Macros                 AES Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Private_Variables              AES Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Private_FunctionPrototypes     AES Private Function Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Aes_Private_Functions              AES Private Functions
+ * @{
+ */
+
+
+/**
+ * @brief  Enables or Disables the AES engine.
+ * @param  xNewState new state for AES engine.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None
+ */
+void SpiritAesMode(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Modifies the register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AES_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~AES_MASK;
+  }
+
+  /* Writes the ANA_FUNC_CONF0 register to enable or disable the AES engine */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Writes the data to encrypt or decrypt, or the encryption key for the 
+ *         derive decryption key operation into the AES_DATA_IN registers.
+ * @param  pcBufferDataIn pointer to the user data buffer. The first byte of the array
+ * 	   shall be the MSB byte and it will be put in the AES_DATA_IN[0] register, while
+ * 	   the last one shall be the LSB and it will be put in the AES_DATA_IN[cDataLength-1]
+ * 	   register. If data to write are less than 16 bytes the remaining AES_DATA_IN registers
+ * 	   will be filled with bytes equal to 0. This parameter is an uint8_t*.
+ * @param  cDataLength length of data in bytes.
+ *         This parameter is an uint8_t.
+ * @retval None
+ */
+void SpiritAesWriteDataIn(uint8_t* pcBufferDataIn, uint8_t cDataLength)
+{
+  uint8_t i, dataInArray[16];
+
+  /* Verifies that there are no more than 16 bytes */
+  (cDataLength>16) ? (cDataLength=16) : cDataLength;
+
+  /* Fill the dataInArray with the data buffer, using padding */
+  for(i=0;i<16;i++)
+  {
+    (i<(16 - cDataLength)) ? (dataInArray[i]=0):(dataInArray[i]=pcBufferDataIn[15-i]);
+
+  }
+
+  /* Writes the AES_DATA_IN registers */
+  g_xStatus = SpiritSpiWriteRegisters(AES_DATA_IN_15_BASE, 16, dataInArray);
+
+}
+
+
+/**
+ * @brief  Returns the encrypted or decrypted data or the decription key from the AES_DATA_OUT register.
+ * @param  pcBufferDataOut pointer to the user data buffer. The AES_DATA_OUT[0]
+ *         register value will be put as first element of the buffer (MSB), while the
+ *         AES_DAT_OUT[cDataLength-1] register value will be put as last element of the buffer (LSB).
+ * 	   This parameter is a uint8_t*.
+ * @param  cDataLength length of data to read in bytes.
+ *         This parameter is a uint8_t.
+ * @retval None
+ */
+void SpiritAesReadDataOut(uint8_t* pcBufferDataOut, uint8_t cDataLength)
+{
+  uint8_t address, dataOutArray[16];
+
+  /* Verifies that there are no more than 16 bytes */
+  (cDataLength>16) ? (cDataLength=16) : cDataLength;
+
+  /* Evaluates the address of AES_DATA_OUT from which start to read */
+  address = AES_DATA_OUT_15_BASE+16-cDataLength;
+
+  /* Reads the exact number of AES_DATA_OUT registers */
+  g_xStatus = (SpiritSpiReadRegisters(address, cDataLength, dataOutArray));
+
+  /* Copy in the user buffer the read values changing the order */
+  for(int i = (cDataLength-1); i>=0; i--)
+  {
+    *pcBufferDataOut = dataOutArray[i];
+    pcBufferDataOut++;
+  }
+
+}
+
+
+/**
+ * @brief  Writes the encryption key into the AES_KEY_IN register.
+ * @param  pcKey pointer to the buffer of 4 words containing the AES key.
+ *         The first byte of the buffer shall be the most significant byte AES_KEY_0 of the AES key.
+ *         The last byte of the buffer shall be the less significant byte AES_KEY_15 of the AES key.
+ * 	   This parameter is an uint8_t*.
+ * @retval None
+ */
+void SpiritAesWriteKey(uint8_t* pcKey)
+{
+  uint8_t pcTempKey[16]; 
+  for (uint8_t i = 0; i < 16; i++)
+  {
+    pcTempKey[15-i] = pcKey[i];
+  }
+  
+  /* Writes the AES_DATA_IN registers */
+  g_xStatus = SpiritSpiWriteRegisters(AES_KEY_IN_15_BASE, 16, pcTempKey);
+
+}
+
+/**
+ * @brief  Returns the encryption/decryption key from the AES_KEY_IN register.
+ * @param  pcKey  pointer to the buffer of 4 words (16 bytes) containing the AES key.
+ *         The first byte of the buffer shall be the most significant byte AES_KEY_0 of the AES key.
+ *         The last byte of the buffer shall be the less significant byte AES_KEY_15 of the AES key.
+ *         This parameter is an uint8_t*.
+ * @retval None
+ */
+void SpiritAesReadKey(uint8_t* pcKey)
+{
+  uint8_t pcTempKey[16];
+
+  /* Reads the AES_DATA_IN registers */
+  g_xStatus = SpiritSpiReadRegisters(AES_KEY_IN_15_BASE, 16, pcTempKey);
+
+
+  for (uint8_t i = 0; i < 16; i++)
+    pcKey[i] = pcTempKey[15-i];
+
+}
+
+
+
+/**
+ * @brief  Derives the decryption key from a given encryption key.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritAesDeriveDecKeyFromEnc(void)
+{
+  /* Sends the COMMAND_AES_KEY command */
+  g_xStatus = SpiritSpiCommandStrobes(COMMAND_AES_KEY);
+
+}
+
+
+/**
+ * @brief  Executes the encryption operation.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritAesExecuteEncryption(void)
+{
+  /* Sends the COMMAND_AES_ENC command */
+  g_xStatus = SpiritSpiCommandStrobes(COMMAND_AES_ENC);
+
+}
+
+
+/**
+ * @brief  Executes the decryption operation.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritAesExecuteDecryption(void)
+{
+  /* Sends the COMMAND_AES_DEC command */
+  g_xStatus = SpiritSpiCommandStrobes(COMMAND_AES_DEC);
+
+}
+
+
+/**
+ * @brief  Executes the key derivation and the decryption operation.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritAesDeriveDecKeyExecuteDec(void)
+{
+  /* Sends the COMMAND_AES_KEY_DEC command */
+  g_xStatus = SpiritSpiCommandStrobes(COMMAND_AES_KEY_DEC);
+
+}
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Calibration.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Calibration.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,491 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Calibration.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Configuration and management of SPIRIT VCO-RCO calibration.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Calibration.h"
+#include "MCU_Interface.h"
+
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Calibration
+ * @{
+ */
+
+
+/**
+ * @defgroup Calibration_Private_TypesDefinitions       Calibration Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Calibration_Private_Defines                Calibration Private Defines
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Calibration_Private_Macros                 Calibration Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Calibration_Private_Variables              Calibration Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup Calibration_Private_FunctionPrototypes     Calibration Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Calibration_Private_Functions              Calibration Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Enables or Disables the RCO calibration.
+ * @param  xNewState new state for RCO calibration.
+           This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritCalibrationRco(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  /* Build new value for the register */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL2_RCO_CALIBRATION_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL2_RCO_CALIBRATION_MASK;
+  }
+
+  /* Writes register to enable or disable the RCO calibration */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables or Disables the VCO calibration.
+ * @param  xNewState new state for VCO calibration.
+           This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritCalibrationVco(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+   /* Build new value for the register */
+  if(xNewState==S_ENABLE)
+    tempRegValue |= PROTOCOL2_VCO_CALIBRATION_MASK;
+  else
+    tempRegValue &= ~PROTOCOL2_VCO_CALIBRATION_MASK;
+
+  /* Writes register to enable or disable the VCO calibration */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the RCO calibration words.
+ * @param  cRwt RWT word for RCO calibration.
+ *         This parameter can be a value of uint8_t.
+ * @param  cRfb RFB word for RCO calibration.
+ *         This parameter can be a value of uint8_t.
+ * @retval None.
+ */
+void SpiritCalibrationSetRcoCalWords(uint8_t cRwt, uint8_t cRfb)
+{
+  uint8_t tempRegValue[2];
+
+  /* Build the value of RWT and the MSbits of the RFB word */
+  tempRegValue[0] = (cRwt << 4) | (cRfb >> 1);
+
+  /* Reads the register value to update the LSbit of RFB */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_IN1_BASE, 1, &tempRegValue[1]);
+
+  /* Build new value for the register */
+  tempRegValue[1] = (tempRegValue[1] & 0x7F) | (cRfb<<7);
+
+  /* Writes the new value for RCO calibration words */
+  g_xStatus = SpiritSpiWriteRegisters(RCO_VCO_CALIBR_IN2_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the RCO calibration words.
+ * @param  pcRwt pointer to the variable in which the RWT word has to be stored.
+ *         This parameter is a variable of uint8_t*.
+ * @param  pcRfb pointer to the variable in which the RFB word has to be stored.
+ *         This parameter is a variable of uint8_t*.
+ * @retval None.
+ */
+void SpiritCalibrationGetRcoCalWords(uint8_t* pcRwt, uint8_t* pcRfb)
+{
+  uint8_t tempRegValue[2];
+
+  /* Reads the registers values */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_OUT1_BASE, 2, tempRegValue);
+
+  /* Build the RWT value */
+  (*pcRwt) = tempRegValue[0] >> 4;
+  /* Build the RFB value */
+  (*pcRfb) = (tempRegValue[0] & 0x0F)<<1 | (tempRegValue[1]>>7);
+
+}
+
+
+/**
+ * @brief  Returns the VCO calibration data from internal VCO calibrator.
+ * @param  None.
+ * @retval uint8_t VCO calibration data word.
+ */
+uint8_t SpiritCalibrationGetVcoCalData(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_OUT0_BASE, 1, &tempRegValue);
+
+  /* Build and returns the VCO calibration data value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the VCO calibration data to be used in TX mode.
+ * @param  cVcoCalData calibration data word to be set.
+ *         This parameter is a variable of uint8_t.
+ * @retval None.
+ */
+void SpiritCalibrationSetVcoCalDataTx(uint8_t cVcoCalData)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_IN1_BASE, 1, &tempRegValue);
+
+  /* Build the value to be written */
+  tempRegValue &= 0x80;
+  tempRegValue |= cVcoCalData;
+
+  /* Writes the new value of calibration data in TX */
+  g_xStatus = SpiritSpiWriteRegisters(RCO_VCO_CALIBR_IN1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the actual VCO calibration data used in TX mode.
+ * @param  None.
+ * @retval uint8_t Calibration data word used in TX mode.
+ */
+uint8_t SpiritCalibrationGetVcoCalDataTx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register containing the calibration data word used in TX mode */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_IN1_BASE, 1, &tempRegValue);
+
+  /* Mask the VCO_CALIBR_TX field and returns the value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the VCO calibration data to be used in RX mode.
+ * @param  cVcoCalData calibration data word to be set.
+ *         This parameter is a variable of uint8_t.
+ * @retval None.
+ */
+void SpiritCalibrationSetVcoCalDataRx(uint8_t cVcoCalData)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_IN0_BASE, 1, &tempRegValue);
+
+  /* Build the value to be written */
+  tempRegValue &= 0x80;
+  tempRegValue |= cVcoCalData;
+
+  /* Writes the new value of calibration data in RX */
+  g_xStatus = SpiritSpiWriteRegisters(RCO_VCO_CALIBR_IN0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the actual VCO calibration data used in RX mode.
+ * @param  None.
+ * @retval uint8_t Calibration data word used in RX mode.
+ */
+uint8_t SpiritCalibrationGetVcoCalDataRx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register containing the calibration data word used in TX mode */
+  g_xStatus = SpiritSpiReadRegisters(RCO_VCO_CALIBR_IN0_BASE, 1, &tempRegValue);
+
+  /* Mask the VCO_CALIBR_RX field and returns the value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the VCO calibration window.
+ * @param  xRefWord value of REFWORD corresponding to the Ref_period according to the formula: CALIBRATION_WIN = 11*Ref_period/fxo.
+           This parameter can be a value of @ref VcoWin.
+ * @retval None.
+ */
+void SpiritCalibrationSetVcoWindow(VcoWin xRefWord)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_VCO_WIN(xRefWord));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+
+  /* Build the values to be written */
+  tempRegValue &= 0xFC;
+  tempRegValue |= xRefWord;
+
+  /* Writes the new value of VCO calibration window */
+  g_xStatus = SpiritSpiWriteRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the VCO calibration window.
+ * @param  None.
+ * @retval VcoWin Value of REFWORD corresponding to the Ref_period according to the formula: CALIBRATION_WIN = 11*Ref_period/fxo.
+ *         This parameter can be a value of @ref VcoWin.
+ */
+VcoWin SpiritCalibrationGetVcoWindow(void)
+{
+  uint8_t tempRegValue1, tempRegValue2;
+  VcoWin refWord;
+
+  /* Reads the register containing the REFWORD value */
+  g_xStatus = SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue1);
+
+  /* Reads the Xtal configuration */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue2);
+
+  /* Mask the REFWORD field */
+  tempRegValue1 &= 0x03;
+
+  /* Mask the 24_26_MHz_SELECT field */
+  tempRegValue2 = ((tempRegValue2 & 0x40)>>6);
+
+  /* In case of 26 MHz crystal */
+  if(tempRegValue2)
+  {
+    switch(tempRegValue1)
+    {
+    case 0:
+      refWord = CALIB_TIME_6_77_US_26MHZ;
+      break;
+    case 1:
+      refWord = CALIB_TIME_13_54_US_26MHZ;
+      break;
+    case 2:
+      refWord = CALIB_TIME_27_08_US_26MHZ;
+      break;
+    case 3:
+      refWord = CALIB_TIME_54_15_US_26MHZ;
+      break;
+    }
+  }
+
+  /* In case of 24 MHz crystal */
+  else
+  {
+    switch(tempRegValue1)
+    {
+    case 0:
+      refWord = CALIB_TIME_7_33_US_24MHZ;
+      break;
+    case 1:
+      refWord = CALIB_TIME_14_67_US_24MHZ;
+      break;
+    case 2:
+      refWord = CALIB_TIME_29_33_US_24MHZ;
+      break;
+    case 3:
+      refWord = CALIB_TIME_58_67_US_24MHZ;
+      break;
+    }
+  }
+
+  return refWord;
+
+}
+
+/**
+ * @brief  Selects a VCO.
+ * @param  xVco can be VCO_H or VCO_L according to which VCO select.
+ *         This parameter can be a value of @ref VcoSel.
+ * @retval None.
+ */
+void SpiritCalibrationSelectVco(VcoSel xVco)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_VCO_SEL(xVco));
+  
+  SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+  
+  tempRegValue &= 0xF9;
+  
+  if(xVco == VCO_H)
+  {
+    tempRegValue |= 0x02;
+    
+  }
+  else
+  {
+    tempRegValue |= 0x04;
+  }
+  SpiritSpiWriteRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);  
+  
+}
+
+
+
+/**
+ * @brief  Returns the VCO selected.
+ * @param  void.
+ * @retval VCO_H or VCO_L according to which VCO selected.
+ *         This parameter can be a value of @ref VcoSel.
+ */
+VcoSel SpiritCalibrationGetVcoSelecttion(void)
+{
+  uint8_t tempRegValue;
+  
+  SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+  
+  tempRegValue = (tempRegValue>>1)&0x3;
+  
+  if(tempRegValue == 0x01)
+  {
+    return VCO_H;
+    
+  }
+  else
+  {
+    return VCO_L;
+  }
+  
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Commands.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Commands.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,144 @@
+/**
+  ******************************************************************************
+ * @file    SPIRIT_Commands.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+ * @brief   Management of SPIRIT Commands.
+ *
+  * @attention
+ *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Commands.h"
+#include "MCU_Interface.h"
+
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Commands
+ * @{
+ */
+
+
+/**
+ * @defgroup Commands_Private_TypesDefinitions  Commands Private TypesDefinitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Commands_Private_Defines           Commands Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+/**
+ * @defgroup Commands_Private_Macros            Commands Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Commands_Private_Variables         Commands Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup Commands_Private_FunctionPrototypes        Commands Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Commands_Private_Functions                 Commands Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Sends a specific command to SPIRIT.
+ * @param  xCommandCode code of the command to send.
+           This parameter can be any value of @ref SpiritCmd.
+ * @retval None.
+ */
+void SpiritCmdStrobeCommand(SpiritCmd xCommandCode)
+{
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_CMD(xCommandCode));
+
+  g_xStatus = SpiritSpiCommandStrobes((uint8_t) xCommandCode);
+}
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Csma.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Csma.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,600 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Csma.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT CSMA.
+  * @details
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Csma.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Csma
+ * @{
+ */
+
+
+/**
+ * @defgroup Csma_Private_TypesDefinitions      CSMA Private TypesDefinitions
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Private_Defines               CSMA Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Private_Macros               CSMA Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Private_Variables             CSMA Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup Csma_Private_FunctionPrototypes    CSMA Private FunctionPrototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Csma_Private_Functions             CSMA Private Functions
+ * @{
+ */
+
+
+/**
+ * @brief  Initializes the SPIRIT CSMA according to the specified parameters in the CsmaInit.
+ * @param  pxCsmaInit Csma init structure.
+ *         This parameter is a pointer to @ref CsmaInit.
+ * @retval None.
+ */
+void SpiritCsmaInit(CsmaInit* pxCsmaInit)
+{
+  uint8_t tempRegValue[5];
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxCsmaInit->xCsmaPersistentMode));
+  s_assert_param(IS_CCA_PERIOD(pxCsmaInit->xMultiplierTbit));
+  s_assert_param(IS_CSMA_LENGTH(pxCsmaInit->xCcaLength));
+  s_assert_param(IS_BU_COUNTER_SEED(pxCsmaInit->nBuCounterSeed));
+  s_assert_param(IS_BU_PRESCALER(pxCsmaInit->cBuPrescaler));
+  s_assert_param(IS_CMAX_NB(pxCsmaInit->cMaxNb));
+
+  /* CSMA BU counter seed (MSB) config */
+  tempRegValue[0] = (uint8_t)(pxCsmaInit->nBuCounterSeed >> 8);
+
+  /* CSMA BU counter seed (LSB) config */
+  tempRegValue[1] = (uint8_t) pxCsmaInit->nBuCounterSeed;
+
+  /* CSMA BU prescaler config and CCA period config */
+  tempRegValue[2] = (pxCsmaInit->cBuPrescaler << 2) | pxCsmaInit->xMultiplierTbit;
+
+  /* CSMA CCA length config and max number of back-off */
+  tempRegValue[3] = (pxCsmaInit->xCcaLength | pxCsmaInit->cMaxNb);
+
+  /* Reads the PROTOCOL1_BASE register value, to write the SEED_RELOAD and CSMA_PERS_ON fields */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue[4]);
+
+  /* Writes the new value for persistent mode */
+  if(pxCsmaInit->xCsmaPersistentMode==S_ENABLE)
+  {
+    tempRegValue[4] |= PROTOCOL1_CSMA_PERS_ON_MASK;
+  }
+  else
+  {
+    tempRegValue[4] &= ~PROTOCOL1_CSMA_PERS_ON_MASK;
+  }
+
+  /* Writes PROTOCOL1_BASE register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue[4]);
+
+  /* Writes CSMA_CONFIGx_BASE registers */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG3_BASE, 4, tempRegValue);
+
+}
+
+
+ /**
+  * @brief  Returns the fitted structure CsmaInit starting from the registers values.
+  * @param  pxCsmaInit Csma structure to be fitted.
+  *         This parameter is a pointer to @ref CsmaInit.
+  * @retval None.
+  */
+void SpiritCsmaGetInfo(CsmaInit* pxCsmaInit)
+{
+   uint8_t tempRegValue[5];
+
+   /* Reads PROTOCOL1_BASE register */
+   g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue[4]);
+
+   /* Reads CSMA_CONFIGx_BASE registers */
+   g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG3_BASE, 4, tempRegValue);
+
+   /* Reads the bu counter seed */
+   pxCsmaInit->nBuCounterSeed = (uint16_t)tempRegValue[1] | ((uint16_t)(tempRegValue[0] << 8));
+
+   /* Reads the bu prescaler */
+   pxCsmaInit->cBuPrescaler = tempRegValue[2]>>2;
+
+   /* Reads the Cca period */
+   pxCsmaInit->xMultiplierTbit = (CcaPeriod)(tempRegValue[2] & 0x03);
+
+   /* Reads the Cca length */
+   pxCsmaInit->xCcaLength = (CsmaLength)(tempRegValue[3]&0xF0);
+
+   /* Reads the max number of back off */
+   pxCsmaInit->cMaxNb = tempRegValue[3] & 0x07;
+
+   /* Reads the persistent mode enable bit */
+   pxCsmaInit->xCsmaPersistentMode = (SpiritFunctionalState)((tempRegValue[4]>>1) & 0x01);
+
+}
+
+
+/**
+ * @brief  Enables or Disables the CSMA.
+ * @param  xNewState the state of the CSMA mode.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritCsma(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Sets or resets the CSMA enable bit */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL1_CSMA_ON_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL1_CSMA_ON_MASK;
+  }
+
+  /* Writes the new value on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+/**
+ * @brief  Gets the CSMA mode. Says if it is enabled or disabled.
+ * @param  None.
+ * @retval SpiritFunctionalState: CSMA mode.
+ */
+SpiritFunctionalState SpiritCsmaGetCsma(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Return if set or reset */
+  if(tempRegValue & PROTOCOL1_CSMA_ON_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+/**
+ * @brief  Enables or Disables the persistent CSMA mode.
+ * @param  xNewState the state of the persistent CSMA mode.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritCsmaPersistentMode(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Enables/disables the CSMA persistent mode */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL1_CSMA_PERS_ON_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL1_CSMA_PERS_ON_MASK;
+  }
+
+  /* Writes the new vaue on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Gets the persistent CSMA mode.
+ * @param  None.
+ * @retval SpiritFunctionalState: CSMA persistent mode.
+ */
+SpiritFunctionalState SpiritCsmaGetPersistentMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Return if set or reset */
+  if(tempRegValue & PROTOCOL1_CSMA_PERS_ON_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+
+/**
+ * @brief  Enables or Disables the seed reload mode (if enabled it reloads the back-off generator seed using the value written in the BU_COUNTER_SEED register).
+ * @param  xNewState the state of the seed reload mode.
+ *	   This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritCsmaSeedReloadMode(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Enables/disables the seed reload mode */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL1_SEED_RELOAD_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL1_SEED_RELOAD_MASK;
+  }
+
+  /* Writes the new value on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Gets the seed reload mode.
+ * @param  None.
+ * @retval SpiritFunctionalState: CSMA seed reload mode.
+ */
+SpiritFunctionalState SpiritCsmaGetSeedReloadMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Return if set or reset */
+  if(tempRegValue & PROTOCOL1_SEED_RELOAD_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+}
+
+
+/**
+ * @brief  Sets the BU counter seed (BU_COUNTER_SEED register). The CSMA back off time is given by the formula: BO = rand(2^NB)*BU.
+ * @param  nBuCounterSeed seed of the random number generator used to apply the BBE algorithm.
+ *	   This parameter is an uint16_t.
+ * @retval None.
+ */
+void SpiritCsmaSetBuCounterSeed(uint16_t nBuCounterSeed)
+{
+  uint8_t tempRegValue[2];
+
+  /* Check parameters */
+  s_assert_param(IS_BU_COUNTER_SEED(nBuCounterSeed));
+
+  /* Build value (MSB)*/
+  tempRegValue[0]=(uint8_t)(nBuCounterSeed>>8);
+  /* Build value (LSB) */
+  tempRegValue[1]=(uint8_t)nBuCounterSeed;
+
+  /* Writes the CSMA_CONFIG3 registers */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG3_BASE, 2, tempRegValue);
+
+}
+
+/**
+ * @brief  Returns the BU counter seed (BU_COUNTER_SEED register).
+ * @param  None.
+ * @retval uint16_t Seed of the random number generator used to apply the BBE algorithm.
+ */
+uint16_t SpiritCsmaGetBuCounterSeed(void)
+{
+  uint8_t tempRegValue[2];
+
+  /* Reads the CSMA_CONFIGx registers value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG3_BASE, 2, tempRegValue);
+
+  /* Build the counter seed and return it */
+  return ((uint16_t)tempRegValue[1] + (((uint16_t)tempRegValue[0])<<8));
+
+}
+
+
+/**
+ * @brief  Sets the BU prescaler. The CSMA back off time is given by the formula: BO = rand(2^NB)*BU.
+ * @param  cBuPrescaler used to program the back-off unit BU.
+ * 	   This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritCsmaSetBuPrescaler(uint8_t cBuPrescaler)
+{
+  uint8_t tempRegValue;
+
+  /* Check parameters */
+  s_assert_param(IS_BU_PRESCALER(cBuPrescaler));
+
+  /* Reads the CSMA_CONFIG1 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+  /* Build the new value for the BU prescaler */
+  tempRegValue &= 0x03;
+  tempRegValue |= (cBuPrescaler<<2);
+
+  /* Writes the new value on the CSMA_CONFIG1_BASE register */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the BU prescaler.
+ * @param  None.
+ * @retval uint8_t Value back-off unit (BU).
+ */
+uint8_t SpiritCsmaGetBuPrescaler(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the CSMA_CONFIG1 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+  /* Build and return the BU prescaler value */
+  return (tempRegValue >> 2);
+
+}
+
+
+/**
+ * @brief  Sets the CCA period.
+ * @param  xMultiplierTbit value of CCA period to store.
+ * 	   This parameter can be a value of @ref CcaPeriod.
+ * @retval None.
+ */
+void SpiritCsmaSetCcaPeriod(CcaPeriod xMultiplierTbit)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_CCA_PERIOD(xMultiplierTbit));
+
+  /* Reads the CSMA_CONFIG1 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+  /* Build the new value setting the the CCA period */
+  tempRegValue &= 0xFC;
+  tempRegValue |= xMultiplierTbit;
+
+  /* Writes the new value on the CSMA_CONFIG1 register */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the CCA period.
+ * @param  None.
+ * @retval CcaPeriod CCA period.
+ */
+CcaPeriod SpiritCsmaGetCcaPeriod(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the CSMA_CONFIG1 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG1_BASE, 1, &tempRegValue);
+
+  /* Build and return the CCA period value */
+  return (CcaPeriod)(tempRegValue & 0x03);
+
+}
+
+
+/**
+ * @brief  Sets the CCA length.
+ * @param  xCcaLength the CCA length (a value between 1 and 15 that multiplies the CCA period).
+ *	   This parameter can be any value of @ref CsmaLength.
+ * @retval None.
+ */
+void SpiritCsmaSetCcaLength(CsmaLength xCcaLength)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_CSMA_LENGTH(xCcaLength));
+
+  /* Reads the CSMA_CONFIG0 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+
+  /* Build the value of CCA length to be set */
+  tempRegValue &= 0x0F;
+  tempRegValue |= xCcaLength;
+
+  /* Writes the new value on the CSMA_CONFIG0 register */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the CCA length.
+ * @param  None.
+ * @retval uint8_t CCA length.
+ */
+uint8_t SpiritCsmaGetCcaLength(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the CSMA_CONFIG0 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+
+  /* Build and return the CCA length */
+  return tempRegValue >> 4;
+
+}
+
+
+/**
+ * @brief  Sets the max number of back-off. If reached Spirit stops the transmission.
+ * @param  cMaxNb the max number of back-off.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritCsmaSetMaxNumberBackoff(uint8_t cMaxNb)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_CMAX_NB(cMaxNb));
+
+  /* Reads the CSMA_CONFIG0 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+
+  /* Build the value of max back off to be set */
+  tempRegValue &= 0xF8;
+  tempRegValue |= cMaxNb;
+
+  /* Writes the new value on the CSMA_CONFIG0 register */
+  g_xStatus = SpiritSpiWriteRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+}
+
+/**
+ * @brief  Returns the max number of back-off.
+ * @param  None.
+ * @retval uint8_t Max number of back-off.
+ */
+uint8_t SpiritCsmaGetMaxNumberBackoff(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the CSMA_CONFIG0 register value */
+  g_xStatus = SpiritSpiReadRegisters(CSMA_CONFIG0_BASE, 1, &tempRegValue);
+
+  /* Build and return the max number of back-off */
+  return (tempRegValue & 0x07);
+
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_DirectRF.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_DirectRF.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,215 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_DirectRF.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT direct transmission / receive modes.
+  * @details
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_DirectRF.h"
+#include "MCU_Interface.h"
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_DirectRf
+ * @{
+ */
+
+
+/**
+ * @defgroup DirectRf_Private_TypesDefinitions          Direct RF Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Private_Defines                   Direct RF Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Private_Macros                    Direct RF Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Private_Variables                 Direct RF Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup DirectRf_Private_FunctionPrototypes        Direct RF Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup DirectRf_Private_Functions                 Direct RF Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Sets the DirectRF RX mode of SPIRIT.
+ * @param  xDirectRx code of the desired mode.
+ *         This parameter can be any value of @ref DirectRx.
+ * @retval None.
+ */
+void SpiritDirectRfSetRxMode(DirectRx xDirectRx)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_DIRECT_RX(xDirectRx));
+
+  /* Reads the register value */
+  SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Build the value to be stored */
+  tempRegValue &= ~PCKTCTRL3_RX_MODE_MASK;
+  tempRegValue |= (uint8_t)xDirectRx;
+
+  /* Writes value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the DirectRF RX mode of SPIRIT.
+ * @param  None.
+ * @retval DirectRx Direct Rx mode.
+ */
+DirectRx SpiritDirectRfGetRxMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value and mask the RX_Mode field */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return value */
+  return (DirectRx)(tempRegValue & 0x30);
+
+}
+
+
+/**
+ * @brief  Sets the TX mode of SPIRIT.
+ * @param  xDirectTx code of the desired source.
+ *         This parameter can be any value of @ref DirectTx.
+ * @retval None.
+ */
+void SpiritDirectRfSetTxMode(DirectTx xDirectTx)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_DIRECT_TX(xDirectTx));
+
+  /* Reads the register value */
+  SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build the value to be stored */
+  tempRegValue &= ~PCKTCTRL1_TX_SOURCE_MASK;
+  tempRegValue |= (uint8_t)xDirectTx;
+
+  /* Writes value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the DirectRF TX mode of SPIRIT.
+ * @param  None.
+ * @retval DirectTx Direct Tx mode.
+ */
+DirectTx SpiritDirectRfGetTxMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value and mask the RX_Mode field */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Returns value */
+  return (DirectTx)(tempRegValue & 0x0C);
+
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_General.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_General.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,449 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_General.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT General functionalities.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_General.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_General
+ * @{
+ */
+
+
+/**
+ * @defgroup General_Private_TypesDefinitions   General Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup General_Private_Defines            General Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup General_Private_Macros             General Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup General_Private_Variables          General Private Variables
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup General_Private_FunctionPrototypes         General Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup General_Private_Functions                          General Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Enables or Disables the output of battery level detector.
+ * @param  xNewState new state for battery level detector.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None
+ */
+void SpiritGeneralBatteryLevel(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the ANA_FUNC_CONF0_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Build the value to be stored */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= BATTERY_LEVEL_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~BATTERY_LEVEL_MASK;
+  }
+
+  /* Writes the new value */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the battery level.
+ * @param  xBatteryLevel new state for battery level.
+ *         This parameter can be a value of @ref BatteryLevel.
+ * @retval None.
+ */
+void SpiritGeneralSetBatteryLevel(BatteryLevel xBatteryLevel)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_BLD_LVL(xBatteryLevel));
+
+  /* Reads the ANA_FUNC_CONF1_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+  /* Build the value to be stored */
+  tempRegValue &= ~ANA_FUNC_CONF1_SET_BLD_LVL_MASK;
+  switch(xBatteryLevel)
+  {
+    case BLD_LVL_2_7_V:
+      tempRegValue |= BLD_LVL_2_7;
+      break;
+    case BLD_LVL_2_5_V:
+      tempRegValue |= BLD_LVL_2_5;
+      break;
+    case BLD_LVL_2_3_V:
+      tempRegValue |= BLD_LVL_2_3;
+      break;
+    case BLD_LVL_2_1_V:
+      tempRegValue |= BLD_LVL_2_1;
+      break;
+  }
+
+  /* Writes the new value */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the settled battery level.
+ * @param  None.
+ * @retval BatteryLevel Settled battery level. This parameter can be a value of @ref BatteryLevel.
+ */
+BatteryLevel SpiritGeneralGetBatteryLevel(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the ANA_FUNC_CONF1_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+  /* Mask the battery level field and returns the settled battery level */
+  return ((BatteryLevel)(tempRegValue & ANA_FUNC_CONF1_SET_BLD_LVL_MASK));
+
+}
+
+
+/**
+ * @brief  Enables or Disables the output of brown out detector.
+ * @param  xNewState new state for brown out detector.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritGeneralBrownOut(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the ANA_FUNC_CONF0_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Build the value to be stored */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= BROWN_OUT_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~BROWN_OUT_MASK;
+  }
+
+  /* Writes value on register */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets High Power Mode.
+ * @param  xNewState new state for High Power Mode.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritGeneralHighPwr(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the ANA_FUNC_CONF0_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Build the value to write */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= HIGH_POWER_MODE_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~HIGH_POWER_MODE_MASK;
+  }
+
+  /* Writes the new value on register */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets External Reference.
+ * @param  xExtMode new state for the external reference.
+ *         This parameter can be: MODE_EXT_XO or MODE_EXT_XIN.
+ * @retval None.
+ */
+void SpiritGeneralSetExtRef(ModeExtRef xExtMode)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_MODE_EXT(xExtMode));
+
+  /* Reads the ANA_FUNC_CONF0_BASE register value */
+  SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Build the value to write */
+  if(xExtMode == MODE_EXT_XO)
+  {
+    tempRegValue &= ~EXT_REF_MASK;
+  }
+  else
+  {
+    tempRegValue |= EXT_REF_MASK;
+  }
+
+  /* Writes value on register */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns External Reference.
+ * @param  None.
+ * @retval ModeExtRef Settled external reference.
+ *         This parameter can be: MODE_EXT_XO or MODE_EXT_XIN.
+ */
+ModeExtRef SpiritGeneralGetExtRef(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the ANA_FUNC_CONF0_BASE register value and return the result */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Mask the EXT_REF field field and returns the settled reference signal */
+  return ((ModeExtRef)((tempRegValue & 0x10)>>4));
+
+}
+
+
+/**
+ * @brief  Sets XO gm at startup.
+ * @param  xGm transconductance value of XO at startup.
+ *         This parameter can be a value of @ref GmConf.
+ * @retval None.
+ */
+void SpiritGeneralSetXoGm(GmConf xGm)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_GM_CONF(xGm));
+
+  /* Reads the ANA_FUNC_CONF1_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+  /* Build the value to write */
+  tempRegValue &= ~ANA_FUNC_CONF1_GMCONF_MASK;
+  switch(xGm)
+  {
+    case GM_SU_13_2:
+      tempRegValue |= GM_13_2;
+      break;
+    case GM_SU_18_2:
+      tempRegValue |= GM_18_2;
+      break;
+    case GM_SU_21_5:
+      tempRegValue |= GM_21_5;
+      break;
+    case GM_SU_25_6:
+      tempRegValue |= GM_25_6;
+      break;
+    case GM_SU_28_8:
+      tempRegValue |= GM_28_8;
+      break;
+    case GM_SU_33_9:
+      tempRegValue |= GM_33_9;
+      break;
+    case GM_SU_38_5:
+      tempRegValue |= GM_38_5;
+      break;
+    case GM_SU_43_0:
+      tempRegValue |= GM_43_0;
+      break;
+  }
+
+  /* Writes new value on register */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the configured XO gm at startup.
+ * @param  None.
+ * @retval GmConf Settled XO gm. This parameter can be a value of @ref GmConf.
+ */
+GmConf SpiritGeneralGetXoGm(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the ANA_FUNC_CONF1_BASE register value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF1_BASE, 1, &tempRegValue);
+
+  /* Mask the GM_CONF field field and returns the settled transconductance of the XO at startup */
+  return ((GmConf)((tempRegValue & 0x1C)>>2));
+
+}
+
+
+/**
+ * @brief  Returns the settled packet format.
+ * @param  None.
+ * @retval PacketType Settled packet type. This parameter can be a value of @ref PacketType.
+ */
+PacketType SpiritGeneralGetPktType(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* cast and return value */
+  return (PacketType)(tempRegValue>>6);
+
+}
+
+
+
+/**
+ * @brief  Returns device part number.
+ * @param  None.
+ * @retval uint16_t Device part number.
+ */
+uint16_t SpiritGeneralGetDevicePartNumber(void)
+{
+  uint8_t tempRegValue[2];
+
+  /* Reads the register value containing the device part number */
+  g_xStatus = SpiritSpiReadRegisters(DEVICE_INFO1_PARTNUM, 2, tempRegValue);
+
+  return ((((uint16_t)tempRegValue[0])<<8) | ((uint16_t)tempRegValue[1]));
+
+}
+
+/**
+ * @brief  Returns SPIRIT RF board version.
+ * @param  None.
+ * @retval SPIRIT RF board version: 0x30 is the only admitted value
+ */
+uint8_t SpiritGeneralGetSpiritVersion(void)
+{
+  uint8_t ver; 
+  SpiritSpiReadRegisters(DEVICE_INFO0_VERSION, 1, &ver);
+  return ver;
+}
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Gpio.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Gpio.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,458 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Gpio.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   This file provides all the low level API to manage SPIRIT GPIO.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Gpio.h"
+#include "MCU_Interface.h"
+
+
+/** @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/** @addtogroup SPIRIT_Gpio
+ * @{
+ */
+
+
+/** @defgroup Gpio_Private_TypesDefinitions     GPIO Private Types Definitions
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup Gpio_Private_Defines              GPIO Private Defines
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Private_Macros               GPIO Private Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Private_Variables            GPIO Private Variables
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Private_FunctionPrototypes   GPIO Private Function Prototypes
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Gpio_Private_Functions            GPIO Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Initializes the SPIRIT GPIOx according to the specified
+ *         parameters in the pxGpioInitStruct.
+ * @param  pxGpioInitStruct pointer to a SGpioInit structure that
+ *         contains the configuration information for the specified SPIRIT GPIO.
+ * @retval None.
+ */
+void SpiritGpioInit(SGpioInit* pxGpioInitStruct)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_GPIO(pxGpioInitStruct->xSpiritGpioPin));
+  s_assert_param(IS_SPIRIT_GPIO_MODE(pxGpioInitStruct->xSpiritGpioMode));
+  s_assert_param(IS_SPIRIT_GPIO_IO(pxGpioInitStruct->xSpiritGpioIO));
+
+  tempRegValue = ((uint8_t)(pxGpioInitStruct->xSpiritGpioMode) | (uint8_t)(pxGpioInitStruct->xSpiritGpioIO));
+
+  g_xStatus = SpiritSpiWriteRegisters(pxGpioInitStruct->xSpiritGpioPin, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables or Disables the output of temperature sensor on SPIRIT GPIO_0.
+ * @param  xNewState new state for temperature sensor.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritGpioTemperatureSensor(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  uint8_t gpio0tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the ANA_FUNC_CONF0 register and mask the result to enable or disable the
+     temperature sensor */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= TEMPERATURE_SENSOR_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~TEMPERATURE_SENSOR_MASK);
+    gpio0tempRegValue = 0x0A; /* Default value */
+  }
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+
+  /* Sets the SPIRIT GPIO_0 according to input request */
+  g_xStatus = SpiritSpiWriteRegisters(GPIO0_CONF_BASE, 1, &gpio0tempRegValue);
+
+}
+
+
+/**
+ * @brief  Forces SPIRIT GPIO_x configured as digital output, to VDD or GND.
+ * @param  xGpioX Specifies the GPIO to be configured.
+ *   This parameter can be one of following parameters:
+ *     @arg SPIRIT_GPIO_0: SPIRIT GPIO_0
+ *     @arg SPIRIT_GPIO_1: SPIRIT GPIO_1
+ *     @arg SPIRIT_GPIO_2: SPIRIT GPIO_2
+ *     @arg SPIRIT_GPIO_3: SPIRIT GPIO_3
+ * @param  xLevel Specifies the level.
+ *   This parameter can be: HIGH or LOW.
+ * @retval None.
+ */
+void SpiritGpioSetLevel(SpiritGpioPin xGpioX, OutputLevel xLevel)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_GPIO(xGpioX));
+  s_assert_param(IS_SPIRIT_GPIO_LEVEL(xLevel));
+
+  /* Reads the SPIRIT_GPIOx register and mask the GPIO_SELECT field */
+  g_xStatus = SpiritSpiReadRegisters(xGpioX, 1, &tempRegValue);
+  tempRegValue &= 0x04;
+
+  /* Sets the value of the SPIRIT GPIO register according to the specified level */
+  if(xLevel == HIGH)
+  {
+    tempRegValue |= (uint8_t)SPIRIT_GPIO_DIG_OUT_VDD | (uint8_t)SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP;
+  }
+  else
+  {
+    tempRegValue |= (uint8_t)SPIRIT_GPIO_DIG_OUT_GND | (uint8_t)SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP;
+  }
+
+  /* Writes the SPIRIT GPIO register */
+  g_xStatus = SpiritSpiWriteRegisters(xGpioX, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns output value (VDD or GND) of SPIRIT GPIO_x, when it is configured as digital output.
+ * @param  xGpioX Specifies the GPIO to be read.
+ *         This parameter can be one of following parameters:
+ *         @arg SPIRIT_GPIO_0: SPIRIT GPIO_0
+ *         @arg SPIRIT_GPIO_1: SPIRIT GPIO_1
+ *         @arg SPIRIT_GPIO_2: SPIRIT GPIO_2
+ *         @arg SPIRIT_GPIO_3: SPIRIT GPIO_3
+ * @retval OutputLevel Logical level of selected GPIO configured as digital output.
+ *         This parameter can be: HIGH or LOW.
+ */
+OutputLevel SpiritGpioGetLevel(SpiritGpioPin xGpioX)
+{
+  uint8_t tempRegValue = 0x00;
+  OutputLevel level;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_GPIO(xGpioX));
+
+  /* Reads the SPIRIT_GPIOx register */
+  g_xStatus = SpiritSpiReadRegisters(xGpioX, 1, &tempRegValue);
+
+  /* Mask the GPIO_SELECT field and returns the value according */
+  tempRegValue &= 0xF8;
+  if(tempRegValue == SPIRIT_GPIO_DIG_OUT_VDD)
+  {
+    level = HIGH;
+  }
+  else
+  {
+    level = LOW;
+  }
+
+  return level;
+
+}
+
+
+/**
+ * @brief  Enables or Disables the MCU clock output.
+ * @param  xNewState new state for the MCU clock output.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritGpioClockOutput(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the MCU_CK_CONF register and mask the result to enable or disable the clock output */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  if(xNewState)
+  {
+    tempRegValue |= MCU_CK_ENABLE;
+  }
+  else
+  {
+    tempRegValue &= (~MCU_CK_ENABLE);
+  }
+
+  /* Writes the MCU_CK_CONF register */
+  g_xStatus = SpiritSpiWriteRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Initializes the SPIRIT Clock Output according to the specified
+ *         parameters in the xClockOutputInitStruct.
+ * @param  pxClockOutputInitStruct pointer to a ClockOutputInit structure that
+ *         contains the configuration information for the SPIRIT Clock Output.
+ * @retval None.
+ * @note   The function SpiritGpioClockOutput() must be called in order to enable
+ *         or disable the MCU clock dividers.
+ */
+void SpiritGpioClockOutputInit(ClockOutputInit* pxClockOutputInitStruct)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_XO(pxClockOutputInitStruct->xClockOutputXOPrescaler));
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_RCO(pxClockOutputInitStruct->xClockOutputRCOPrescaler));
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_EXTRA_CYCLES(pxClockOutputInitStruct->xExtraClockCycles));
+
+  /* Calculates the register value to write according to the specified configuration */
+  tempRegValue = ((uint8_t)(pxClockOutputInitStruct->xClockOutputXOPrescaler) | (uint8_t)(pxClockOutputInitStruct->xClockOutputRCOPrescaler) | \
+           (uint8_t)(pxClockOutputInitStruct->xExtraClockCycles));
+
+  /* Writes the MCU_CLOCK register */
+  g_xStatus = SpiritSpiWriteRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the XO ratio as clock output.
+ * @param  xXOPrescaler the XO prescaler to be used as clock output.
+ *         This parameter can be any value of @ref ClockOutputXOPrescaler .
+ * @retval None
+ */
+void SpiritGpioSetXOPrescaler(ClockOutputXOPrescaler xXOPrescaler)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_XO(xXOPrescaler));
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the XO_RATIO field and writes the new value */
+  tempRegValue &= 0x61;
+  tempRegValue |= ((uint8_t)xXOPrescaler);
+
+  /* Writes the new XO prescaler in the MCU_CLOCK register */
+  g_xStatus = SpiritSpiWriteRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the settled XO prescaler as clock output.
+ * @param  None.
+ * @retval ClockOutputXOPrescaler Settled XO prescaler used for clock
+ *         output. This parameter can be a value of @ref ClockOutputXOPrescaler .
+ */
+ClockOutputXOPrescaler SpiritGpioGetXOPrescaler(void)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the XO_RATIO field and return the value */
+  return ((ClockOutputXOPrescaler)(tempRegValue & 0x1E));
+
+}
+
+
+/**
+ * @brief  Sets the RCO ratio as clock output
+ * @param  xRCOPrescaler the RCO prescaler to be used as clock output.
+ *         This parameter can be any value of @ref ClockOutputRCOPrescaler .
+ * @retval None.
+ */
+void SpiritGpioSetRCOPrescaler(ClockOutputRCOPrescaler xRCOPrescaler)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_RCO(xRCOPrescaler));
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the RCO_RATIO field and writes the new value */
+  tempRegValue &= 0xFE;
+  tempRegValue |= ((uint8_t)xRCOPrescaler);
+
+  /* Writes the new RCO prescaler in the MCU_CLOCK register */
+  g_xStatus = SpiritSpiWriteRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the settled RCO prescaler as clock output.
+ * @param  None.
+ * @retval ClockOutputRCOPrescaler Settled RCO prescaler used for clock
+ *         output. This parameter can be a value of @ref ClockOutputRCOPrescaler.
+ */
+ClockOutputRCOPrescaler SpiritGpioGetRCOPrescaler(void)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the RCO_RATIO field and returns the value */
+  return ((ClockOutputRCOPrescaler)(tempRegValue & 0x01));
+
+}
+
+
+/**
+ * @brief  Sets the RCO ratio as clock output.
+ * @param  xExtraCycles the number of extra clock cycles provided before switching
+ *         to STANDBY state. This parameter can be any value of @ref ExtraClockCycles .
+ * @retval None.
+ */
+void SpiritGpioSetExtraClockCycles(ExtraClockCycles xExtraCycles)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_CLOCK_OUTPUT_EXTRA_CYCLES(xExtraCycles));
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the CLOCK_TAIL field and writes the new value */
+  tempRegValue &= 0x9F;
+  tempRegValue |= ((uint8_t)xExtraCycles);
+
+  /* Writes the new number of extra clock cycles in the MCU_CLOCK register */
+  g_xStatus = SpiritSpiWriteRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the settled RCO prescaler as clock output.
+ * @param  None.
+ * @retval ExtraClockCycles Settled number of extra clock cycles
+ *         provided before switching to STANDBY state. This parameter can be
+ *         any value of @ref ExtraClockCycles .
+ */
+ExtraClockCycles SpiritGpioGetExtraClockCycles(void)
+{
+  uint8_t tempRegValue = 0x00;
+
+  /* Reads the MCU_CLK_CONFIG register */
+  g_xStatus = SpiritSpiReadRegisters(MCU_CK_CONF_BASE, 1, &tempRegValue);
+
+  /* Mask the CLOCK_TAIL field and returns the value */
+  return ((ExtraClockCycles)(tempRegValue & 0x60));
+
+}
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Irq.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Irq.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,320 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Irq.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT IRQs.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Irq.h"
+#include "MCU_Interface.h"
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Irq
+ * @{
+ */
+
+
+/**
+ * @defgroup Irq_Private_TypesDefinitions       IRQ Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Irq_Private_Defines                IRQ Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Irq_Private_Macros                 IRQ Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Irq_Private_Variables              IRQ Private Variables
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Irq_Private_FunctionPrototypes     IRQ Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Irq_Private_Functions              IRQ Private Functions
+ * @{
+ */
+
+
+/**
+ * @brief  De initializate the SpiritIrqs structure setting all the bitfield to 0.
+ *         Moreover, it sets the IRQ mask registers to 0x00000000, disabling all IRQs.
+ * @param  pxIrqInit pointer to a variable of type @ref SpiritIrqs, in which all the
+ *         bitfields will be settled to zero.
+ * @retval None.
+ */
+void SpiritIrqDeInit(SpiritIrqs* pxIrqInit)
+{
+  uint8_t tempRegValue[4]={0x00,0x00,0x00,0x00};
+
+  if(pxIrqInit!=NULL)
+  {
+    /* Sets the bitfields of passed structure to one */
+    *(uint32_t*)pxIrqInit = 0x0;
+  }
+
+  /* Writes the IRQ_MASK registers */
+  g_xStatus = SpiritSpiWriteRegisters(IRQ_MASK3_BASE, 4, tempRegValue);
+}
+
+
+/**
+ * @brief  Enables all the IRQs according to the user defined pxIrqInit structure.
+ * @param  pxIrqInit pointer to a variable of type @ref SpiritIrqs, through which the
+ *         user enable specific IRQs. This parameter is a pointer to a SpiritIrqs.
+ *         For example suppose to enable only the two IRQ Low Battery Level and Tx Data Sent:
+ * @code
+ * SpiritIrqs myIrqInit = {0};
+ * myIrqInit.IRQ_LOW_BATT_LVL = 1;
+ * myIrqInit.IRQ_TX_DATA_SENT = 1;
+ * SpiritIrqInit(&myIrqInit);
+ * @endcode
+ * @retval None.
+ */
+void SpiritIrqInit(SpiritIrqs* pxIrqInit)
+{
+  /* Writes the IRQ_MASK registers */
+  g_xStatus = SpiritSpiWriteRegisters(IRQ_MASK3_BASE, 4, (uint8_t*)pxIrqInit);
+
+}
+
+
+/**
+ * @brief  Enables or disables a specific IRQ.
+ * @param  xIrq IRQ to enable or disable.
+ *         This parameter can be any value of @ref IrqList.
+ * @param  xNewState new state for the IRQ.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritIrq(IrqList xIrq, SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempValue = 0;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_IRQ_LIST(xIrq));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the IRQ_MASK registers */
+  g_xStatus = SpiritSpiReadRegisters(IRQ_MASK3_BASE, 4, tempRegValue);
+
+  /* Build the IRQ mask word */
+  for(uint8_t i=0; i<4; i++)
+  {
+    tempValue += ((uint32_t)tempRegValue[i])<<(8*(3-i));
+  }
+  
+  /* Rebuild the new mask according to user request */
+  if(xNewState == S_DISABLE)
+  {
+    tempValue &= (~xIrq);
+  }
+  else
+  {
+    tempValue |= (xIrq);
+  }
+
+  /* Build the array of bytes to write in the IRQ_MASK registers */
+  for(uint8_t j=0; j<4; j++)
+  {
+    tempRegValue[j] = (uint8_t)(tempValue>>(8*(3-j)));
+  }
+  
+  /* Writes the new IRQ mask in the corresponding registers */
+  g_xStatus = SpiritSpiWriteRegisters(IRQ_MASK3_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Fills a pointer to a structure of SpiritIrqs type reading the IRQ_MASK registers.
+ * @param  pxIrqMask pointer to a variable of type @ref SpiritIrqs, through which the
+ *         user can read which IRQs are enabled. All the bitfields equals to zero correspond
+ *         to enabled IRQs, while all the bitfields equals to one correspond to disabled IRQs.
+ *         This parameter is a pointer to a SpiritIrqs.
+ *         For example suppose that the Power On Reset and RX Data ready are the only enabled IRQs.
+ * @code
+ * SpiritIrqs myIrqMask;
+ * SpiritIrqGetStatus(&myIrqMask);
+ * @endcode
+ * Then
+ * myIrqMask.IRQ_POR and myIrqMask.IRQ_RX_DATA_READY are equal to 0
+ * while all the other bitfields are equal to one.
+ * @retval None.
+ */
+void SpiritIrqGetMask(SpiritIrqs* pxIrqMask)
+{
+  /* Reads IRQ_MASK registers */
+  g_xStatus = SpiritSpiReadRegisters(IRQ_MASK3_BASE, 4, (uint8_t*)pxIrqMask);
+}
+
+
+/**
+ * @brief  Filla a pointer to a structure of SpiritIrqs type reading the IRQ_STATUS registers.
+ * @param  pxIrqStatus pointer to a variable of type @ref SpiritIrqs, through which the
+ *         user can read the status of all the IRQs. All the bitfields equals to one correspond
+ *         to the raised interrupts. This parameter is a pointer to a SpiritIrqs.
+ *         For example suppose that the XO settling timeout is raised as well as the Sync word
+ *         detection.
+ * @code
+ * SpiritIrqs myIrqStatus;
+ * SpiritIrqGetStatus(&myIrqStatus);
+ * @endcode
+ * Then
+ * myIrqStatus.IRQ_XO_COUNT_EXPIRED and myIrqStatus.IRQ_VALID_SYNC are equals to 1
+ * while all the other bitfields are equals to zero.
+ * @retval None.
+ */
+void SpiritIrqGetStatus(SpiritIrqs* pxIrqStatus)
+{
+  /* Reads IRQ_STATUS registers */
+  g_xStatus = SpiritSpiReadRegisters(IRQ_STATUS3_BASE, 4, (uint8_t*)pxIrqStatus);
+}
+
+
+/**
+ * @brief  Clear the IRQ status registers.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritIrqClearStatus(void)
+{
+  uint8_t tempRegValue[4];
+
+  /* Reads the IRQ_STATUS registers clearing all the flags */
+  g_xStatus = SpiritSpiReadRegisters(IRQ_STATUS3_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Verifies if a specific IRQ has been generated.
+ *         The call resets all the IRQ status, so it can't be used in case of multiple raising interrupts.
+ * @param  xFlag IRQ flag to be checked.
+ *         This parameter can be any value of @ref IrqList.
+ * @retval SpiritBool S_TRUE or S_FALSE.
+ */
+SpiritBool SpiritIrqCheckFlag(IrqList xFlag)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempValue = 0;
+  SpiritBool flag;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_IRQ_LIST(xFlag));
+
+  /* Reads registers and build the status word */
+  g_xStatus = SpiritSpiReadRegisters(IRQ_STATUS3_BASE, 4, tempRegValue);
+  for(uint8_t i=0; i<4; i++)
+  {
+    tempValue += ((uint32_t)tempRegValue[i])<<(8*(3-i));
+  }
+  
+  if(tempValue & xFlag)
+  {
+    flag = S_TRUE;
+  }
+  else
+  {
+    flag = S_FALSE;
+  }
+
+  return flag;
+
+}
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_LinearFifo.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_LinearFifo.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,337 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_LinearFifo.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT Fifo.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_LinearFifo.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_LinearFifo
+ * @{
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_TypesDefinitions        Linear FIFO Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_Defines                 Linear FIFO Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_Macros                  Linear FIFO Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_Variables               Linear FIFO Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_FunctionPrototypes      Linear FIFO Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup LinearFifo_Private_Functions               Linear FIFO Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Returns the number of elements in the Rx FIFO.
+ * @param  None.
+ * @retval uint8_t Number of elements in the Rx FIFO.
+ */
+uint8_t SpiritLinearFifoReadNumElementsRxFifo(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(LINEAR_FIFO_STATUS0_BASE, 1, &tempRegValue);
+
+  /* Build and return value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Returns the number of elements in the Tx FIFO.
+ * @param  None.
+ * @retval uint8_t Number of elements in the Tx FIFO.
+ */
+uint8_t SpiritLinearFifoReadNumElementsTxFifo(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the number of elements in TX FIFO and return the value */
+  g_xStatus = SpiritSpiReadRegisters(LINEAR_FIFO_STATUS1_BASE, 1, &tempRegValue);
+
+  /* Build and return value */
+  return (tempRegValue & 0x7F);
+}
+
+
+/**
+ * @brief  Sets the almost full threshold for the Rx FIFO. When the number of elements in RX FIFO reaches this value an interrupt can be generated to the MCU.
+ * @note   The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost
+ *         full FIFO irq will be raised when the number of elements is equals to 96-7 = 89.
+ * @param  cThrRxFifo almost full threshold.
+ * 	   This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritLinearFifoSetAlmostFullThresholdRx(uint8_t cThrRxFifo)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_FIFO_THR(cThrRxFifo));
+
+  /* Build the register value */
+  tempRegValue = cThrRxFifo & 0x7F;
+
+  /* Writes the Almost Full threshold for RX in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(FIFO_CONFIG3_RXAFTHR_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the almost full threshold for RX FIFO.
+ * @note   The almost full threshold is encountered from the top of the FIFO. For example, if it is 7 the almost
+ *         full FIFO irq will be raised when the number of elements is equals to 96-7 = 89.
+ * @param  None.
+ * @retval uint8_t Almost full threshold for Rx FIFO.
+ */
+uint8_t SpiritLinearFifoGetAlmostFullThresholdRx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the almost full threshold for RX FIFO and return the value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG3_RXAFTHR_BASE, 1, &tempRegValue);
+
+  /* Build and return value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the almost empty threshold for the Rx FIFO. When the number of elements in RX FIFO reaches this value an interrupt can be generated to the MCU.
+ * @param  cThrRxFifo almost empty threshold.
+ * 	   This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritLinearFifoSetAlmostEmptyThresholdRx(uint8_t cThrRxFifo)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_FIFO_THR(cThrRxFifo));
+
+  /* Build the register value */
+  tempRegValue = cThrRxFifo & 0x7F;
+
+  /* Writes the Almost Empty threshold for RX in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(FIFO_CONFIG2_RXAETHR_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the almost empty threshold for Rx FIFO.
+ * @param  None.
+ * @retval uint8_t Almost empty threshold for Rx FIFO.
+ */
+uint8_t SpiritLinearFifoGetAlmostEmptyThresholdRx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the almost empty threshold for RX FIFO and returns the value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG2_RXAETHR_BASE, 1, &tempRegValue);
+
+  /* Build and return value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the almost full threshold for the Tx FIFO. When the number of elements in TX FIFO reaches this value an interrupt can be generated to the MCU.
+ * @note   The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost
+ *         full FIFO irq will be raised when the number of elements is equals to 96-7 = 89.
+ * @param  cThrTxFifo almost full threshold.
+ * 	   This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritLinearFifoSetAlmostFullThresholdTx(uint8_t cThrTxFifo)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_FIFO_THR(cThrTxFifo));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG1_TXAFTHR_BASE, 1, &tempRegValue);
+
+  /* Build the register value */
+  tempRegValue &= 0x80;
+  tempRegValue |= cThrTxFifo;
+
+  /* Writes the Almost Full threshold for Tx in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(FIFO_CONFIG1_TXAFTHR_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the almost full threshold for Tx FIFO.
+ * @note   The almost full threshold is encountered from the top of the FIFO. For example, if it is set to 7 the almost
+ *         full FIFO irq will be raised when the number of elements is equals to 96-7 = 89.
+ * @param  None.
+ * @retval uint8_t Almost full threshold for Tx FIFO.
+ */
+uint8_t SpiritLinearFifoGetAlmostFullThresholdTx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the almost full threshold for Tx FIFO and returns the value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG1_TXAFTHR_BASE, 1, &tempRegValue);
+
+  /* Build and returns value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Sets the almost empty threshold for the Tx FIFO. When the number of elements in Tx FIFO reaches this value an interrupt can can be generated to the MCU.
+ * @param  cThrTxFifo: almost empty threshold.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritLinearFifoSetAlmostEmptyThresholdTx(uint8_t cThrTxFifo)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_FIFO_THR(cThrTxFifo));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG0_TXAETHR_BASE, 1, &tempRegValue);
+
+  /* Build the register value */
+  tempRegValue &= 0x80;
+  tempRegValue |= cThrTxFifo;
+
+  /* Writes the Almost Empty threshold for Tx in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(FIFO_CONFIG0_TXAETHR_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the almost empty threshold for Tx FIFO.
+ * @param  None.
+ * @retval uint8_t Almost empty threshold for Tx FIFO.
+ */
+uint8_t SpiritLinearFifoGetAlmostEmptyThresholdTx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the almost empty threshold for TX FIFO and returns the value */
+  g_xStatus = SpiritSpiReadRegisters(FIFO_CONFIG0_TXAETHR_BASE, 1, &tempRegValue);
+
+  /* Build and return value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Management.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Management.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,364 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Management.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   The management layer for SPIRIT1 library.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Management.h"
+
+/**
+* @addtogroup SPIRIT_Libraries
+* @{
+*/
+
+
+/**
+* @defgroup SPIRIT_MANAGEMENT              SPIRIT Management
+* @{
+*/
+
+/**
+* @brief  BS value to write in the SYNT0 register according to the selected band
+*/
+static const uint8_t s_vectcBandRegValue[4]={SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32};
+
+#define COMMUNICATION_STATE_TX          0
+#define COMMUNICATION_STATE_RX          1
+#define COMMUNICATION_STATE_NONE        2
+
+static uint32_t s_nDesiredFrequency;
+
+static volatile uint8_t s_cCommunicationState = COMMUNICATION_STATE_NONE;
+
+
+/**
+* @brief  Factor is: B/2 used in the formula for SYNTH word calculation
+*/
+static const uint8_t s_vectcBHalfFactor[4]={(HIGH_BAND_FACTOR/2), (MIDDLE_BAND_FACTOR/2), (LOW_BAND_FACTOR/2), (VERY_LOW_BAND_FACTOR/2)};
+
+
+/**
+* @defgroup SPIRIT_MANAGEMENT_FUNCTIONS    SPIRIT Management Functions
+* @{
+*/
+
+
+/**
+* @defgroup WORKAROUND_FUNCTIONS              SPIRIT Management Workaround Functions
+* @{
+*/
+
+/**
+* @brief  Private SpiritRadioSetFrequencyBase function only used in SpiritManagementWaVcoCalibration.
+* @param  lFBase the base carrier frequency expressed in Hz as unsigned word.
+* @retval None.
+*/
+void SpiritManagementSetFrequencyBase(uint32_t lFBase)
+{
+  uint32_t synthWord, Fc;
+  uint8_t band = 0, anaRadioRegArray[4], wcp;
+  
+  /* Check the parameter */
+  s_assert_param(IS_FREQUENCY_BAND(lFBase));
+  
+  /* Search the operating band */
+  if(IS_FREQUENCY_BAND_HIGH(lFBase))
+  {
+    band = HIGH_BAND;
+  }
+  else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
+  {
+    band = MIDDLE_BAND;
+  }
+  else if(IS_FREQUENCY_BAND_LOW(lFBase))
+  {
+    band = LOW_BAND;
+  }
+  else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
+  {
+    band = VERY_LOW_BAND;
+  }
+  
+  int32_t FOffset  = SpiritRadioGetFrequencyOffset();
+  uint32_t lChannelSpace  = SpiritRadioGetChannelSpace();
+  uint8_t cChannelNum = SpiritRadioGetChannel();
+  
+  /* Calculates the channel center frequency */
+  Fc = lFBase + FOffset + lChannelSpace*cChannelNum;
+  
+  /* Reads the reference divider */
+  uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
+  
+  switch(band)
+  {
+  case VERY_LOW_BAND:
+    if(Fc<161281250)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case LOW_BAND:
+    if(Fc<322562500)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case MIDDLE_BAND:
+    if(Fc<430083334)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case HIGH_BAND:
+    if(Fc<860166667)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+  }
+  
+  /* Search the VCO charge pump word and set the corresponding register */
+  wcp = SpiritRadioSearchWCP(Fc);
+  
+  synthWord = (uint32_t)(lFBase*(((double)(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band]))/SpiritRadioGetXtalFrequency()));
+  
+  /* Build the array of registers values for the analog part */
+  anaRadioRegArray[0] = (uint8_t)(((synthWord>>21)&(0x0000001F))|(wcp<<5));
+  anaRadioRegArray[1] = (uint8_t)((synthWord>>13)&(0x000000FF));
+  anaRadioRegArray[2] = (uint8_t)((synthWord>>5)&(0x000000FF));
+  anaRadioRegArray[3] = (uint8_t)(((synthWord&0x0000001F)<<3)| s_vectcBandRegValue[band]);
+  
+  /* Configures the needed Analog Radio registers */
+  g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, anaRadioRegArray);
+}
+
+uint8_t SpiritManagementWaVcoCalibration(void)
+{
+  uint8_t s_cVcoWordRx;
+  uint8_t s_cVcoWordTx;
+  uint32_t nFreq;
+  uint8_t cRestore = 0;
+  uint8_t cStandby = 0;
+  uint32_t xtal_frequency = SpiritRadioGetXtalFrequency();
+  
+  /* Enable the reference divider if the XTAL is between 48 and 52 MHz */
+  if(xtal_frequency>DOUBLE_XTAL_THR)
+  {
+    if(!SpiritRadioGetRefDiv())
+    {
+      cRestore = 1;
+      nFreq = SpiritRadioGetFrequencyBase();
+      SpiritRadioSetRefDiv(S_ENABLE);
+      SpiritManagementSetFrequencyBase(nFreq);
+    }
+  }
+  nFreq = SpiritRadioGetFrequencyBase();
+  
+  /* Increase the VCO current */
+  uint8_t tmp = 0x19; SpiritSpiWriteRegisters(0xA1,1,&tmp);
+  
+  SpiritCalibrationVco(S_ENABLE);
+  
+  SpiritRefreshStatus();
+  if(g_xStatus.MC_STATE == MC_STATE_STANDBY)
+  {
+    cStandby = 1;
+    SpiritCmdStrobeReady();
+    do{
+      SpiritRefreshStatus();
+      if(g_xStatus.MC_STATE == 0x13)
+      {
+        return 1;
+      }
+    }while(g_xStatus.MC_STATE != MC_STATE_READY); 
+  }
+  
+  SpiritCmdStrobeLockTx();
+  
+  do{
+    SpiritRefreshStatus();
+    if(g_xStatus.MC_STATE == 0x13)
+    {
+      return 1;
+    }
+  }while(g_xStatus.MC_STATE != MC_STATE_LOCK);
+  
+  s_cVcoWordTx = SpiritCalibrationGetVcoCalData();
+  
+  SpiritCmdStrobeReady();
+  
+  do{
+    SpiritRefreshStatus();
+  }while(g_xStatus.MC_STATE != MC_STATE_READY); 
+  
+    
+  SpiritCmdStrobeLockRx();
+  
+  do{
+    SpiritRefreshStatus();
+    if(g_xStatus.MC_STATE == 0x13)
+    {
+      return 1;
+    }
+  }while(g_xStatus.MC_STATE != MC_STATE_LOCK);
+  
+  s_cVcoWordRx = SpiritCalibrationGetVcoCalData();
+  
+  SpiritCmdStrobeReady();
+  
+  do{
+    SpiritRefreshStatus();
+    if(g_xStatus.MC_STATE == 0x13)
+    {
+      return 1;
+    }
+  }while(g_xStatus.MC_STATE != MC_STATE_READY);
+  
+  if(cStandby == 1)
+  {
+    SpiritCmdStrobeStandby();    
+  }
+  SpiritCalibrationVco(S_DISABLE);
+  
+  /* Disable the reference divider if the XTAL is between 48 and 52 MHz */
+  if(cRestore)
+  {
+    SpiritRadioSetRefDiv(S_DISABLE);    
+    SpiritManagementSetFrequencyBase(nFreq);
+  }
+  
+  /* Restore the VCO current */
+  tmp = 0x11; SpiritSpiWriteRegisters(0xA1,1,&tmp);
+  
+  SpiritCalibrationSetVcoCalDataTx(s_cVcoWordTx);
+  SpiritCalibrationSetVcoCalDataRx(s_cVcoWordRx);
+  
+  return 0;
+}
+
+
+void SpiritManagementWaCmdStrobeTx(void)
+{
+  if(s_cCommunicationState != COMMUNICATION_STATE_TX)
+  {
+    //uint32_t xtal_frequency = SpiritRadioGetXtalFrequency();
+    
+    /* To achive the max output power */
+    if(s_nDesiredFrequency>=150000000 && s_nDesiredFrequency<=470000000)
+    {
+      /* Optimal setting for Tx mode only */
+      SpiritRadioSetPACwc(LOAD_3_6_PF);
+    }
+    else
+    {
+      /* Optimal setting for Tx mode only */
+      SpiritRadioSetPACwc(LOAD_0_PF);
+    }
+    
+    uint8_t tmp = 0x11; SpiritSpiWriteRegisters(0xa9, 1, &tmp); /* Enable VCO_L buffer */
+    tmp = 0x20; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */
+    
+    s_cCommunicationState = COMMUNICATION_STATE_TX;
+  }
+}
+
+
+void SpiritManagementWaCmdStrobeRx(void)
+{
+  if(s_cCommunicationState != COMMUNICATION_STATE_RX)
+  {    
+    uint8_t tmp = 0x98; SpiritSpiWriteRegisters(PM_CONFIG1_BASE, 1, &tmp); /* Set SMPS switching frequency */    
+    SpiritRadioSetPACwc(LOAD_0_PF); /* Set the correct CWC parameter */
+    
+    s_cCommunicationState = COMMUNICATION_STATE_RX;
+  }
+}
+
+void SpiritManagementWaTRxFcMem(uint32_t nDesiredFreq)
+{
+  s_cCommunicationState = COMMUNICATION_STATE_NONE;
+  s_nDesiredFrequency = nDesiredFreq;
+}
+
+
+void SpiritManagementWaExtraCurrent(void)
+{          
+  uint8_t tmp= 0xCA;SpiritSpiWriteRegisters(0xB2, 1, &tmp); 
+  tmp= 0x04;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 
+  /* just a read to loose some microsecs more */
+  SpiritSpiReadRegisters(0xA8, 1, &tmp);
+  tmp= 0x00;SpiritSpiWriteRegisters(0xA8, 1, &tmp); 
+}
+
+/**
+* @}
+*/
+
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktBasic.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktBasic.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,615 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_PktBasic.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT Basic packets.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_PktBasic.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_PktBasic
+ * @{
+ */
+
+
+/**
+ * @defgroup PktBasic_Private_TypesDefinitions  Pkt Basic Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Private_Defines           Pkt Basic Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Private_Macros            Pkt Basic Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Private_Variables          Pkt Basic Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup PktBasic_Private_FunctionPrototypes        Pkt Basic Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktBasic_Private_Functions                 Pkt Basic Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Initializes the SPIRIT Basic packet according to the specified parameters in the PktBasicInit struct.
+ *         Notice that this function sets the autofiltering option on CRC if it is set to any value different from BASIC_NO_CRC.
+ * @param  pxPktBasicInit Basic packet init structure.
+ *         This parameter is a pointer to @ref PktBasicInit.
+ * @retval None.
+ */
+void SpiritPktBasicInit(PktBasicInit* pxPktBasicInit)
+{
+  uint8_t tempRegValue[4], i;
+
+  /* Check the parameters */
+  s_assert_param(IS_BASIC_PREAMBLE_LENGTH(pxPktBasicInit->xPreambleLength));
+  s_assert_param(IS_BASIC_SYNC_LENGTH(pxPktBasicInit->xSyncLength));
+  s_assert_param(IS_BASIC_CRC_MODE(pxPktBasicInit->xCrcMode));
+  s_assert_param(IS_BASIC_LENGTH_WIDTH_BITS(pxPktBasicInit->cPktLengthWidth));
+  s_assert_param(IS_BASIC_FIX_VAR_LENGTH(pxPktBasicInit->xFixVarLength));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicInit->xAddressField));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicInit->xFec));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicInit->xDataWhitening));
+  s_assert_param(IS_BASIC_CONTROL_LENGTH(pxPktBasicInit->xControlLength));
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue[0]);
+
+  /* Mask a reserved bit */
+  tempRegValue[0] &= ~0x20;
+
+  /* Always set the automatic packet filtering */
+  tempRegValue[0] |= PROTOCOL1_AUTO_PCKT_FLT_MASK;
+
+  /* Writes the value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue[0]);
+
+  /* Reads the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+
+  /* Always reset the control and source filtering (also if it is not present in basic) */
+  tempRegValue[0] &= ~(PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK | PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK);
+
+  /* Writes the value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+
+  if(pxPktBasicInit->xAddressField == S_ENABLE)
+  {
+    tempRegValue[0]=0x08;
+  }
+  else
+  {
+    tempRegValue[0]=0x00;
+  }
+  /* Address and control length setting */
+  tempRegValue[0] |= ((uint8_t) pxPktBasicInit->xControlLength);
+
+  /* Packet format and width length setting */
+  pxPktBasicInit->cPktLengthWidth == 0 ? pxPktBasicInit->cPktLengthWidth=1 : pxPktBasicInit->cPktLengthWidth;
+  tempRegValue[1] = ((uint8_t) PCKTCTRL3_PCKT_FRMT_BASIC) | ((uint8_t)(pxPktBasicInit->cPktLengthWidth-1));
+
+  /* Preamble, sync and fixed or variable length setting */
+  tempRegValue[2] = ((uint8_t) pxPktBasicInit->xPreambleLength) | ((uint8_t) pxPktBasicInit->xSyncLength) |
+                    ((uint8_t) pxPktBasicInit->xFixVarLength);
+
+  /* CRC length, whitening and FEC setting */
+  tempRegValue[3] = (uint8_t) pxPktBasicInit->xCrcMode;
+
+  if(pxPktBasicInit->xDataWhitening == S_ENABLE)
+  {
+     tempRegValue[3] |= PCKTCTRL1_WHIT_MASK;
+  }
+
+  if(pxPktBasicInit->xFec == S_ENABLE)
+  {
+     tempRegValue[3] |= PCKTCTRL1_FEC_MASK;
+  }
+
+  /* Writes registers */
+  SpiritSpiWriteRegisters(PCKTCTRL4_BASE, 4, tempRegValue);
+
+  /* Sync words setting */
+  for(i=0;i<4;i++)
+  {
+    if(i<3-(pxPktBasicInit->xSyncLength >>1))
+    {
+      tempRegValue[i]=0;
+    }
+    else
+    {
+      tempRegValue[i] = (uint8_t)(pxPktBasicInit->lSyncWords>>(8*i));
+    }
+  }
+
+  /* Sets CRC check bit */
+  if(pxPktBasicInit->xCrcMode == PKT_NO_CRC)
+  {
+    SpiritPktBasicFilterOnCrc(S_DISABLE);
+  }
+  else
+  {
+    SpiritPktBasicFilterOnCrc(S_ENABLE);
+  }
+
+  
+  g_xStatus = SpiritSpiWriteRegisters(SYNC4_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the SPIRIT Basic packet structure according to the specified parameters in the registers.
+ * @param  pxPktBasicInit Basic packet init structure.
+ *         This parameter is a pointer to @ref PktBasicInit.
+ * @retval None.
+ */
+void SpiritPktBasicGetInfo(PktBasicInit* pxPktBasicInit)
+{
+  uint8_t tempRegValue[10];
+
+  /* Reads registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 10, tempRegValue);
+
+  /* Length width */
+  pxPktBasicInit->cPktLengthWidth=(tempRegValue[1] & 0x0F)+1;
+
+  /* Address field */
+  pxPktBasicInit->xAddressField=(SpiritFunctionalState)((tempRegValue[0]>>3) & 0x01);
+
+  /* Control length */
+  pxPktBasicInit->xControlLength=(BasicControlLength)(tempRegValue[0] & 0x07);
+
+  /* CRC mode */
+  pxPktBasicInit->xCrcMode=(BasicCrcMode)(tempRegValue[3] & 0xE0);
+
+  /* Whitening */
+  pxPktBasicInit->xDataWhitening=(SpiritFunctionalState)((tempRegValue[3] >> 4) & 0x01);
+
+  /* FEC */
+  pxPktBasicInit->xFec=(SpiritFunctionalState)(tempRegValue[3] & 0x01);
+
+  /* FIX or VAR bit */
+  pxPktBasicInit->xFixVarLength=(BasicFixVarLength)(tempRegValue[2] & 0x01);
+
+  /* Preamble length */
+  pxPktBasicInit->xPreambleLength=(BasicPreambleLength)(tempRegValue[2] & 0xF8);
+
+  /* Sync length */
+  pxPktBasicInit->xSyncLength=(BasicSyncLength)(tempRegValue[2] & 0x06);
+
+  /* sync Words */
+  pxPktBasicInit->lSyncWords=0;
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+      if(i>2-(((uint8_t)pxPktBasicInit->xSyncLength) >>1))
+      {
+        pxPktBasicInit->lSyncWords |= (uint32_t)(tempRegValue[i+6])<<(8*i);
+      }
+  }
+
+}
+
+
+/**
+ * @brief  Initializes the SPIRIT Basic packet addresses according to the specified
+ *         parameters in the PktBasicAddressesInit struct.
+ * @param  pxPktBasicAddresses Basic packet addresses init structure.
+ *         This parameter is a pointer to @ref PktBasicAddresses.
+ * @retval None.
+ */
+void SpiritPktBasicAddressesInit(PktBasicAddressesInit* pxPktBasicAddresses)
+{
+  uint8_t tempRegValue[3];
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnMyAddress));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnMulticastAddress));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktBasicAddresses->xFilterOnBroadcastAddress));
+
+
+  /* Reads the PCKT_FLT_OPTIONS ragister */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+  
+  /* Enables or disables filtering on my address */
+  if(pxPktBasicAddresses->xFilterOnMyAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+  
+  /* Enables or disables filtering on multicast address */
+  if(pxPktBasicAddresses->xFilterOnMulticastAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+  
+  /* Enables or disables filtering on broadcast address */
+  if(pxPktBasicAddresses->xFilterOnBroadcastAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+  
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+  
+  /* Fills the array with the addresses passed in the structure */
+  tempRegValue[0] = pxPktBasicAddresses->cBroadcastAddress;
+  tempRegValue[1] = pxPktBasicAddresses->cMulticastAddress;
+  tempRegValue[2] = pxPktBasicAddresses->cMyAddress;
+  
+  /* Writes values on the PCKT_FLT_GOALS registers */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 3, tempRegValue);
+  
+  
+}
+
+
+/**
+ * @brief  Returns the SPIRIT Basic packet addresses structure according to the specified
+ *         parameters in the registers.
+ * @param  pxPktBasicAddresses Basic packet addresses init structure.
+ *         This parameter is a pointer to @ref PktBasicAddresses.
+ * @retval None.
+ */
+void SpiritPktBasicGetAddressesInfo(PktBasicAddressesInit* pxPktBasicAddresses)
+{
+  uint8_t tempRegValue[3];
+
+  /* Reads values on the PCKT_FLT_GOALS registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 3, tempRegValue);
+
+  /* Fit the structure with the read addresses */
+  pxPktBasicAddresses->cBroadcastAddress = tempRegValue[0];
+  pxPktBasicAddresses->cMulticastAddress = tempRegValue[1];
+  pxPktBasicAddresses->cMyAddress = tempRegValue[2];
+
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+
+  /* Fit the structure with the read filtering bits */
+  pxPktBasicAddresses->xFilterOnBroadcastAddress = (SpiritFunctionalState)((tempRegValue[0] >> 1) & 0x01);
+  pxPktBasicAddresses->xFilterOnMulticastAddress = (SpiritFunctionalState)((tempRegValue[0] >> 2) & 0x01);
+  pxPktBasicAddresses->xFilterOnMyAddress = (SpiritFunctionalState)((tempRegValue[0] >> 3) & 0x01);
+
+}
+
+
+/**
+ * @brief  Configures the Basic packet format as packet used by SPIRIT.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritPktBasicSetFormat(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Build the new value. Also set to 0 the direct RX mode bits */
+  tempRegValue &= 0x0F;
+  tempRegValue |= (uint8_t)PCKTCTRL3_PCKT_FRMT_BASIC;
+
+  /* Writes the  value on the PCKTCTRL3 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Reads the PCKTCTRL1_BASE register */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build the new value. Set to 0 the direct TX mode bits */
+  tempRegValue &= 0xF3;
+
+  /* Writes the value on the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Mask a reserved bit */
+  tempRegValue &= ~0x20;
+
+  /* Writes the value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+}
+
+
+/**
+ * @brief  Sets the address length for SPIRIT Basic packets.
+ * @param  xAddressField length of ADDRESS in bytes.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktBasicAddressField(SpiritFunctionalState xAddressField)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xAddressField));
+
+  /* Reads the PCKTCTRL4 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+  /* Build the address length for the register */
+  if(xAddressField==S_ENABLE)
+  {
+    tempRegValue |= 0x08;
+  }
+  else
+  {
+    tempRegValue &= 0x07;
+  }
+
+  /* Writes the new value on the PCKTCTRL4 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Specifies if the Address field for SPIRIT Basic packets is enabled or disabled.
+ * @param  None.
+ * @retval SpiritFunctionalState Notifies if the address field is enabled or disabled.
+ */
+SpiritFunctionalState SpiritPktBasicGetAddressField(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL4 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+  /* Returns the address field value */
+  if(tempRegValue & PCKTCTRL4_ADDRESS_LEN_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+
+/**
+ * @brief  Sets the payload length for SPIRIT Basic packets. Since the packet length
+ *         depends from the address and the control field size, this
+ *         function reads the correspondent registers in order to determine
+ *         the correct packet length to be written.
+ * @param  nPayloadLength payload length in bytes.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+void SpiritPktBasicSetPayloadLength(uint16_t nPayloadLength)
+{
+  uint8_t tempRegValue[2];
+  uint16_t overSize=0;
+
+  /* Computes the oversize (address + control) size */
+  if(SpiritPktBasicGetAddressField())
+  {
+    overSize=1;
+  }
+  overSize += (uint16_t) SpiritPktBasicGetControlLength();
+
+  /* Computes PCKTLEN0 value from nPayloadLength */
+  tempRegValue[1]=BASIC_BUILD_PCKTLEN0(nPayloadLength+overSize);
+  /* Computes PCKTLEN1 value from nPayloadLength */
+  tempRegValue[0]=BASIC_BUILD_PCKTLEN1(nPayloadLength+overSize);
+
+  /* Writes data on the PCKTLEN1/0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the payload length for SPIRIT Basic packets. Since the
+ *         packet length depends from the address and the control
+ *         field size, this function reads the correspondent
+ *         registers in order to determine the correct payload length
+ *         to be returned.
+ * @param  None.
+ * @retval uint16_t Payload length in bytes.
+ */
+uint16_t SpiritPktBasicGetPayloadLength(void)
+{
+  uint8_t tempRegValue[2];
+  uint16_t overSize=0;
+
+  /* Computes the oversize (address + control) size */
+  if(SpiritPktBasicGetAddressField())
+  {
+    overSize=1;
+  }
+  overSize += (uint16_t) SpiritPktBasicGetControlLength();
+
+  /* Reads the packet length registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+  /* Returns the packet length */
+  return ((((uint16_t)tempRegValue[0])<<8) + (uint16_t) tempRegValue[1]) - overSize;
+}
+
+/**
+ * @brief  Returns the packet length field of the received packet.
+ * @param  None.
+ * @retval uint16_t Packet length.
+ */
+uint16_t SpiritPktBasicGetReceivedPktLength(void)
+{
+  uint8_t tempRegValue[2];
+  uint16_t overSize=0;
+
+  /* Computes the oversize (address + control) size */
+  if(SpiritPktBasicGetAddressField())
+  {
+    overSize=1;
+  }
+  overSize += (uint16_t) SpiritPktBasicGetControlLength();
+  
+  /* Reads the RX_PCKT_LENx registers value */
+  g_xStatus = SpiritSpiReadRegisters(RX_PCKT_LEN1_BASE, 2, tempRegValue);
+
+  /* Rebuild and return the length field */
+  return (((((uint16_t) tempRegValue[0]) << 8) + (uint16_t) tempRegValue[1]) - overSize);
+}
+
+/**
+ * @brief  Computes and sets the variable payload length for SPIRIT Basic packets.
+ * @param  nMaxPayloadLength payload length in bytes.
+ *         This parameter is an uint16_t.
+ * @param  xAddressField Enable or Disable Address Field.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @param  xControlLength Control length in bytes.
+ *         This parameter can be any value of @ref BasicControlLength.
+ * @retval None.
+ */
+void SpiritPktBasicSetVarLengthWidth(uint16_t nMaxPayloadLength, SpiritFunctionalState xAddressField, BasicControlLength xControlLength)
+{
+  uint8_t tempRegValue,
+          addressLength,
+          i;
+  uint32_t packetLength;
+
+  /* Sets the address length according to xAddressField */
+  if(xAddressField == S_ENABLE)
+  {
+    addressLength=1;
+  }
+  else
+  {
+    addressLength=0;
+  }
+
+  /* packet length = payload length + address length + control length */
+  packetLength=nMaxPayloadLength+addressLength+xControlLength;
+
+  /* Computes the number of bits */
+  for(i=0;i<16;i++)
+  {
+    if(packetLength == 0) break;
+    {
+    packetLength >>= 1;
+    }
+  }
+  i==0 ? i=1 : i;
+
+  /* Reads the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Build value for the length width */
+  tempRegValue &= ~PCKTCTRL3_LEN_WID_MASK;
+  tempRegValue |= (uint8_t)(i-1);
+
+  /* Writes the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+}
+
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktCommon.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktCommon.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1453 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_PktCommon.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of the common features of SPIRIT packets.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_PktCommon.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_PktCommon
+ * @{
+ */
+
+
+/**
+ * @defgroup PktCommon_Private_TypesDefinitions         Pkt Common Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Private_Defines                  Pkt Common Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Private_Macros                   Pkt Common Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Private_Variables                Pkt Common Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+
+/**
+ * @defgroup PktCommon_Private_FunctionPrototypes       Pkt Common Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktCommon_Private_Functions                Pkt Common Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Sets the CONTROL field length for SPIRIT packets.
+ * @param  xControlLength length of CONTROL field in bytes.
+ *         This parameter can be any value of @ref PktControlLength.
+ * @retval None.
+ */
+void SpiritPktCommonSetControlLength(PktControlLength xControlLength)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_CONTROL_LENGTH(xControlLength));
+
+  /* Reads the PCKTCTRL4 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+  /* Set the control length */
+  tempRegValue &= ~PCKTCTRL4_CONTROL_LEN_MASK;
+  tempRegValue |= (uint8_t)xControlLength;
+
+  /* Writes the new value on the PCKTCTRL4 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+}
+
+
+/**
+ * @brief  Returns the CONTROL field length for SPIRIT packets.
+ * @param  None.
+ * @retval uint8_t Control field length.
+ */
+uint8_t SpiritPktCommonGetControlLength(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL4 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return value */
+  return (tempRegValue & PCKTCTRL4_CONTROL_LEN_MASK);
+}
+
+
+/**
+ * @brief  Sets the PREAMBLE field Length mode for SPIRIT packets.
+ * @param  xPreambleLength length of PREAMBLE field in bytes.
+ *         This parameter can be any value of @ref PktPreambleLength.
+ * @retval None.
+ */
+void SpiritPktCommonSetPreambleLength(PktPreambleLength xPreambleLength)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_PREAMBLE_LENGTH(xPreambleLength));
+
+  /* Reads the PCKTCTRL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+  /* Set the preamble length */
+  tempRegValue &= ~PCKTCTRL2_PREAMBLE_LENGTH_MASK;
+  tempRegValue |= (uint8_t)xPreambleLength;
+
+  /* Writes the new value on the PCKTCTRL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+}
+
+
+/**
+ * @brief  Returns the PREAMBLE field Length mode for SPIRIT packets.
+ * @param  None.
+ * @retval uint8_t Preamble field length in bytes.
+ */
+uint8_t SpiritPktCommonGetPreambleLength(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return value */
+  return ((tempRegValue & PCKTCTRL2_PREAMBLE_LENGTH_MASK)>>3) + 1;
+
+}
+
+
+/**
+ * @brief  Sets the SYNC field Length for SPIRIT packets.
+ * @param  xSyncLength length of SYNC field in bytes.
+ *         This parameter can be any value of @ref PktSyncLength.
+ * @retval None.
+ */
+void SpiritPktCommonSetSyncLength(PktSyncLength xSyncLength)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_SYNC_LENGTH(xSyncLength));
+
+  /* Reads the PCKTCTRL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+  /* Set the sync length */
+  tempRegValue &= ~PCKTCTRL2_SYNC_LENGTH_MASK;
+  tempRegValue |= (uint8_t)xSyncLength;
+
+  /* Writes the new value on the PCKTCTRL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the SYNC field Length for SPIRIT packets.
+ * @param  None.
+ * @retval uint8_t Sync field length in bytes.
+ */
+uint8_t SpiritPktCommonGetSyncLength(void)
+{
+  uint8_t tempRetValue;
+
+  /* Reads the PCKTCTRL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL2_BASE, 1, &tempRetValue);
+
+  /* Rebuild and return value */
+  return ((tempRetValue & PCKTCTRL2_SYNC_LENGTH_MASK)>>1) + 1;
+
+}
+
+
+/**
+ * @brief  Sets fixed or variable payload length mode for SPIRIT packets.
+ * @param  xFixVarLength variable or fixed length.
+ *         PKT_FIXED_LENGTH_VAR -> variable (the length is extracted from the received packet).
+ *         PKT_FIXED_LENGTH_FIX -> fix (the length is set by PCKTLEN0 and PCKTLEN1).
+ * @retval None.
+ */
+void SpiritPktCommonSetFixVarLength(PktFixVarLength xFixVarLength)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_FIX_VAR_LENGTH(xFixVarLength));
+
+  /* Reads the PCKTCTRL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+  /* Set fixed or variable address mode */
+  tempRegValue &= ~PCKTCTRL2_FIX_VAR_LEN_MASK;
+  tempRegValue |= (uint8_t)xFixVarLength;
+
+  /* Writes the new value on the PCKTCTRL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables or Disables the filtering on CRC.
+ * @param  xNewState new state for CRC_CHECK.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonFilterOnCrc(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PCKT_FLT_OPTIONS register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Modify the register value: enable or disable the CRC filtering */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_CRC_CHECK_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_CRC_CHECK_MASK;
+  }
+
+  /* Writes the PCKT_FLT_OPTIONS register value */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the CRC filtering enable bit.
+ * @param  None.
+ * @retval SpiritFunctionalState CRC filtering.
+ */
+SpiritFunctionalState SpiritPktCommonGetFilterOnCrc(void)
+{
+  uint8_t tempRegValue;
+
+
+  /* Reads the PCKT_FLT_OPTIONS register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Check the CRC filtering bit */
+  if(tempRegValue & PCKT_FLT_OPTIONS_CRC_CHECK_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+
+/**
+ * @brief  Sets the CRC mode for SPIRIT packets.
+ * @param  xCrcMode length of CRC field in bytes.
+ *         This parameter can be any value of @ref PktCrcMode.
+ * @retval None.
+ */
+void SpiritPktCommonSetCrcMode(PktCrcMode xCrcMode)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_CRC_MODE(xCrcMode));
+
+  /* Reads the PCKTCTRL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build data to write setting the CRC mode */
+  tempRegValue &= ~PCKTCTRL1_CRC_MODE_MASK;
+  tempRegValue |= (uint8_t)xCrcMode;
+
+  /* Writes the new value on the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the CRC mode for SPIRIT packets.
+ * @param  None.
+ * @retval PktCrcMode Crc mode.
+ */
+PktCrcMode SpiritPktCommonGetCrcMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return value */
+  return (PktCrcMode)(tempRegValue & 0xE0);
+
+}
+
+
+/**
+ * @brief  Enables or Disables WHITENING for SPIRIT packets.
+ * @param  xNewState new state for WHITENING mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonWhitening(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PCKTCTRL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build data to write: set or reset the whitening enable bit */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKTCTRL1_WHIT_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKTCTRL1_WHIT_MASK;
+  }
+
+  /* Writes the new value on the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables or Disables FEC for SPIRIT packets.
+ * @param  xNewState new state for FEC mode.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonFec(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PCKTCTRL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build data to write: set or reset the FEC enable bit */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKTCTRL1_FEC_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKTCTRL1_FEC_MASK;
+  }
+
+  /* Writes data on the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets a specific SYNC word for SPIRIT packets.
+ * @param  xSyncX SYNC word number to be set.
+ *         This parameter can be any value of @ref PktSyncX.
+ * @param  cSyncWord SYNC word.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetSyncxWord(PktSyncX xSyncX ,  uint8_t cSyncWord)
+{
+  uint8_t tempRegAddress;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_SYNCx(xSyncX));
+
+  /* Set the specified address */
+  switch(xSyncX)
+  {
+    case PKT_SYNC_WORD_1:
+      tempRegAddress=SYNC1_BASE;
+      break;
+    case PKT_SYNC_WORD_2:
+      tempRegAddress=SYNC2_BASE;
+      break;
+    case PKT_SYNC_WORD_3:
+      tempRegAddress=SYNC3_BASE;
+      break;
+    default:
+      tempRegAddress=SYNC4_BASE;
+      break;
+  }
+
+  /* Writes value on the selected register */
+  g_xStatus = SpiritSpiWriteRegisters(tempRegAddress, 1, &cSyncWord);
+
+}
+
+
+/**
+ * @brief  Returns a specific SYNC word for SPIRIT packets.
+ * @param  xSyncX SYNC word number to be get.
+ *         This parameter can be any value of @ref PktSyncX.
+ * @retval uint8_t Sync word x.
+ */
+uint8_t SpiritPktCommonGetSyncxWord(PktSyncX xSyncX)
+{
+  uint8_t tempRegAddress, tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_SYNCx(xSyncX));
+
+  /* Set the specified address */
+  switch(xSyncX)
+  {
+    case PKT_SYNC_WORD_1:
+      tempRegAddress=SYNC1_BASE;
+      break;
+    case PKT_SYNC_WORD_2:
+      tempRegAddress=SYNC2_BASE;
+      break;
+    case PKT_SYNC_WORD_3:
+      tempRegAddress=SYNC3_BASE;
+      break;
+    default:
+      tempRegAddress=SYNC4_BASE;
+      break;
+  }
+
+  /* Reads the selected register value */
+  g_xStatus = SpiritSpiReadRegisters(tempRegAddress, 1, &tempRegValue);
+
+  /* Returns the read value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets multiple SYNC words for SPIRIT packets.
+ * @param  lSyncWords SYNC words to be set with format: 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ *         This parameter is a uint32_t.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a @ref PktSyncLength.
+ * @retval None.
+ */
+void SpiritPktCommonSetSyncWords(uint32_t lSyncWords, PktSyncLength xSyncLength)
+{
+  uint8_t tempRegValue[4];
+
+  /* Split the 32-bit value in 4 8-bit values */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+	if(i< ((3-xSyncLength) >>1) )
+    {
+      tempRegValue[i]=0;
+    }
+    else
+    {
+      tempRegValue[i]=(uint8_t)(lSyncWords>>(8*i));
+    }
+  }
+
+  /* Writes SYNC value on the SYNCx registers */
+  g_xStatus = SpiritSpiWriteRegisters(SYNC4_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns multiple SYNC words for SPIRIT packets.
+ * @param  xSyncLength SYNC length in bytes. The 32bit word passed will be stored in the SYNCx registers from the MSb
+ *         until the number of bytes in xSyncLength has been stored.
+ *         This parameter is a pointer to @ref PktSyncLength.
+ * @retval uint32_t Sync words. The format of the read 32 bit word is 0x|SYNC1|SYNC2|SYNC3|SYNC4|.
+ */
+uint32_t SpiritPktCommonGetSyncWords(PktSyncLength xSyncLength)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempRetValue=0;
+
+  /* Reads the SYNCx registers value */
+  g_xStatus = SpiritSpiReadRegisters(SYNC4_BASE, 4, tempRegValue);
+
+  /* Rebuild the SYNC words */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+    if(i>2-(xSyncLength >>1))
+    {
+      tempRetValue |= tempRegValue[i]<<(8*i);
+    }
+  }
+
+  /* Return SYNC words */
+  return tempRetValue;
+
+}
+
+
+/**
+ * @brief  Returns the variable length width (in number of bits).
+ * @param  None.
+ * @retval uint8_t Variable length width in bits.
+ */
+uint8_t SpiritPktCommonGetVarLengthWidth(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return value */
+  return (tempRegValue & PCKTCTRL3_LEN_WID_MASK)+1;
+
+}
+
+
+/**
+ * @brief  Sets the destination address for the Tx packet.
+ * @param  cAddress Destination address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetDestinationAddress(uint8_t cAddress)
+{
+  /* Writes value on PCKT_FLT_GOALS_SOURCE_ADDR register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_SOURCE_ADDR_BASE, 1, &cAddress);
+
+}
+
+
+/**
+ * @brief  Returns the settled destination address.
+ * @param  None.
+ * @retval uint8_t Transmitted destination address.
+ */
+uint8_t SpiritPktCommonGetTransmittedDestAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads value on the PCKT_FLT_GOALS_SOURCE_ADDR register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_SOURCE_ADDR_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the node my address. When the filtering on my address is on, if the destination address extracted from the received packet is equal to the content of the
+ *         my address, then the packet is accepted (this is the address of the node).
+ * @param  cAddress Address of the present node.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetMyAddress(uint8_t cAddress)
+{
+  /* Writes value on the PCKT_FLT_GOALS_TX_ADDR register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_TX_ADDR_BASE, 1, &cAddress);
+
+}
+
+
+/**
+ * @brief  Returns the address of the present node.
+ * @param  None.
+ * @retval uint8_t My address (address of this node).
+ */
+uint8_t SpiritPktCommonGetMyAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads value on the PCKT_FLT_GOALS_TX_ADDR register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_TX_ADDR_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the broadcast address. If the destination address extracted from the received packet is equal to the content of the
+ *         BROADCAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Broadcast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetBroadcastAddress(uint8_t cAddress)
+{
+  /* Writes value on the PCKT_FLT_GOALS_BROADCAST register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 1, &cAddress);
+
+}
+
+
+/**
+ * @brief  Returns the broadcast address.
+ * @param  None.
+ * @retval uint8_t Broadcast address.
+ */
+uint8_t SpiritPktCommonGetBroadcastAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads value on the PCKT_FLT_GOALS_BROADCAST register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the multicast address. When the multicast filtering is on, if the destination address extracted from the received packet is equal to the content of the
+ *         MULTICAST_ADDR register, then the packet is accepted.
+ * @param  cAddress Multicast address.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetMulticastAddress(uint8_t cAddress)
+{
+  /* Writes value on the PCKT_FLT_GOALS_MULTICAST register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_MULTICAST_BASE, 1, &cAddress);
+
+}
+
+
+/**
+ * @brief  Returns the multicast address.
+ * @param  None.
+ * @retval uint8_t Multicast address.
+ */
+uint8_t SpiritPktCommonGetMulticastAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads value on the PCKT_FLT_GOALS_MULTICAST register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_MULTICAST_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  lMask Control mask.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetCtrlMask(uint32_t lMask)
+{
+  uint8_t tempRegValue[4];
+
+  /* Split the 32-bit value in 4 8-bit values */
+  tempRegValue[0] = (uint8_t) lMask;
+  tempRegValue[1] = (uint8_t)(lMask >> 8);
+  tempRegValue[2] = (uint8_t)(lMask >> 16);
+  tempRegValue[3] = (uint8_t)(lMask >> 24);
+
+  /* Writes values on the CKT_FLT_GOALS_CONTROLx_MASK registers */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_CONTROL0_MASK_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the control mask. The 1 bits of the CONTROL_MASK indicate the
+ *         bits to be used in filtering. (All 0s no filtering)
+ * @param  None.
+ * @retval uint32_t Control mask.
+ */
+uint32_t SpiritPktCommonGetCtrlMask(void)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempRetValue=0;
+
+  /* Reads the PCKT_FLT_GOALS_CONTROLx_MASK registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_CONTROL0_MASK_BASE, 4, tempRegValue);
+
+  /* Rebuild the control mask value on a 32-bit integer variable */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+    tempRetValue |= ((uint32_t)tempRegValue[i])<<(8*i);
+  }
+
+  /* Return value */
+  return tempRetValue;
+}
+
+/**
+ * @brief  Sets the control field reference. If the bits enabled by the CONTROL_MASK
+ *         match the ones of the control fields extracted from the received packet
+ *         then the packet is accepted.
+ * @param  lReference Control reference.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetCtrlReference(uint32_t lReference)
+{
+  uint8_t tempRegValue[4];
+
+  /* Split the 32-bit value in 4 8-bit values */
+  tempRegValue[0] = (uint8_t) lReference;
+  tempRegValue[1] = (uint8_t)(lReference >> 8);
+  tempRegValue[2] = (uint8_t)(lReference >> 16);
+  tempRegValue[3] = (uint8_t)(lReference >> 24);
+
+  /* Writes values on the CKT_FLT_GOALS_CONTROLx_FIELD registers */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_CONTROL0_FIELD_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the control field reference.
+ * @param  None.
+ * @retval uint32_t Control reference.
+ */
+uint32_t SpiritPktCommonGetCtrlReference(void)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempRetValue=0;
+
+  /* Reads the PCKT_FLT_GOALS_CONTROLx_FIELD registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_CONTROL0_FIELD_BASE, 4, tempRegValue);
+
+  /* Rebuild the control mask value on a 32-bit integer variable */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+    tempRetValue |= ((uint32_t)tempRegValue[i])<<(8*i);
+  }
+
+  /* Return value */
+  return tempRetValue;
+}
+
+
+/**
+ * @brief  Sets the TX control field.
+ * @param  lField Tx contro field.
+ *         This parameter is an uint32_t.
+ * @retval None.
+ */
+void SpiritPktCommonSetTransmittedCtrlField(uint32_t lField)
+{
+  uint8_t tempRegValue[4];
+
+  /* Split the 32-bit value in 4 8-bit values */
+  tempRegValue[3] = (uint8_t) lField;
+  tempRegValue[2] = (uint8_t)(lField >> 8);
+  tempRegValue[1] = (uint8_t)(lField >> 16);
+  tempRegValue[0] = (uint8_t)(lField >> 24);
+
+  /* Writes value on the TX_CTRL_FIELDx register */
+  g_xStatus = SpiritSpiWriteRegisters(TX_CTRL_FIELD3_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the Tx control field.
+ * @param  None.
+ * @retval uint32_t Control field of the transmitted packet.
+ */
+uint32_t SpiritPktCommonGetTransmittedCtrlField(void)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempRetValue=0;
+
+  /* Reads the TX_CTRL_FIELDx registers */
+  g_xStatus = SpiritSpiReadRegisters(TX_CTRL_FIELD3_BASE, 4, tempRegValue);
+
+  /* Rebuild value: build a 32-bit value from the read bytes */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+    tempRetValue |= ((uint32_t)tempRegValue[i])<<(8*(3-i));
+  }
+
+  /* Return value */
+  return tempRetValue;
+
+}
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with My address.
+ * @param  xNewState new state for DEST_VS_SOURCE_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonFilterOnMyAddress(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+   /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+
+  /* Modify the register value: set or reset the TX source address control */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Set or reset the DESTINATION vs TX enabling bit */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with multicast address.
+ * @param  xNewState new state for DEST_VS_MULTICAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonFilterOnMulticastAddress(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PCKT_FLT_OPTIONS register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Enable or disable the filtering option */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  If enabled RX packet is accepted if its destination address matches with broadcast address.
+ * @param  xNewState new state for DEST_VS_BROADCAST_ADDRESS.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonFilterOnBroadcastAddress(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Enable or disable the filtering option */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the enable bit of the my address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+SpiritFunctionalState SpiritPktCommonGetFilterOnMyAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Gets the enable/disable bit in form of SpiritFunctionalState type */
+  if(tempRegValue & 0x08)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+/**
+ * @brief  Returns the enable bit of the multicast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+SpiritFunctionalState SpiritPktCommonGetFilterOnMulticastAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Get the enable/disable bit in form of SpiritFunctionalState type */
+  if(tempRegValue & 0x04)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+/**
+ * @brief  Returns the enable bit of the broadcast address filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+SpiritFunctionalState SpiritPktCommonGetFilterOnBroadcastAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Get the enable/disable bit in form of SpiritFunctionalState type */
+  if(tempRegValue & 0x02)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+
+/**
+ * @brief  Returns the destination address of the received packet.
+ * @param  None.
+ * @retval uint8_t Destination address of the received address.
+ */
+uint8_t SpiritPktCommonGetReceivedDestAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RX_ADDR_FIELD0 register value */
+  g_xStatus = SpiritSpiReadRegisters(RX_ADDR_FIELD0_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Returns the control field of the received packet.
+ * @param  None.
+ * @retval uint32_t Received control field.
+ */
+uint32_t SpiritPktCommonGetReceivedCtrlField(void)
+{
+  uint8_t tempRegValue[4];
+  uint32_t tempRetValue=0;
+
+  /* Reads the PCKT_FLT_GOALS_CONTROLx_MASK registers */
+  g_xStatus = SpiritSpiReadRegisters(RX_CTRL_FIELD0_BASE, 4, tempRegValue);
+
+  /* Rebuild the control mask value on a 32-bit integer variable */
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+    tempRetValue |= ((uint32_t)tempRegValue[i])<<(8*i);
+  }
+
+  /* Returns value */
+  return tempRetValue;
+}
+
+
+/**
+ * @brief  Returns the CRC field of the received packet.
+ * @param  cCrcFieldVect array in which the CRC field has to be stored.
+ *         This parameter is an uint8_t array of 3 elements.
+ * @retval None.
+ */
+void SpiritPktCommonGetReceivedCrcField(uint8_t* cCrcFieldVect)
+{
+  uint8_t tempRegValue[3],crcLength;
+  PktCrcMode crcMode;
+  
+  /* Gets the CRC mode in PktCrcMode enum */
+  crcMode=SpiritPktCommonGetCrcMode();
+  
+  /* Cast to uint8_t */
+  crcLength = (uint8_t)crcMode;
+  
+  /* Obtains the real length: see the @ref PktCrcMode enumeration */
+  crcLength >>= 5;
+  if(crcLength>=3) crcLength--;
+  
+  /* Reads the CRC_FIELDx registers value */
+  g_xStatus = SpiritSpiReadRegisters(CRC_FIELD2_BASE, 3,tempRegValue);
+  
+  /* Sets the array to be returned */
+  for(uint8_t i=0 ; i<3 ; i++)
+  {
+    if(i<crcLength) 
+    {
+      cCrcFieldVect[i]=tempRegValue[2-i];
+    }
+    else 
+    {
+      cCrcFieldVect[i]=0;
+    }
+  }
+  
+}
+
+
+/**
+ * @brief  Sets the AUTO ACKNOLEDGEMENT mechanism on the receiver. When the feature is enabled and
+ *         a data packet has been correctly received, then an acknowledgement packet is sent back to the originator of the received
+ *         packet. If the PIGGYBACKING bit is also set, payload data will be read from the FIFO; otherwise an empty packet is sent
+ *         only containing the source and destination addresses and the sequence number of the packet being acknowledged.
+ * @param  xAutoAck new state for autoack.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @param  xPiggybacking new state for autoack.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonAutoAck(SpiritFunctionalState xAutoAck , SpiritFunctionalState xPiggybacking)
+{
+  uint8_t tempRegValue[2];
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xAutoAck));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xPiggybacking));
+  /* Check if piggybacking is enabled and autoack is disabled */
+  s_assert_param(!(xPiggybacking==S_ENABLE && xAutoAck==S_DISABLE));
+
+  /* Reads the PROTOCOL[1:0] registers value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 2, tempRegValue);
+
+  /* Sets the specified LLP option */
+  /* Autoack setting */
+  if(xAutoAck == S_ENABLE)
+  {
+    tempRegValue[1] |= PROTOCOL0_AUTO_ACK_MASK;
+  }
+  else
+  {
+    tempRegValue[1] &= (~PROTOCOL0_AUTO_ACK_MASK);
+  }
+
+  /* Piggybacking setting */
+  if(xPiggybacking == S_ENABLE)
+  {
+    tempRegValue[0] |= PROTOCOL1_PIGGYBACKING_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= (~PROTOCOL1_PIGGYBACKING_MASK);
+  }
+
+  /* Writes data on the PROTOCOL[1:0] registers */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the AUTO ACKNOLEDGEMENT mechanism on the transmitter. On the transmitter side, the NACK_TX field can be used to require or not an acknowledgment for each individual packet: if
+ *         NACK_TX is set to "1" then acknowledgment will not be required; if NACK_TX is set to "0" then acknowledgment will be
+ *         required.
+ * @param  xNewState new state for TX_AUTOACK.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonRequireAck(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads value on the PROTOCOL0 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the ack requirement option */
+  if(xNewState == S_DISABLE)
+  {
+    tempRegValue |= PROTOCOL0_NACK_TX_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL0_NACK_TX_MASK;
+  }
+
+  /* Writes value on the PROTOCOL0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the TX sequence number to be used to start counting.
+ * @param  cSeqNumberReload new value for Tx seq number reload.
+ * @retval None.
+ */
+void SpiritPktCommonSetTransmittedSeqNumberReload(uint8_t cSeqNumberReload){
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_SEQ_NUMBER_RELOAD(cSeqNumberReload));
+
+  /* Reads value on the PROTOCOL2 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  tempRegValue &= 0xE7;
+  tempRegValue |= (cSeqNumberReload << 3);
+
+  /* Writes value on the PROTOCOL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the TX sequence number to be used to start counting.
+ * @param  cSeqNumberReload new value for Tx seq number reload.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritPktCommonSetNMaxReTx(PktNMaxReTx xNMaxReTx)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PKT_NMAX_RETX(xNMaxReTx));
+
+  /* Reads the PROTOCOL0 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+
+  /* Build the value to be written */
+  tempRegValue &= ~PROTOCOL0_NMAX_RETX_MASK;
+  tempRegValue |= xNMaxReTx;
+
+  /* Writes value on the PROTOCOL0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the max number of automatic retransmission.
+ * @param  None.
+ * @retval uint8_t Max number of retransmissions.
+ *         This parameter is an uint8_t.
+ */
+uint8_t SpiritPktCommonGetNMaxReTx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL0 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+
+  /* Build the value to be written */
+  return ((tempRegValue & PROTOCOL0_NMAX_RETX_MASK)>>4);
+
+}
+
+/**
+ * @brief  Returns the TX ACK request
+ * @param  None.
+ * @retval uint8_t Max number of retransmissions.
+ *         This parameter is an uint8_t.
+ */
+SpiritFunctionalState SpiritPktCommonGetTxAckRequest(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PROTOCOL0 register value */
+  g_xStatus = SpiritSpiReadRegisters(RX_PCKT_INFO_BASE, 1, &tempRegValue);
+
+  /* Build the value to be written */
+  return (SpiritFunctionalState)((tempRegValue & TX_PCKT_INFO_NACK_RX)>>2);
+
+}
+   
+   
+/**
+ * @brief  Returns the source address of the received packet.
+ * @param  None.
+ * @retval uint8_t Source address of the received packet.
+ */
+uint8_t SpiritPktCommonGetReceivedSourceAddress(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RX_ADDR_FIELD1 register value */
+  g_xStatus = SpiritSpiReadRegisters(RX_ADDR_FIELD1_BASE, 1, &tempRegValue);
+
+  /* Returns value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Returns the sequence number of the received packet.
+ * @param  None.
+ * @retval uint8_t Received Sequence number.
+ */
+uint8_t SpiritPktCommonGetReceivedSeqNumber(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RX_PCKT_INFO register value */
+  g_xStatus = SpiritSpiReadRegisters(RX_PCKT_INFO_BASE, 1, &tempRegValue);
+
+  /* Obtains and returns the sequence number */
+  return tempRegValue & 0x03;
+
+}
+
+
+/**
+ * @brief  Returns the Nack bit of the received packet
+ * @param  None.
+ * @retval uint8_t Value of the Nack bit.
+ */
+uint8_t SpiritPktCommonGetReceivedNackRx(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RX_PCKT_INFO register value */
+  g_xStatus = SpiritSpiReadRegisters(RX_PCKT_INFO_BASE, 1, &tempRegValue);
+
+  /* Obtains and returns the RX nack bit */
+  return (tempRegValue >> 2) & 0x01;
+
+}
+
+
+/**
+ * @brief  Returns the sequence number of the transmitted packet.
+ * @param  None.
+ * @retval uint8_t Sequence number of the transmitted packet.
+ */
+uint8_t SpiritPktCommonGetTransmittedSeqNumber(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the TX_PCKT_INFO register value */
+  g_xStatus = SpiritSpiReadRegisters(TX_PCKT_INFO_BASE, 1, &tempRegValue);
+
+  /* Obtains and returns the TX sequence number */
+  return (tempRegValue >> 4) & 0x07;
+
+}
+
+
+/**
+ * @brief  Returns the number of retransmission done on the transmitted packet.
+ * @param  None.
+ * @retval uint8_t Number of retransmissions done until now.
+ */
+uint8_t SpiritPktCommonGetNReTx(void)
+{
+  uint8_t tempRetValue;
+
+  /* Reads the TX_PCKT_INFO register value */
+  g_xStatus = SpiritSpiReadRegisters(TX_PCKT_INFO_BASE, 1, &tempRetValue);
+
+  /* Obtains and returns the number of retransmission done */
+  return (tempRetValue & 0x0F);
+
+}
+
+
+/**
+ * @brief  If enabled RX packet is accepted only if the masked control field matches the
+ *         masked control field reference (CONTROL_MASK & CONTROL_FIELD_REF == CONTROL_MASK & RX_CONTROL_FIELD).
+ * @param  xNewState new state for Control filtering enable bit.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ * @note   This filtering control is enabled by default but the control mask is by default set to 0.
+ *         As a matter of fact the user has to enable the control filtering bit after the packet initialization
+ *         because the PktInit routine disables it.
+ */
+void SpiritPktCommonFilterOnControlField(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+   /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+
+  /* Modify the register value: set or reset the control bit filtering */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Set or reset the CONTROL filtering enabling bit */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK;
+  }
+
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the enable bit of the control field filtering.
+ * @param  None.
+ * @retval SpiritFunctionalState This parameter can be S_ENABLE or S_DISABLE.
+ */
+SpiritFunctionalState SpiritPktCommonGetFilterOnControlField(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Gets the enable/disable bit in form of SpiritFunctionalState type */
+  if(tempRegValue & PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK)
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktMbus.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktMbus.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,354 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_PktMbus.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT MBUS packets.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_PktMbus.h"
+#include "SPIRIT_Radio.h"
+#include "MCU_Interface.h"
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_PktMbus
+ * @{
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_TypesDefinitions           Pkt MBUS Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_Defines                    Pkt MBUS Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_Macros                     Pkt MBUS Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_Variables                  Pkt MBUS Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_FunctionPrototypes         Pkt MBUS Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktMbus_Private_Functions                  Pkt MBUS Private Functions
+ * @{
+ */
+
+
+/**
+ * @brief  Initializes the SPIRIT MBUS packet according to the specified parameters in the PktMbusInit struct.
+ * @param  pxPktMbusInit pointer to a PktMbusInit structure that contains the configuration information for the specified SPIRIT MBUS PACKET FORMAT.
+ *         This parameter is a pointer to @ref PktMbusInit.
+ * @retval None.
+ */
+void SpiritPktMbusInit(PktMbusInit* pxPktMbusInit)
+{
+  uint8_t tempRegValue[3];
+
+  /* Check the parameters */
+  s_assert_param(IS_MBUS_SUBMODE(pxPktMbusInit->xMbusSubmode));
+
+  /* Packet format config */
+  SpiritPktMbusSetFormat();
+  SpiritPktCommonFilterOnCrc(S_DISABLE);
+  SpiritRadioCsBlanking(S_ENABLE);
+  
+  /* Preamble, postamble and submode config */
+  tempRegValue[0] = pxPktMbusInit->cPreambleLength;
+  tempRegValue[1] = pxPktMbusInit->cPostambleLength;
+  tempRegValue[2] = (uint8_t) pxPktMbusInit->xMbusSubmode;
+
+  /* Writes the new values on the MBUS_PRMBL registers */
+  g_xStatus = SpiritSpiWriteRegisters(MBUS_PRMBL_BASE, 3, tempRegValue);
+
+}
+
+/**
+ * @brief  Returns the SPIRIT MBUS packet structure according to the specified parameters in the registers.
+ * @param  pxPktMbusInit MBUS packet init structure.
+ *         This parameter is a pointer to @ref PktMbusInit.
+ * @retval None.
+ */
+void SpiritPktMbusGetInfo(PktMbusInit* pxPktMbusInit)
+{
+  uint8_t tempRegValue[3];
+
+  /* Reads the MBUS regs value */
+  g_xStatus = SpiritSpiReadRegisters(MBUS_PRMBL_BASE, 3, tempRegValue);
+
+  /* Fit the structure */
+  pxPktMbusInit->cPreambleLength = tempRegValue[0];
+  pxPktMbusInit->cPostambleLength = tempRegValue[1];
+  pxPktMbusInit->xMbusSubmode = (MbusSubmode) (tempRegValue[2]&0x0E);
+
+}
+
+
+/**
+ * @brief  Configures the MBUS packet format as the one used by SPIRIT.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritPktMbusSetFormat(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Sets format bits. Also set to 0 the direct RX mode bits */
+  tempRegValue &= 0x0F;
+  tempRegValue |= ((uint8_t)PCKTCTRL3_PCKT_FRMT_MBUS);
+
+  /* Writes value on the PCKTCTRL3 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Reads the PCKTCTRL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build the new value. Set to 0 the direct TX mode bits */
+  tempRegValue &= 0xF3;
+
+  /* Writes the value on the PCKTCTRL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Mask a reserved bit */
+  tempRegValue &= ~0x20;
+
+  /* Writes the value on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets how many chip sequence “01” shall be added in the preamble
+ *         respect to the minimum value as defined according to the specified sub-mode.
+ * @param  cPreamble the number of chip sequence.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktMbusSetPreamble(uint8_t cPreamble)
+{
+  /* Modifies the MBUS_PRMBL register value */
+  g_xStatus = SpiritSpiWriteRegisters(MBUS_PRMBL_BASE, 1, &cPreamble);
+
+}
+
+
+/**
+ * @brief  Returns how many chip sequence "01" are added in the preamble
+ *         respect to the minimum value as defined according to the specified sub-mode.
+ * @param  None.
+ * @retval uint8_t Preable in number of "01" chip sequences.
+ */
+uint8_t SpiritPktMbusGetPreamble(void)
+{
+  uint8_t tempRegValue;
+
+  /* Modifies the MBUS_PRMBL register value */
+  g_xStatus = SpiritSpiReadRegisters(MBUS_PRMBL_BASE, 1, &tempRegValue);
+
+  /* Return value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets how many chip sequence “01” will be used in postamble
+ * @param  cPostamble the number of chip sequence.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktMbusSetPostamble(uint8_t cPostamble)
+{
+  /* Modifies the MBUS_PSTMBL register value */
+  g_xStatus = SpiritSpiWriteRegisters(MBUS_PSTMBL_BASE, 1, &cPostamble);
+
+}
+
+
+/**
+ * @brief  Returns how many chip sequence "01" are used in the postamble
+ * @param  None.
+ * @retval uint8_t Postamble in number of "01" chip sequences.
+ */
+uint8_t SpiritPktMbusGetPostamble(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the MBUS_PSTMBL register */
+  g_xStatus = SpiritSpiReadRegisters(MBUS_PSTMBL_BASE, 1, &tempRegValue);
+
+  /* Returns value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the MBUS submode used.
+ * @param  xMbusSubmode the submode used.
+ *         This parameter can be any value of @ref MbusSubmode.
+ * @retval None.
+ */
+void SpiritPktMbusSetSubmode(MbusSubmode xMbusSubmode)
+{
+  /* Modifies the MBUS_CTRL register value */
+  g_xStatus = SpiritSpiWriteRegisters(MBUS_CTRL_BASE, 1, (uint8_t*)xMbusSubmode);
+
+}
+
+
+/**
+ * @brief  Returns the MBUS submode used.
+ * @param  None.
+ * @retval MbusSubmode MBUS submode.
+ */
+MbusSubmode SpiritPktMbusGetSubmode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the MBUS_CTRL register value */
+  g_xStatus = SpiritSpiReadRegisters(MBUS_CTRL_BASE, 1, &tempRegValue);
+
+  /* Returns value */
+  return (MbusSubmode) tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the payload length for SPIRIT MBUS packets.
+ * @param  nPayloadLength payload length in bytes.
+ *         This parameter is an uint16_t.
+ * @retval None.
+ */
+void SpiritPktMbusSetPayloadLength(uint16_t nPayloadLength)
+{
+  uint8_t tempRegValue[2];
+
+  /* Computes PCKTLEN0 value from nPayloadLength */
+  tempRegValue[1]=BUILD_PCKTLEN0(nPayloadLength);//(uint8_t)nPayloadLength;
+  /* Computes PCKTLEN1 value from nPayloadLength */
+  tempRegValue[0]=BUILD_PCKTLEN1(nPayloadLength);//(uint8_t)(nPayloadLength>>8);
+
+  /* Writes data on the PCKTLEN1/0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the payload length for SPIRIT MBUS packets.
+ * @param  None.
+ * @retval uint16_t Payload length in bytes.
+ */
+uint16_t SpiritPktMbusGetPayloadLength(void)
+{
+  uint8_t tempRegValue[2];
+
+  /* Reads the packet length registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+  /* Returns the packet length */
+  return ((((uint16_t)tempRegValue[0])<<8) + (uint16_t) tempRegValue[1]);
+
+}
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktStack.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_PktStack.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,687 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_PktStack.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT STack packets.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_PktStack.h"
+#include "MCU_Interface.h"
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_PktStack
+ * @{
+ */
+
+
+/**
+ * @defgroup PktStack_Private_TypesDefinitions          Pkt STack Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Private_Defines                   Pkt STack Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Private_Macros                    Pkt STack Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Private_Variables                 Pkt STack Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Private_FunctionPrototypes        Pkt STack Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup PktStack_Private_Functions                 Pkt STack Private Functions
+ * @{
+ */
+
+
+/**
+ * @brief  Initializes the SPIRIT STack packet according to the specified
+ *         parameters in the PktStackInit.
+ * @param  pxPktStackInit STack packet init structure.
+ *         This parameter is a pointer to @ref PktStackInit.
+ * @retval None.
+ */
+void SpiritPktStackInit(PktStackInit* pxPktStackInit)
+{
+  uint8_t tempRegValue[4], i;
+
+  /* Check the parameters */
+  s_assert_param(IS_STACK_PREAMBLE_LENGTH(pxPktStackInit->xPreambleLength));
+  s_assert_param(IS_STACK_SYNC_LENGTH(pxPktStackInit->xSyncLength));
+  s_assert_param(IS_STACK_CRC_MODE(pxPktStackInit->xCrcMode));
+  s_assert_param(IS_STACK_LENGTH_WIDTH_BITS(pxPktStackInit->cPktLengthWidth));
+  s_assert_param(IS_STACK_FIX_VAR_LENGTH(pxPktStackInit->xFixVarLength));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackInit->xFec));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackInit->xDataWhitening));
+  s_assert_param(IS_STACK_CONTROL_LENGTH(pxPktStackInit->xControlLength));
+
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue[0]);
+
+  /* Mask a reserved bit */
+  tempRegValue[0] &= ~0x20;
+
+  /* Always (!) set the automatic packet filtering */
+  tempRegValue[0] |= PROTOCOL1_AUTO_PCKT_FLT_MASK;
+
+  /* Writes the value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue[0]);
+
+  /* Reads the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+
+  /* Always reset the control and source filtering */
+  tempRegValue[0] &= ~(PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK | PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK);
+
+  /* Writes the value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+
+
+  /* Address and control length setting: source and destination address are always present so ADDRESS_LENGTH=2 */
+  tempRegValue[0] = 0x10 | ((uint8_t) pxPktStackInit->xControlLength);
+
+
+  /* Packet format and width length setting */
+  pxPktStackInit->cPktLengthWidth == 0 ? pxPktStackInit->cPktLengthWidth=1 : pxPktStackInit->cPktLengthWidth;
+  tempRegValue[1] = ((uint8_t) PCKTCTRL3_PCKT_FRMT_STACK) | ((uint8_t)(pxPktStackInit->cPktLengthWidth-1));
+
+  /* Preamble, sync and fixed or variable length setting */
+  tempRegValue[2] = ((uint8_t) pxPktStackInit->xPreambleLength) | ((uint8_t) pxPktStackInit->xSyncLength) |
+                    ((uint8_t) pxPktStackInit->xFixVarLength);
+
+  /* CRC length, whitening and FEC setting */
+  tempRegValue[3] = (uint8_t) pxPktStackInit->xCrcMode;
+
+  if(pxPktStackInit->xDataWhitening == S_ENABLE)
+  {
+     tempRegValue[3] |= PCKTCTRL1_WHIT_MASK;
+  }
+
+  if(pxPktStackInit->xFec == S_ENABLE)
+  {
+     tempRegValue[3] |= PCKTCTRL1_FEC_MASK;
+  }
+  
+  /* Writes registers */
+  SpiritSpiWriteRegisters(PCKTCTRL4_BASE, 4, tempRegValue);
+
+  /* Sync words setting */
+  for(i=0;i<4;i++)
+  {
+    if(i<3-(pxPktStackInit->xSyncLength >>1))
+    {
+      tempRegValue[i]=0;
+    }
+    else
+    {
+      tempRegValue[i] = (uint8_t)(pxPktStackInit->lSyncWords>>(8*i));
+    }
+  }
+
+  /* Enables or disables the CRC check */
+  if(pxPktStackInit->xCrcMode == PKT_NO_CRC)
+  {
+    SpiritPktStackFilterOnCrc(S_DISABLE);
+  }
+  else
+  {
+    SpiritPktStackFilterOnCrc(S_ENABLE);
+  }
+
+  /* Writes registers */
+  g_xStatus = SpiritSpiWriteRegisters(SYNC4_BASE, 4, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the SPIRIT STack packet structure according to the specified parameters in the registers.
+ * @param  pxPktStackInit STack packet init structure.
+ *         This parameter is a pointer to @ref PktStackInit.
+ * @retval None.
+ */
+void SpiritPktStackGetInfo(PktStackInit* pxPktStackInit)
+{
+  uint8_t tempRegValue[10];
+
+  /* Reads registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 10, tempRegValue);
+
+  /* Length width */
+  pxPktStackInit->cPktLengthWidth=(tempRegValue[1] & 0x0F)+1;
+
+  /* Control length */
+  pxPktStackInit->xControlLength=(StackControlLength)(tempRegValue[0] & 0x07);
+
+  /* CRC mode */
+  pxPktStackInit->xCrcMode=(StackCrcMode)(tempRegValue[3] & 0xE0);
+
+  /* Whitening */
+  pxPktStackInit->xDataWhitening=(SpiritFunctionalState)((tempRegValue[3] >> 4) & 0x01);
+
+  /* FEC */
+  pxPktStackInit->xFec=(SpiritFunctionalState)(tempRegValue[3] & 0x01);
+
+  /* FIX or VAR bit */
+  pxPktStackInit->xFixVarLength=(StackFixVarLength)(tempRegValue[2] & 0x01);
+
+  /* Preamble length */
+  pxPktStackInit->xPreambleLength=(StackPreambleLength)(tempRegValue[2] & 0xF8);
+
+  /* Sync length */
+  pxPktStackInit->xSyncLength=(StackSyncLength)(tempRegValue[2] & 0x06);
+
+  /* sync Words */
+  pxPktStackInit->lSyncWords=0;
+  for(uint8_t i=0 ; i<4 ; i++)
+  {
+      if(i>2-(pxPktStackInit->xSyncLength >>1))
+      {
+        pxPktStackInit->lSyncWords |= tempRegValue[i+6]<<(8*i);
+      }
+  }
+
+}
+
+
+/**
+ * @brief  Initializes the SPIRIT STack packet addresses according to the specified
+ *         parameters in the PktStackAddresses struct.
+ * @param  pxPktStackAddresses STack packet addresses init structure.
+ *         This parameter is a pointer to @ref PktStackAddressesInit .
+ * @retval None.
+ */
+void SpiritPktStackAddressesInit(PktStackAddressesInit* pxPktStackAddresses)
+{
+  uint8_t tempRegValue[3];
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMyAddress));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMulticastAddress));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnBroadcastAddress));
+  
+  /* Reads the filtering options ragister */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+  
+  /* Enables or disables filtering on my address */
+  if(pxPktStackAddresses->xFilterOnMyAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK;
+  }
+  
+  /* Enables or disables filtering on multicast address */
+  if(pxPktStackAddresses->xFilterOnMulticastAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK;
+  }
+  
+  /* Enables or disables filtering on broadcast address */
+  if(pxPktStackAddresses->xFilterOnBroadcastAddress == S_ENABLE)
+  {
+    tempRegValue[0] |= PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK;
+  }
+  
+  /* Writes value on the register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+  
+  /* Fills array with the addresses passed in the structure */
+  tempRegValue[0] = pxPktStackAddresses->cBroadcastAddress;
+  tempRegValue[1] = pxPktStackAddresses->cMulticastAddress;
+  tempRegValue[2] = pxPktStackAddresses->cMyAddress;
+  
+  /* Writes them on the addresses registers */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 3, tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the SPIRIT STack packet addresses structure according to the specified
+*         parameters in the registers.
+* @param  pxPktStackAddresses STack packet addresses init structure.
+*         This parameter is a pointer to @ref PktStackAddresses.
+* @retval None.
+*/
+void SpiritPktStackGetAddressesInfo(PktStackAddressesInit* pxPktStackAddresses)
+{
+  uint8_t tempRegValue[3];
+  
+  /* Reads values on the PCKT_FLT_GOALS registers */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_BROADCAST_BASE, 3, tempRegValue);
+  
+  /* Fit the structure with the read addresses */
+  pxPktStackAddresses->cBroadcastAddress = tempRegValue[0];
+  pxPktStackAddresses->cMulticastAddress = tempRegValue[1];
+  pxPktStackAddresses->cMyAddress = tempRegValue[2];
+  
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue[0]);
+  
+  /* Fit the structure with the read filtering bits */
+  pxPktStackAddresses->xFilterOnBroadcastAddress = (SpiritFunctionalState)((tempRegValue[0] >> 1) & 0x01);
+  pxPktStackAddresses->xFilterOnMulticastAddress = (SpiritFunctionalState)((tempRegValue[0] >> 2) & 0x01);
+  pxPktStackAddresses->xFilterOnMyAddress = (SpiritFunctionalState)((tempRegValue[0] >> 3) & 0x01);
+  
+}
+
+
+/**
+* @brief  Initializes the SPIRIT STack packet LLP options according to the specified
+*         parameters in the PktStackLlpInit struct.
+* @param  pxPktStackLlpInit STack packet LLP init structure.
+*         This parameter is a pointer to @ref PktStackLlpInit.
+* @retval None.
+*/
+void SpiritPktStackLlpInit(PktStackLlpInit* pxPktStackLlpInit)
+{
+  uint8_t tempRegValue[2];
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackLlpInit->xPiggybacking));
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(pxPktStackLlpInit->xAutoAck));
+  s_assert_param(IS_STACK_NMAX_RETX(pxPktStackLlpInit->xNMaxRetx));
+  /* check if piggybacking is enabled and autoack is disabled */
+  s_assert_param(!(pxPktStackLlpInit->xPiggybacking==S_ENABLE && pxPktStackLlpInit->xAutoAck==S_DISABLE));
+
+  /* Piggybacking mechanism setting on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 2, tempRegValue);
+  if(pxPktStackLlpInit->xPiggybacking == S_ENABLE)
+  {
+    tempRegValue[0] |= PROTOCOL1_PIGGYBACKING_MASK;
+  }
+  else
+  {
+    tempRegValue[0] &= ~PROTOCOL1_PIGGYBACKING_MASK;
+  }
+
+  /* RX and TX autoack mechanisms setting on the PROTOCOL0 register */
+  if(pxPktStackLlpInit->xAutoAck == S_ENABLE)
+  {
+    tempRegValue[1] |= PROTOCOL0_AUTO_ACK_MASK;
+  }
+  else
+  {
+    tempRegValue[1] &= ~PROTOCOL0_AUTO_ACK_MASK;
+  }
+
+  /* Max number of retransmission setting */
+  tempRegValue[1] &= ~PROTOCOL0_NMAX_RETX_MASK;
+  tempRegValue[1] |= pxPktStackLlpInit->xNMaxRetx;
+
+  /* Writes registers */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the SPIRIT STack packet LLP options according to the specified
+ *         values in the registers.
+ * @param  pxPktStackLlpInit STack packet LLP structure.
+ *         This parameter is a pointer to @ref PktStackLlpInit.
+ * @retval None.
+ */
+void SpiritPktStackLlpGetInfo(PktStackLlpInit* pxPktStackLlpInit)
+{
+  uint8_t tempRegValue[2];
+
+  /* Piggybacking mechanism setting on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 2, tempRegValue);
+
+  /* Fit the structure with the read values */
+  pxPktStackLlpInit->xPiggybacking = (SpiritFunctionalState)((tempRegValue[0] >> 6) & 0x01);
+  pxPktStackLlpInit->xAutoAck = (SpiritFunctionalState)((tempRegValue[1] >> 2) & 0x01);
+  pxPktStackLlpInit->xNMaxRetx = (StackNMaxReTx)(tempRegValue[1] & PROTOCOL0_NMAX_RETX_MASK);
+
+}
+
+
+/**
+ * @brief  Configures the STack packet format for SPIRIT.
+ * @param  None.
+ * @retval None.
+ */
+void SpiritPktStackSetFormat(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Build value to be written. Also set to 0 the direct RX mode bits */
+  tempRegValue &= 0x0F;
+  tempRegValue |= ((uint8_t)PCKTCTRL3_PCKT_FRMT_STACK);
+
+  /* Writes the value on the PCKTCTRL3 register. */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Reads the PCKTCTRL1 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Build the new value. Set to 0 the direct TX mode bits */
+  tempRegValue &= 0xF3;
+
+  /* Writes the PCKTCTRL1 value on register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL1_BASE, 1, &tempRegValue);
+
+  /* Reads the PROTOCOL1 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Mask a reserved bit */
+  tempRegValue &= ~0x20;
+
+  /* Writes the value on the PROTOCOL1 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the address length for SPIRIT STack packets (always 2).
+ * @param  None.
+ * @retval None.
+ */
+void SpiritPktStackSetAddressLength(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the PCKTCTRL4 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+  /* Build the new value */
+  tempRegValue &= ~PCKTCTRL4_ADDRESS_LEN_MASK;
+  tempRegValue |= ((uint8_t)0x10);
+
+  /* Writes the value on the PCKTCTRL4 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL4_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the payload length for SPIRIT STack packets. Since the packet length
+ *         depends from the address (always 2 for this packet format)
+ *         and the control field size, this function reads the control length register
+ *         content in order to determine the correct packet length to be written.
+ * @param  nPayloadLength payload length in bytes.
+ *         This parameter can be any value of uint16_t.
+ * @retval None.
+ */
+void SpiritPktStackSetPayloadLength(uint16_t nPayloadLength)
+{
+  uint8_t tempRegValue[2];
+
+  /* Computes the oversize (address + control) size */
+  uint16_t overSize = 2 + (uint16_t) SpiritPktStackGetControlLength();
+
+  /* Computes PCKTLEN0 value from lPayloadLength */
+  tempRegValue[1]=STACK_BUILD_PCKTLEN0(nPayloadLength+overSize);
+  /* Computes PCKTLEN1 value from lPayloadLength */
+  tempRegValue[0]=STACK_BUILD_PCKTLEN1(nPayloadLength+overSize);
+
+  /* Writes the value on the PCKTLENx registers */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the payload length for SPIRIT STack packets. Since the
+ *         packet length depends from the address and the control
+ *         field size, this function reads the correspondent
+ *         registers in order to determine the correct payload length
+ *         to be returned.
+ * @param  None.
+ * @retval uint16_t Payload length.
+ */
+uint16_t SpiritPktStackGetPayloadLength(void)
+{
+  uint8_t tempRegValue[2];
+  /* Computes the oversize (address + control) size */
+  uint16_t overSize = 2 + (uint16_t) SpiritPktStackGetControlLength();
+
+  /* Reads the PCKTLEN1 registers value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTLEN1_BASE, 2, tempRegValue);
+
+  /* Rebuild and return the payload length value */
+  return ((((uint16_t) tempRegValue[1])<<8) + (uint16_t) tempRegValue[0] - overSize);
+
+}
+
+
+/**
+ * @brief  Computes and sets the variable payload length for SPIRIT STack packets.
+ * @param  nMaxPayloadLength payload length in bytes.
+ *         This parameter is an uint16_t.
+ * @param  xControlLength control length in bytes.
+ *         This parameter can be any value of @ref StackControlLength.
+ * @retval None.
+ */
+void SpiritPktStackSetVarLengthWidth(uint16_t nMaxPayloadLength, StackControlLength xControlLength)
+{
+  uint8_t tempRegValue,
+          i;
+  uint32_t packetLength;
+
+
+  /* packet length = payload length + address length (2) + control length */
+  packetLength=nMaxPayloadLength+2+xControlLength;
+
+  /* Computes the number of bits */
+  for(i=0;i<16;i++)
+  {
+    if(packetLength == 0) 
+    {
+      break;
+    }
+    packetLength >>= 1;
+  }
+  i==0 ? i=1 : i;
+
+  /* Reads the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiReadRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+  /* Build the register value */
+  tempRegValue &= ~PCKTCTRL3_LEN_WID_MASK;
+  tempRegValue |= ((uint8_t)(i-1));
+
+  /* Writes the PCKTCTRL3 register value */
+  g_xStatus = SpiritSpiWriteRegisters(PCKTCTRL3_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Rx packet source mask. Used to mask the address of the accepted packets. If 0 -> no filtering.
+ * @param  cMask Rx source mask.
+ *         This parameter is an uint8_t.
+ * @retval None.
+ */
+void SpiritPktStackSetRxSourceMask(uint8_t cMask)
+{
+  /* Writes value on the register PCKT_FLT_GOALS_SOURCE_MASK */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_GOALS_SOURCE_MASK_BASE, 1, &cMask);
+
+}
+
+
+/**
+ * @brief  Returns the Rx packet source mask. Used to mask the address of the accepted packets. If 0 -> no filtering.
+ * @param  None.
+ * @retval uint8_t Rx source mask.
+ */
+uint8_t SpiritPktStackGetRxSourceMask(void)
+{
+  uint8_t tempRegValue;
+
+  /* Writes value on the PCKT_FLT_GOALS_SOURCE_MASK register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_GOALS_SOURCE_MASK_BASE, 1, &tempRegValue);
+
+  /* Return the read value */
+  return tempRegValue;
+
+}
+
+/**
+ * @brief  Returns the packet length field of the received packet.
+ * @param  None.
+ * @retval uint16_t Packet length.
+ */
+uint16_t SpiritPktStackGetReceivedPktLength(void)
+{
+  uint8_t tempRegValue[2];
+  uint16_t tempLength;
+  
+  /* Reads the RX_PCKT_LENx registers value */
+  g_xStatus = SpiritSpiReadRegisters(RX_PCKT_LEN1_BASE, 2, tempRegValue);
+
+  /* Rebuild and return the the length field */
+  tempLength = ((((uint16_t) tempRegValue[0]) << 8) + (uint16_t) tempRegValue[1]);
+  
+  /* Computes the oversize (address + control) size */
+  tempLength -= 2 + (uint16_t) SpiritPktStackGetControlLength();
+  
+  return tempLength;
+
+}
+
+
+/**
+ * @brief  If enabled RX packet is accepted only if the masked source address field matches the
+ *         masked source address field reference (SOURCE_MASK & SOURCE_FIELD_REF == SOURCE_MASK & RX_SOURCE_FIELD).
+ * @param  xNewState new state for Source address filtering enable bit.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ * @note   This filtering control is enabled by default but the source address mask is by default set to 0.
+ *         As a matter of fact the user has to enable the source filtering bit after the packet initialization
+ *         because the PktInit routine disables it.
+ */
+void SpiritPktStackFilterOnSourceAddress(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+   /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+
+  /* Modify the register value: set or reset the source bit filtering */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+  /* Set or reset the SOURCE ADDRESS filtering enabling bit */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK;
+  }
+
+  /* Writes the new value on the PCKT_FLT_OPTIONS register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 1, &tempRegValue);
+
+}
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Qi.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Qi.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,636 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Qi.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT QI.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Qi.h"
+#include "MCU_Interface.h"
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Qi
+ * @{
+ */
+
+
+/**
+ * @defgroup Qi_Private_TypesDefinitions        QI Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Private_Defines                 QI Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Private_Macros                  QI Private Macros
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Private_Variables               QI Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Private_FunctionPrototypes      QI Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Qi_Private_Functions               QI Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Enables/Disables the PQI Preamble Quality Indicator check. The running peak PQI is
+ *         compared to a threshold value and the preamble valid IRQ is asserted as soon as the threshold is passed.
+ * @param  xNewState new state for PQI check.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritQiPqiCheck(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the PQI Check bit on the QI_BASE register */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= QI_PQI_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~QI_PQI_MASK;
+  }
+
+  /* Writes value on the QI register */
+  g_xStatus = SpiritSpiWriteRegisters(QI_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables/Disables the Synchronization Quality Indicator check. The running peak SQI is
+ *         compared to a threshold value and the sync valid IRQ is asserted as soon as the threshold is passed.
+ * @param  xNewState new state for SQI check.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritQiSqiCheck(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the SQI Check bit on the QI_BASE register */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= QI_SQI_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~QI_SQI_MASK;
+  }
+
+  /* Writes value on the QI register */
+  g_xStatus = SpiritSpiWriteRegisters(QI_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the PQI threshold. The preamble quality threshold is 4*PQI_TH (PQI_TH = 0..15).
+ * @param  xPqiThr parameter of the formula above.
+ * 	   This variable is a @ref PqiThreshold.
+ * @retval None.
+ */
+void SpiritQiSetPqiThreshold(PqiThreshold xPqiThr)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_PQI_THR(xPqiThr));
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Build the PQI threshold value to be written */
+  tempRegValue &= 0xC3;
+  tempRegValue |= ((uint8_t)xPqiThr);
+
+  /* Writes value on the QI register */
+  g_xStatus = SpiritSpiWriteRegisters(QI_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the PQI threshold. The preamble quality threshold is 4*PQI_TH (PQI_TH = 0..15).
+ * @param  None.
+ * @retval PqiThreshold PQI threshold (PQI_TH of the formula above).
+ */
+PqiThreshold SpiritQiGetPqiThreshold(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return the PQI threshold value */
+  return (PqiThreshold)(tempRegValue & 0x3C);
+
+}
+
+
+/**
+ * @brief  Sets the SQI threshold. The synchronization quality
+ *         threshold is equal to 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3. When SQI_TH is 0 perfect match is required; when
+ *         SQI_TH = 1, 2, 3 then 1, 2, or 3 bit errors are respectively accepted. It is recommended that the SQI check is always
+ *         enabled.
+ * @param  xSqiThr parameter of the formula above.
+ * 	   This parameter is a @ref SqiThreshold.
+ * @retval None.
+ */
+void SpiritQiSetSqiThreshold(SqiThreshold xSqiThr)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SQI_THR(xSqiThr));
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Build the SQI threshold value to be written */
+  tempRegValue &= 0x3F;
+  tempRegValue |= ((uint8_t)xSqiThr);
+
+  /* Writes the new value on the QI register */
+  g_xStatus = SpiritSpiWriteRegisters(QI_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the SQI threshold. The synchronization quality threshold is equal to 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3.
+ * @param  None.
+ * @retval SqiThreshold SQI threshold (SQI_TH of the formula above).
+ */
+SqiThreshold SpiritQiGetSqiThreshold(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the QI register value */
+  g_xStatus = SpiritSpiReadRegisters(QI_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return the SQI threshold value */
+  return (SqiThreshold)(tempRegValue & 0xC0);
+
+}
+
+
+/**
+ * @brief  Returns the PQI value.
+ * @param  None.
+ * @retval uint8_t PQI value.
+ */
+uint8_t SpiritQiGetPqi(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the LINK_QUALIF2 register value */
+  g_xStatus = SpiritSpiReadRegisters(LINK_QUALIF2_BASE, 1, &tempRegValue);
+
+  /* Returns the PQI value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Returns the SQI value.
+ * @param  None.
+ * @retval uint8_t SQI value.
+ */
+uint8_t SpiritQiGetSqi(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register LINK_QUALIF1 value */
+  g_xStatus = SpiritSpiReadRegisters(LINK_QUALIF1_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return the SQI value */
+  return (tempRegValue & 0x7F);
+
+}
+
+
+/**
+ * @brief  Returns the LQI value.
+ * @param  None.
+ * @retval uint8_t LQI value.
+ */
+uint8_t SpiritQiGetLqi(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the LINK_QUALIF0 register value */
+  g_xStatus = SpiritSpiReadRegisters(LINK_QUALIF0_BASE, 1, &tempRegValue);
+
+  /* Rebuild and return the LQI value */
+  return ((tempRegValue & 0xF0)>> 4);
+
+}
+
+
+/**
+ * @brief  Returns the CS status.
+ * @param  None.
+ * @retval SpiritFlagStatus CS value (S_SET or S_RESET).
+ */
+SpiritFlagStatus SpiritQiGetCs(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the LINK_QUALIF1 register value */
+  g_xStatus = SpiritSpiReadRegisters(LINK_QUALIF1_BASE, 1, &tempRegValue);
+
+  /* Rebuild and returns the CS status value */
+  if((tempRegValue & 0x80) == 0)
+  {
+    return S_RESET;
+  }
+  else
+  {
+    return S_SET;
+  }
+
+}
+
+
+/**
+ * @brief  Returns the RSSI value. The measured power is reported in steps of half a dB from 0 to 255 and is offset in such a way that -120 dBm corresponds
+ *         to 20.
+ * @param  None.
+ * @retval uint8_t RSSI value.
+ */
+uint8_t SpiritQiGetRssi(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RSSI_LEVEL register value */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_LEVEL_BASE, 1, &tempRegValue);
+
+  /* Returns the RSSI value */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Sets the RSSI threshold.
+ * @param  cRssiThr RSSI threshold reported in steps of half a dBm with a -130 dBm offset.
+ *         This parameter must be a uint8_t.
+ * @retval None.
+ */
+void SpiritQiSetRssiThreshold(uint8_t cRssiThr)
+{
+  /* Writes the new value on the RSSI_TH register */
+  g_xStatus = SpiritSpiWriteRegisters(RSSI_TH_BASE, 1, &cRssiThr);
+
+}
+
+
+/**
+ * @brief  Returns the RSSI threshold.
+ * @param  None.
+ * @retval uint8_t RSSI threshold.
+ */
+uint8_t SpiritQiGetRssiThreshold(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RSSI_TH register value */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_TH_BASE, 1, &tempRegValue);
+
+  /* Returns RSSI threshold */
+  return tempRegValue;
+
+}
+
+
+/**
+ * @brief  Computes the RSSI threshold from its dBm value according to the formula: (RSSI[Dbm] + 130)/0.5
+ * @param  nDbmValue RSSI threshold reported in dBm.
+ *         This parameter must be a sint16_t.
+ * @retval uint8_t RSSI threshold corresponding to dBm value.
+ */
+uint8_t SpiritQiComputeRssiThreshold(int nDbmValue)
+{
+  /* Check the parameters */
+  s_assert_param(IS_RSSI_THR_DBM(nDbmValue));
+
+  /* Computes the RSSI threshold for register */
+  return 2*(nDbmValue+130);
+
+}
+
+/**
+ * @brief  Sets the RSSI threshold from its dBm value according to the formula: (RSSI[Dbm] + 130)/0.5.
+ * @param  nDbmValue RSSI threshold reported in dBm.
+ *         This parameter must be a sint16_t.
+ * @retval None.
+ */
+void SpiritQiSetRssiThresholddBm(int nDbmValue)
+{
+  uint8_t tempRegValue=2*(nDbmValue+130);
+
+  /* Check the parameters */
+  s_assert_param(IS_RSSI_THR_DBM(nDbmValue));
+
+  /* Writes the new value on the RSSI_TH register */
+  g_xStatus = SpiritSpiWriteRegisters(RSSI_TH_BASE, 1, &tempRegValue);
+
+}
+
+/**
+ * @brief  Sets the RSSI filter gain. This parameter sets the bandwidth of a low pass IIR filter (RSSI_FLT register, allowed values 0..15), a
+ *         lower values gives a faster settling of the measurements but lower precision. The recommended value for such parameter is 14.
+ * @param  xRssiFg RSSI filter gain value.
+ *         This parameter can be any value of @ref RssiFilterGain.
+ * @retval None.
+ */
+void SpiritQiSetRssiFilterGain(RssiFilterGain xRssiFg)
+{
+  uint8_t tempRegValue;
+
+   /* Check the parameters */
+  s_assert_param(IS_RSSI_FILTER_GAIN(xRssiFg));
+
+  /* Reads the RSSI_FLT register */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+  /* Sets the specified filter gain */
+  tempRegValue &= 0x0F;
+  tempRegValue |= ((uint8_t)xRssiFg);
+
+  /* Writes the new value on the RSSI_FLT register */
+  g_xStatus = SpiritSpiWriteRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the RSSI filter gain.
+ * @param  None.
+ * @retval RssiFilterGain RSSI filter gain.
+ */
+RssiFilterGain SpiritQiGetRssiFilterGain(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RSSI_FLT register */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+  /* Rebuild and returns the filter gain value */
+  return (RssiFilterGain)(tempRegValue & 0xF0);
+
+}
+
+
+/**
+ * @brief  Sets the CS Mode. When static carrier sensing is used (cs_mode = 0), the carrier sense signal is asserted when the measured RSSI is above the
+ *         value specified in the RSSI_TH register and is deasserted when the RSSI falls 3 dB below the same threshold.
+ *         When dynamic carrier sense is used (cs_mode = 1, 2, 3), the carrier sense signal is asserted if the signal is above the
+ *         threshold and a fast power increase of 6, 12 or 18 dB is detected; it is deasserted if a power fall of the same amplitude is
+ *         detected.
+ * @param  xCsMode CS mode selector.
+ *         This parameter can be any value of @ref CSMode.
+ * @retval None.
+ */
+void SpiritQiSetCsMode(CSMode xCsMode)
+{
+  uint8_t tempRegValue;
+
+   /* Check the parameters */
+  s_assert_param(IS_CS_MODE(xCsMode));
+
+  /* Reads the RSSI_FLT register */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+  /* Sets bit to select the CS mode */
+  tempRegValue &= ~0x0C;
+  tempRegValue |= ((uint8_t)xCsMode);
+
+  /* Writes the new value on the RSSI_FLT register */
+  g_xStatus = SpiritSpiWriteRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the CS Mode.
+ * @param  None.
+ * @retval CSMode CS mode.
+ */
+CSMode SpiritQiGetCsMode(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the RSSI_FLT register */
+  g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+
+  /* Rebuild and returns the CS mode value */
+  return (CSMode)(tempRegValue & 0x0C);
+
+}
+
+/**
+ * @brief  Enables/Disables the CS Timeout Mask. If enabled CS value contributes to timeout disabling.
+ * @param  xNewState new state for CS Timeout Mask.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritQiCsTimeoutMask(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL2 register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the CS timeout mask */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL2_CS_TIMEOUT_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL2_CS_TIMEOUT_MASK;
+  }
+
+  /* Writes the new value on the PROTOCOL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables/Disables the PQI Timeout Mask. If enabled PQI value contributes to timeout disabling.
+ * @param  xNewState new state for PQI Timeout Mask.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritQiPqiTimeoutMask(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL2 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the PQI timeout mask */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL2_PQI_TIMEOUT_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL2_PQI_TIMEOUT_MASK;
+  }
+
+  /* Writes the new value on the PROTOCOL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables/Disables the SQI Timeout Mask. If enabled SQI value contributes to timeout disabling.
+ * @param  xNewState new state for SQI Timeout Mask.
+ *         This parameter can be S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritQiSqiTimeoutMask(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+
+  /* Reads the PROTOCOL2 register */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  /* Enables or disables the SQI timeout mask */
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL2_SQI_TIMEOUT_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL2_SQI_TIMEOUT_MASK;
+  }
+
+  /* Writes the new value on the PROTOCOL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ *@}
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Radio.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Radio.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,3144 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Radio.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   This file provides all the low level API to manage Analog and Digital
+  *          radio part of SPIRIT.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Radio.h"
+#include "MCU_Interface.h"
+#include <math.h>
+
+/** @addtogroup SPIRIT_Libraries
+* @{
+*/
+
+
+/** @addtogroup SPIRIT_Radio
+* @{
+*/
+
+
+/** @defgroup Radio_Private_TypesDefinitions            Radio Private Types Definitions
+* @{
+*/
+
+
+/**
+* @}
+*/
+
+
+/** @defgroup Radio_Private_Defines                     Radio Private Defines
+* @{
+*/
+
+
+
+
+/**
+* @}
+*/
+
+
+/** @defgroup Radio_Private_Macros                      Radio Private Macros
+* @{
+*/
+#define XTAL_FLAG(xtalFrequency)               (xtalFrequency>=25e6) ? XTAL_FLAG_26_MHz:XTAL_FLAG_24_MHz
+
+#define ROUND(A)                                  (((A-(uint32_t)A)> 0.5)? (uint32_t)A+1:(uint32_t)A)
+/**
+* @}
+*/
+
+
+/** @defgroup Radio_Private_Variables                   Radio Private Variables
+* @{
+*/
+/**
+* @brief  The Xtal frequency. To be set by the user (see SetXtalFreq() function)
+*/
+static uint32_t s_lXtalFrequency;
+
+/**
+* @brief  Factor is: B/2 used in the formula for SYNTH word calculation
+*/
+static const uint8_t s_vectcBHalfFactor[4]={(HIGH_BAND_FACTOR/2), (MIDDLE_BAND_FACTOR/2), (LOW_BAND_FACTOR/2), (VERY_LOW_BAND_FACTOR/2)};
+
+/**
+* @brief  BS value to write in the SYNT0 register according to the selected band
+*/
+static const uint8_t s_vectcBandRegValue[4]={SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32};
+
+
+/**
+* @brief  It represents the available channel bandwidth times 10 for 26 Mhz xtal.
+* @note   The channel bandwidth for others xtal frequencies can be computed since this table
+*         multiplying the current table by a factor xtal_frequency/26e6.
+*/
+static const uint16_t s_vectnBandwidth26M[90]=
+{
+  8001, 7951, 7684, 7368, 7051, 6709, 6423, 5867, 5414, \
+    4509, 4259, 4032, 3808, 3621, 3417, 3254, 2945, 2703, \
+      2247, 2124, 2015, 1900, 1807, 1706, 1624, 1471, 1350, \
+        1123, 1062, 1005,  950,  903,  853,  812,  735,  675, \
+          561,  530,  502,  474,  451,  426,  406,  367,  337, \
+            280,  265,  251,  237,  226,  213,  203,  184,  169, \
+              140,  133,  126,  119,  113,  106,  101,   92,   84, \
+                70,   66,   63,   59,   56,   53,   51,   46,   42, \
+                  35,   33,   31,   30,   28,   27,   25,   23,   21, \
+                    18,   17,   16,   15,   14,   13,   13,   12,   11
+};
+
+/**
+* @brief  It represents the available VCO frequencies
+*/
+static const uint16_t s_vectnVCOFreq[16]=
+{
+  4644, 4708, 4772, 4836, 4902, 4966, 5030, 5095, \
+    5161, 5232, 5303, 5375, 5448, 5519, 5592, 5663
+};
+
+/**
+* @brief  This variable is used to enable or disable
+*  the VCO calibration WA called at the end of the SpiritRadioSetFrequencyBase fcn.
+*  Default is enabled.
+*/
+static SpiritFunctionalState xDoVcoCalibrationWA=S_ENABLE;
+
+
+/**
+* @brief  These values are used to interpolate the power curves.
+*         Interpolation curves are linear in the following 3 regions:
+*       - reg value: 1 to 13    (up region)
+*       - reg value: 13 to 40   (mid region)
+*       - reg value: 41 to 90   (low region)
+*       power_reg = m*power_dBm + q
+*       For each band the order is: {m-up, q-up, m-mid, q-mid, m-low, q-low}.
+* @note The power interpolation curves have been extracted
+*       by measurements done on the divisional evaluation boards.
+*/
+static const float fPowerFactors[5][6]={ 
+  {-2.11,25.66,-2.11,25.66,-2.00,31.28},   /* 915 */
+  {-2.04,23.45,-2.04,23.45,-1.95,27.66},   /* 868 */
+  {-3.48,38.45,-1.89,27.66,-1.92,30.23},   /* 433 */
+  {-3.27,35.43,-1.80,26.31,-1.89,29.61},   /* 315 */
+  {-4.18,50.66,-1.80,30.04,-1.86,32.22},   /* 169 */
+};
+
+/**
+* @}
+*/
+
+
+/** @defgroup Radio_Private_FunctionPrototypes          Radio Private Function Prototypes
+* @{
+*/
+
+
+/**
+* @}
+*/
+
+
+/** @defgroup Radio_Private_Functions                    Radio Private Functions
+* @{
+*/
+
+/**
+* @brief  Initializes the SPIRIT analog and digital radio part according to the specified
+*         parameters in the pxSRadioInitStruct.
+* @param  pxSRadioInitStruct pointer to a SRadioInit structure that
+*         contains the configuration information for the analog radio part of SPIRIT.
+* @retval Error code: 0=no error, 1=error during calibration of VCO.
+*/
+uint8_t SpiritRadioInit(SRadioInit* pxSRadioInitStruct)
+{
+  int32_t FOffsetTmp;
+  uint8_t anaRadioRegArray[8], digRadioRegArray[4];
+  int16_t xtalOffsetFactor;
+  uint8_t drM, drE, FdevM, FdevE, bwM, bwE;
+    
+  /* Workaround for Vtune */
+  uint8_t value = 0xA0; SpiritSpiWriteRegisters(0x9F, 1, &value);
+  
+  /* Calculates the offset respect to RF frequency and according to xtal_ppm parameter: (xtal_ppm*FBase)/10^6 */
+  FOffsetTmp = (int32_t)(((float)pxSRadioInitStruct->nXtalOffsetPpm*pxSRadioInitStruct->lFrequencyBase)/PPM_FACTOR);
+  
+  /* Check the parameters */
+  s_assert_param(IS_FREQUENCY_BAND(pxSRadioInitStruct->lFrequencyBase));
+  s_assert_param(IS_MODULATION_SELECTED(pxSRadioInitStruct->xModulationSelect));
+  s_assert_param(IS_DATARATE(pxSRadioInitStruct->lDatarate));
+  s_assert_param(IS_FREQUENCY_OFFSET(FOffsetTmp,s_lXtalFrequency));
+  s_assert_param(IS_CHANNEL_SPACE(pxSRadioInitStruct->nChannelSpace,s_lXtalFrequency));
+  s_assert_param(IS_F_DEV(pxSRadioInitStruct->lFreqDev,s_lXtalFrequency));
+  
+  /* Disable the digital, ADC, SMPS reference clock divider if fXO>24MHz or fXO<26MHz */
+  SpiritSpiCommandStrobes(COMMAND_STANDBY);    
+  do{
+    /* Delay for state transition */
+    for(volatile uint8_t i=0; i!=0xFF; i++);
+    
+    /* Reads the MC_STATUS register */
+    SpiritRefreshStatus();
+  }while(g_xStatus.MC_STATE!=MC_STATE_STANDBY);
+  
+  if(s_lXtalFrequency<DOUBLE_XTAL_THR)
+  {
+    SpiritRadioSetDigDiv(S_DISABLE);
+    s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth,s_lXtalFrequency));
+  }
+  else
+  {      
+    SpiritRadioSetDigDiv(S_ENABLE);
+    s_assert_param(IS_CH_BW(pxSRadioInitStruct->lBandwidth,(s_lXtalFrequency>>1)));
+  }
+  
+  /* Goes in READY state */
+  SpiritSpiCommandStrobes(COMMAND_READY);
+  do{
+    /* Delay for state transition */
+    for(volatile uint8_t i=0; i!=0xFF; i++);
+    
+    /* Reads the MC_STATUS register */
+    SpiritRefreshStatus();
+  }while(g_xStatus.MC_STATE!=MC_STATE_READY);
+  
+  /* Calculates the FC_OFFSET parameter and cast as signed int: FOffsetTmp = (Fxtal/2^18)*FC_OFFSET */
+  xtalOffsetFactor = (int16_t)(((float)FOffsetTmp*FBASE_DIVIDER)/s_lXtalFrequency);
+  anaRadioRegArray[2] = (uint8_t)((((uint16_t)xtalOffsetFactor)>>8)&0x0F);
+  anaRadioRegArray[3] = (uint8_t)(xtalOffsetFactor);
+  
+  /* Calculates the channel space factor */
+  anaRadioRegArray[0] =((uint32_t)pxSRadioInitStruct->nChannelSpace<<9)/(s_lXtalFrequency>>6)+1;
+  
+  SpiritManagementWaTRxFcMem(pxSRadioInitStruct->lFrequencyBase);
+  
+  /* 2nd order DEM algorithm enabling */
+  uint8_t tmpreg; SpiritSpiReadRegisters(0xA3, 1, &tmpreg);
+  tmpreg &= ~0x02; SpiritSpiWriteRegisters(0xA3, 1, &tmpreg);
+  
+  /* Check the channel center frequency is in one of the possible range */
+  s_assert_param(IS_FREQUENCY_BAND((pxSRadioInitStruct->lFrequencyBase + ((xtalOffsetFactor*s_lXtalFrequency)/FBASE_DIVIDER) + pxSRadioInitStruct->nChannelSpace * pxSRadioInitStruct->cChannelNumber)));  
+  
+  /* Calculates the datarate mantissa and exponent */
+  SpiritRadioSearchDatarateME(pxSRadioInitStruct->lDatarate, &drM, &drE);
+  digRadioRegArray[0] = (uint8_t)(drM);
+  digRadioRegArray[1] = (uint8_t)(0x00 | pxSRadioInitStruct->xModulationSelect |drE);
+  
+  /* Read the fdev register to preserve the clock recovery algo bit */
+  SpiritSpiReadRegisters(0x1C, 1, &tmpreg);
+  
+  /* Calculates the frequency deviation mantissa and exponent */
+  SpiritRadioSearchFreqDevME(pxSRadioInitStruct->lFreqDev, &FdevM, &FdevE);
+  digRadioRegArray[2] = (uint8_t)((FdevE<<4) | (tmpreg&0x08) | FdevM);
+  
+  /* Calculates the channel filter mantissa and exponent */
+  SpiritRadioSearchChannelBwME(pxSRadioInitStruct->lBandwidth, &bwM, &bwE);
+  
+  digRadioRegArray[3] = (uint8_t)((bwM<<4) | bwE);
+ 
+  float if_off=(3.0*480140)/(s_lXtalFrequency>>12)-64;
+  
+  uint8_t ifOffsetAna = ROUND(if_off);
+  
+  if(s_lXtalFrequency<DOUBLE_XTAL_THR)
+  {
+    /* if offset digital is the same in case of single xtal */
+    anaRadioRegArray[1] = ifOffsetAna;
+  }
+  else
+  {
+    if_off=(3.0*480140)/(s_lXtalFrequency>>13)-64;
+    
+    /* ... otherwise recompute it */
+    anaRadioRegArray[1] = ROUND(if_off);
+  }
+//  if(s_lXtalFrequency==24000000) {
+//    ifOffsetAna = 0xB6;
+//    anaRadioRegArray[1] = 0xB6;
+//  }
+//  if(s_lXtalFrequency==25000000) {
+//    ifOffsetAna = 0xAC;
+//    anaRadioRegArray[1] = 0xAC;
+//  }
+//  if(s_lXtalFrequency==26000000) {
+//    ifOffsetAna = 0xA3;
+//    anaRadioRegArray[1] = 0xA3;
+//  }
+//  if(s_lXtalFrequency==48000000) {
+//    ifOffsetAna = 0x3B;
+//    anaRadioRegArray[1] = 0xB6;
+//  }
+//  if(s_lXtalFrequency==50000000) {
+//    ifOffsetAna = 0x36;
+//    anaRadioRegArray[1] = 0xAC;
+//  }
+//  if(s_lXtalFrequency==52000000) {
+//    ifOffsetAna = 0x31;
+//    anaRadioRegArray[1] = 0xA3;
+//  }
+  
+  g_xStatus = SpiritSpiWriteRegisters(IF_OFFSET_ANA_BASE, 1, &ifOffsetAna);
+
+  
+  /* Sets Xtal configuration */
+  if(s_lXtalFrequency>DOUBLE_XTAL_THR)
+  {
+    SpiritRadioSetXtalFlag(XTAL_FLAG((s_lXtalFrequency/2)));
+  }
+  else
+  {
+    SpiritRadioSetXtalFlag(XTAL_FLAG(s_lXtalFrequency));
+  }
+  
+  /* Sets the channel number in the corresponding register */
+  SpiritSpiWriteRegisters(CHNUM_BASE, 1, &pxSRadioInitStruct->cChannelNumber);
+  
+  /* Configures the Analog Radio registers */
+  SpiritSpiWriteRegisters(CHSPACE_BASE, 4, anaRadioRegArray);
+  
+  /* Configures the Digital Radio registers */
+  g_xStatus = SpiritSpiWriteRegisters(MOD1_BASE, 4, digRadioRegArray);
+  
+  /* Enable the freeze option of the AFC on the SYNC word */
+  SpiritRadioAFCFreezeOnSync(S_ENABLE);
+  
+  /* Set the IQC correction optimal value */
+  anaRadioRegArray[0]=0x80;
+  anaRadioRegArray[1]=0xE3;
+  g_xStatus = SpiritSpiWriteRegisters(0x99, 2, anaRadioRegArray);
+  
+  return SpiritRadioSetFrequencyBase(pxSRadioInitStruct->lFrequencyBase);
+  
+}
+
+
+/**
+* @brief  Returns the SPIRIT analog and digital radio structure according to the registers value.
+* @param  pxSRadioInitStruct pointer to a SRadioInit structure that
+*         contains the configuration information for the analog radio part of SPIRIT.
+* @retval None.
+*/
+void SpiritRadioGetInfo(SRadioInit* pxSRadioInitStruct)
+{
+  uint8_t anaRadioRegArray[8], digRadioRegArray[4];
+  BandSelect band;
+  int16_t xtalOffsetFactor;
+  
+  /* Get the RF board version */
+  //SpiritVersion xSpiritVersion = SpiritGeneralGetSpiritVersion();
+  
+  /* Reads the Analog Radio registers */
+  SpiritSpiReadRegisters(SYNT3_BASE, 8, anaRadioRegArray);
+  
+  /* Reads the Digital Radio registers */
+  g_xStatus = SpiritSpiReadRegisters(MOD1_BASE, 4, digRadioRegArray);
+  
+  /* Reads the operating band masking the Band selected field */
+  if((anaRadioRegArray[3] & 0x07) == SYNT0_BS_6)
+  {
+    band = HIGH_BAND;
+  }
+  else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_12)
+  {
+    band = MIDDLE_BAND;
+  }
+  else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_16)
+  {
+    band = LOW_BAND;
+  }
+  else if ((anaRadioRegArray[3] & 0x07) == SYNT0_BS_32)
+  {
+    band = VERY_LOW_BAND;
+  }
+  else
+  {
+    /* if it is another value, set it to a valid one in order to avoid access violation */
+    uint8_t tmp=(anaRadioRegArray[3]&0xF8)|SYNT0_BS_6;
+    SpiritSpiWriteRegisters(SYNT0_BASE,1,&tmp);
+    band = HIGH_BAND;
+  }
+  
+  /* Computes the synth word */
+  uint32_t synthWord = (uint32_t)((((uint32_t)(anaRadioRegArray[0]&0x1F))<<21)+(((uint32_t)(anaRadioRegArray[1]))<<13)+\
+    (((uint32_t)(anaRadioRegArray[2]))<<5)+(((uint32_t)(anaRadioRegArray[3]))>>3));
+  
+  /* Calculates the frequency base */
+  uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
+  pxSRadioInitStruct->lFrequencyBase = (uint32_t)round(synthWord*(((double)s_lXtalFrequency)/(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band])));
+  
+  /* Calculates the Offset Factor */
+  uint16_t xtalOffTemp = ((((uint16_t)anaRadioRegArray[6])<<8)+((uint16_t)anaRadioRegArray[7]));
+  
+  /* If a negative number then convert the 12 bit 2-complement in a 16 bit number */
+  if(xtalOffTemp & 0x0800)
+  {
+    xtalOffTemp = xtalOffTemp | 0xF000;
+  }
+  else
+  {
+    xtalOffTemp = xtalOffTemp & 0x0FFF;
+  }
+  
+  xtalOffsetFactor = *((int16_t*)(&xtalOffTemp));
+  
+  /* Calculates the frequency offset in ppm */
+  pxSRadioInitStruct->nXtalOffsetPpm =(int16_t)((uint32_t)xtalOffsetFactor*s_lXtalFrequency*PPM_FACTOR)/((uint32_t)FBASE_DIVIDER*pxSRadioInitStruct->lFrequencyBase);
+  
+  /* Channel space */
+  pxSRadioInitStruct->nChannelSpace = anaRadioRegArray[4]*(s_lXtalFrequency>>15);
+  
+  /* Channel number */
+  pxSRadioInitStruct->cChannelNumber = SpiritRadioGetChannel();
+  
+  /* Modulation select */
+  pxSRadioInitStruct->xModulationSelect = (ModulationSelect)(digRadioRegArray[1] & 0x70);
+  
+  /* Reads the frequency deviation for mantissa and exponent */
+  uint8_t FDevM = digRadioRegArray[2]&0x07;
+  uint8_t FDevE = (digRadioRegArray[2]&0xF0)>>4;
+  
+  /* Reads the channel filter register for mantissa and exponent */
+  uint8_t bwM = (digRadioRegArray[3]&0xF0)>>4;
+  uint8_t bwE = digRadioRegArray[3]&0x0F;
+  
+  uint8_t cDivider = 0;
+  cDivider = SpiritRadioGetDigDiv();
+  
+  /* Calculates the datarate */
+  pxSRadioInitStruct->lDatarate = ((s_lXtalFrequency>>(5+cDivider))*(256+digRadioRegArray[0]))>>(23-(digRadioRegArray[1]&0x0F));
+  
+  /* Calculates the frequency deviation */
+  // (((s_lXtalFrequency>>6)*(8+FDevM))>>(12-FDevE+cCorrection));
+  pxSRadioInitStruct->lFreqDev =(uint32_t)((float)s_lXtalFrequency/(((uint32_t)1)<<18)*(uint32_t)((8.0+FDevM)/2*(1<<FDevE)));
+  
+  /* Reads the channel filter bandwidth from the look-up table and return it */
+  pxSRadioInitStruct->lBandwidth = (uint32_t)(100.0*s_vectnBandwidth26M[bwM+(bwE*9)]*((s_lXtalFrequency>>cDivider)/26e6));
+  
+}
+
+
+/**
+* @brief  Sets the Xtal configuration in the ANA_FUNC_CONF0 register.
+* @param  xXtal one of the possible value of the enum type XtalFrequency.
+*         @arg XTAL_FLAG_24_MHz:  in case of 24 MHz crystal
+*         @arg XTAL_FLAG_26_MHz:  in case of 26 MHz crystal
+* @retval None.
+*/
+void SpiritRadioSetXtalFlag(XtalFlag xXtal)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_XTAL_FLAG(xXtal));
+  
+  /* Reads the ANA_FUNC_CONF_0 register */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+  if(xXtal == XTAL_FLAG_26_MHz)
+  {
+    tempRegValue|=SELECT_24_26_MHZ_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~SELECT_24_26_MHZ_MASK);
+  }
+  
+  /* Sets the 24_26MHz_SELECT field in the ANA_FUNC_CONF_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the Xtal configuration in the ANA_FUNC_CONF0 register.
+* @param  None.
+* @retval XtalFrequency Settled Xtal configuration.
+*/
+XtalFlag SpiritRadioGetXtalFlag(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the Xtal configuration in the ANA_FUNC_CONF_0 register and return the value */
+  g_xStatus = SpiritSpiReadRegisters(ANA_FUNC_CONF0_BASE, 1, &tempRegValue);
+  
+  return (XtalFlag)((tempRegValue & 0x40)>>6);
+  
+}
+
+
+/**
+* @brief  Returns the charge pump word for a given VCO frequency.
+* @param  lFc channel center frequency expressed in Hz.
+*         This parameter can be a value in one of the following ranges:<ul>
+*         <li> High_Band: from 779 MHz to 915 MHz </li>
+*         <li> Middle Band: from 387 MHz to 470 MHz </li>
+*         <li> Low Band: from 300 MHz to 348 MHz </li>
+*         <li> Very low Band: from 150 MHz to 174 MHz </li> </ul>
+* @retval uint8_t Charge pump word.
+*/
+uint8_t SpiritRadioSearchWCP(uint32_t lFc)
+{
+  int8_t i;
+  uint32_t vcofreq;
+  uint8_t BFactor;
+  
+  /* Check the channel center frequency is in one of the possible range */
+  s_assert_param(IS_FREQUENCY_BAND(lFc));
+  
+  /* Search the operating band */
+  if(IS_FREQUENCY_BAND_HIGH(lFc))
+  {
+    BFactor = HIGH_BAND_FACTOR;
+  }
+  else if(IS_FREQUENCY_BAND_MIDDLE(lFc))
+  {
+    BFactor = MIDDLE_BAND_FACTOR;
+  }
+  else if(IS_FREQUENCY_BAND_LOW(lFc))
+  {
+    BFactor = LOW_BAND_FACTOR;
+  }
+  else
+  {
+    BFactor = VERY_LOW_BAND_FACTOR;
+  }
+  
+  /* Calculates the VCO frequency VCOFreq = lFc*B */
+  vcofreq = (lFc/1000000)*BFactor;
+  
+  /* Search in the vco frequency array the charge pump word */
+  if(vcofreq>=s_vectnVCOFreq[15])
+  {
+    i=15;
+  }
+  else
+  {
+    /* Search the value */
+    for(i=0 ; i<15 && vcofreq>s_vectnVCOFreq[i] ; i++);
+    
+    /* Be sure that it is the best approssimation */
+    if (i!=0 && s_vectnVCOFreq[i]-vcofreq>vcofreq-s_vectnVCOFreq[i-1])
+      i--;
+  }
+  
+  /* Return index */
+  return (i%8);
+  
+}
+
+/**
+* @brief  Returns the synth word.
+* @param  None.
+* @retval uint32_t Synth word.
+*/
+uint32_t SpiritRadioGetSynthWord(void)
+{
+  uint8_t regArray[4];
+  
+  /* Reads the SYNTH registers, build the synth word and return it */
+  g_xStatus = SpiritSpiReadRegisters(SYNT3_BASE, 4, regArray);
+  return ((((uint32_t)(regArray[0]&0x1F))<<21)+(((uint32_t)(regArray[1]))<<13)+\
+    (((uint32_t)(regArray[2]))<<5)+(((uint32_t)(regArray[3]))>>3));
+  
+}
+
+
+/**
+* @brief  Sets the SYNTH registers.
+* @param  lSynthWord the synth word to write in the SYNTH[3:0] registers.
+* @retval None.
+*/
+void SpiritRadioSetSynthWord(uint32_t lSynthWord)
+{
+  uint8_t tempArray[4];
+  uint8_t tempRegValue;
+  
+  /* Reads the SYNT0 register */
+  g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
+  
+  /* Mask the Band selected field */
+  tempRegValue &= 0x07;
+  
+  /* Build the array for SYNTH registers */
+  tempArray[0] = (uint8_t)((lSynthWord>>21)&(0x0000001F));
+  tempArray[1] = (uint8_t)((lSynthWord>>13)&(0x000000FF));
+  tempArray[2] = (uint8_t)((lSynthWord>>5)&(0x000000FF));
+  tempArray[3] = (uint8_t)(((lSynthWord&0x0000001F)<<3)| tempRegValue);
+  
+  /* Writes the synth word in the SYNTH registers */
+  g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, tempArray);
+  
+}
+
+
+/**
+* @brief  Sets the operating band.
+* @param  xBand the band to set.
+*         This parameter can be one of following parameters:
+*         @arg  HIGH_BAND   High_Band selected: from 779 MHz to 915 MHz
+*         @arg  MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
+*         @arg  LOW_BAND:  Low Band selected: from 300 MHz to 348 MHz
+*         @arg  VERY_LOW_BAND:  Very low Band selected: from 150 MHz to 174 MHz
+* @retval None.
+*/
+void SpiritRadioSetBand(BandSelect xBand)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_BAND_SELECTED(xBand));
+  
+  /* Reads the SYNT0 register*/
+  g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
+  
+  /* Mask the SYNTH[4;0] field and write the BS value */
+  tempRegValue &= 0xF8;
+  tempRegValue |= s_vectcBandRegValue[xBand];
+  
+  /* Configures the SYNT0 register setting the operating band */
+  g_xStatus = SpiritSpiWriteRegisters(SYNT0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the operating band.
+* @param  None.
+* @retval BandSelect Settled band.
+*         This returned value can be one of the following parameters:
+*         @arg  HIGH_BAND   High_Band selected: from 779 MHz to 915 MHz
+*         @arg  MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
+*         @arg  LOW_BAND:  Low Band selected: from 300 MHz to 348 MHz
+*         @arg  VERY_LOW_BAND:  Very low Band selected: from 150 MHz to 174 MHz
+*/
+BandSelect SpiritRadioGetBand(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the SYNT0 register */
+  g_xStatus = SpiritSpiReadRegisters(SYNT0_BASE, 1, &tempRegValue);
+  
+  /* Mask the Band selected field */
+  if((tempRegValue & 0x07) == SYNT0_BS_6)
+  {
+    return HIGH_BAND;
+  }
+  else if ((tempRegValue & 0x07) == SYNT0_BS_12)
+  {
+    return MIDDLE_BAND;
+  }
+  else if ((tempRegValue & 0x07) == SYNT0_BS_16)
+  {
+    return LOW_BAND;
+  }
+  else
+  {
+    return VERY_LOW_BAND;
+  }
+  
+}
+
+
+/**
+* @brief  Sets the channel number.
+* @param  cChannel the channel number.
+* @retval None.
+*/
+void SpiritRadioSetChannel(uint8_t cChannel)
+{
+  /* Writes the CHNUM register */
+  g_xStatus = SpiritSpiWriteRegisters(CHNUM_BASE, 1, &cChannel);
+  
+}
+
+
+/**
+* @brief  Returns the actual channel number.
+* @param  None.
+* @retval uint8_t Actual channel number.
+*/
+uint8_t SpiritRadioGetChannel(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the CHNUM register and return the value */
+  g_xStatus = SpiritSpiReadRegisters(CHNUM_BASE, 1, &tempRegValue);
+  
+  return tempRegValue;
+  
+}
+
+
+/**
+* @brief  Sets the channel space factor in channel space register.
+*         The channel spacing step is computed as F_Xo/32768.
+* @param  fChannelSpace the channel space expressed in Hz.
+* @retval None.
+*/
+void SpiritRadioSetChannelSpace(uint32_t fChannelSpace)
+{
+  uint8_t cChannelSpaceFactor;
+  
+  /* Round to the nearest integer */
+  cChannelSpaceFactor = ((uint32_t)fChannelSpace*CHSPACE_DIVIDER)/s_lXtalFrequency;
+  
+  /* Write value into the register */
+  g_xStatus = SpiritSpiWriteRegisters(CHSPACE_BASE, 1, &cChannelSpaceFactor);
+  
+}
+
+
+/**
+* @brief  Returns the channel space register.
+* @param  None.
+* @retval uint32_t Channel space. The channel space is: CS = channel_space_factor x XtalFrequency/2^15
+*         where channel_space_factor is the CHSPACE register value.
+*/
+uint32_t SpiritRadioGetChannelSpace(void)
+{
+  uint8_t channelSpaceFactor;
+  
+  /* Reads the CHSPACE register, calculate the channel space and return it */
+  g_xStatus = SpiritSpiReadRegisters(CHSPACE_BASE, 1, &channelSpaceFactor);
+  
+  /* Compute the Hertz value and return it */
+  return ((channelSpaceFactor*s_lXtalFrequency)/CHSPACE_DIVIDER);
+  
+}
+
+
+/**
+* @brief  Sets the FC OFFSET register starting from xtal ppm value.
+* @param  nXtalPpm the xtal offset expressed in ppm.
+* @retval None.
+*/
+void SpiritRadioSetFrequencyOffsetPpm(int16_t nXtalPpm)
+{
+  uint8_t tempArray[2];
+  int16_t xtalOffsetFactor;
+  uint32_t synthWord, fBase;
+  int32_t FOffsetTmp;
+  BandSelect band;
+  
+  /* Reads the synth word */
+  synthWord = SpiritRadioGetSynthWord();
+  
+  /* Reads the operating band */
+  band = SpiritRadioGetBand();
+  
+  /* Calculates the frequency base */
+  uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
+  fBase = synthWord*(s_lXtalFrequency/(s_vectcBHalfFactor[band]*cRefDiv)/FBASE_DIVIDER);
+  
+  /* Calculates the offset respect to RF frequency and according to xtal_ppm parameter */
+  FOffsetTmp = (int32_t)(((float)nXtalPpm*fBase)/PPM_FACTOR);
+  
+  /* Check the Offset is in the correct range */
+  s_assert_param(IS_FREQUENCY_OFFSET(FOffsetTmp,s_lXtalFrequency));
+  
+  /* Calculates the FC_OFFSET value to write in the corresponding register */  
+  xtalOffsetFactor = (int16_t)(((float)FOffsetTmp*FBASE_DIVIDER)/s_lXtalFrequency);
+  
+  /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */
+  tempArray[0]=(uint8_t)((((uint16_t)xtalOffsetFactor)>>8)&0x0F);
+  tempArray[1]=(uint8_t)(xtalOffsetFactor);
+  
+  /* Writes the FC_OFFSET registers */
+  g_xStatus = SpiritSpiWriteRegisters(FC_OFFSET1_BASE, 2, tempArray);
+  
+}
+
+
+/**
+* @brief  Sets the FC OFFSET register starting from frequency offset expressed in Hz.
+* @param  lFOffset frequency offset expressed in Hz as signed word.
+* @retval None.
+*/
+void SpiritRadioSetFrequencyOffset(int32_t lFOffset)
+{
+  uint8_t tempArray[2];
+  int16_t offset;
+  
+  /* Check that the Offset is in the correct range */
+  s_assert_param(IS_FREQUENCY_OFFSET(lFOffset,s_lXtalFrequency));
+  
+  /* Calculates the offset value to write in the FC_OFFSET register */
+  offset = (int16_t)(((float)lFOffset*FBASE_DIVIDER)/s_lXtalFrequency);
+  
+  /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */
+  tempArray[0]=(uint8_t)((((uint16_t)offset)>>8)&0x0F);
+  tempArray[1]=(uint8_t)(offset);
+  
+  /* Writes the FC_OFFSET registers */
+  g_xStatus = SpiritSpiWriteRegisters(FC_OFFSET1_BASE, 2, tempArray);
+  
+}
+
+
+/**
+* @brief  Returns the actual frequency offset.
+* @param  None.
+* @retval int32_t Frequency offset expressed in Hz as signed word.
+*/
+int32_t SpiritRadioGetFrequencyOffset(void)
+{
+  uint8_t tempArray[2];
+  int16_t xtalOffsetFactor;
+  
+  /* Reads the FC_OFFSET registers */
+  g_xStatus = SpiritSpiReadRegisters(FC_OFFSET1_BASE, 2, tempArray);
+  
+  /* Calculates the Offset Factor */
+  uint16_t xtalOffTemp = ((((uint16_t)tempArray[0])<<8)+((uint16_t)tempArray[1]));
+  
+  if(xtalOffTemp & 0x0800)
+  {
+    xtalOffTemp = xtalOffTemp | 0xF000;
+  }
+  else
+  {
+    xtalOffTemp = xtalOffTemp & 0x0FFF;
+  }
+  
+  xtalOffsetFactor = *((int16_t*)(&xtalOffTemp));
+  
+  /* Calculates the frequency offset and return it */
+  return ((int32_t)(xtalOffsetFactor*s_lXtalFrequency)/FBASE_DIVIDER);
+  
+}
+
+
+
+/**
+* @brief  Sets the Synth word and the Band Select register according to desired base carrier frequency.
+*         In this API the Xtal configuration is read out from
+*         the corresponding register. The user shall fix it before call this API.
+* @param  lFBase the base carrier frequency expressed in Hz as unsigned word.
+* @retval Error code: 0=no error, 1=error during calibration of VCO.
+*/
+uint8_t SpiritRadioSetFrequencyBase(uint32_t lFBase)
+{
+  uint32_t synthWord, Fc;
+  uint8_t band, anaRadioRegArray[4], wcp;
+  
+  /* Check the parameter */
+  s_assert_param(IS_FREQUENCY_BAND(lFBase));
+  
+  /* Search the operating band */
+  if(IS_FREQUENCY_BAND_HIGH(lFBase))
+  {
+    band = HIGH_BAND;
+  }
+  else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
+  {
+    band = MIDDLE_BAND;
+  }
+  else if(IS_FREQUENCY_BAND_LOW(lFBase))
+  {
+    band = LOW_BAND;
+  }
+  else
+  {
+    band = VERY_LOW_BAND;
+  }
+  
+  int32_t FOffset  = SpiritRadioGetFrequencyOffset();
+  uint32_t lChannelSpace  = SpiritRadioGetChannelSpace();
+  uint8_t cChannelNum = SpiritRadioGetChannel();
+  
+  /* Calculates the channel center frequency */
+  Fc = lFBase + FOffset + lChannelSpace*cChannelNum;
+  
+  /* Reads the reference divider */
+  uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv()+1;
+  
+  /* Selects the VCO */
+  switch(band)
+  {
+  case VERY_LOW_BAND:
+    if(Fc<161281250)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case LOW_BAND:
+    if(Fc<322562500)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case MIDDLE_BAND:
+    if(Fc<430083334)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+    break;
+    
+  case HIGH_BAND:
+    if(Fc<860166667)
+    {
+      SpiritCalibrationSelectVco(VCO_L);
+    }
+    else
+    {
+      SpiritCalibrationSelectVco(VCO_H);
+    }
+  }
+  
+  /* Search the VCO charge pump word and set the corresponding register */
+  wcp = SpiritRadioSearchWCP(Fc);
+  
+  synthWord = (uint32_t)(lFBase*s_vectcBHalfFactor[band]*(((double)(FBASE_DIVIDER*cRefDiv))/s_lXtalFrequency));
+  
+  /* Build the array of registers values for the analog part */
+  anaRadioRegArray[0] = (uint8_t)(((synthWord>>21)&(0x0000001F))|(wcp<<5));
+  anaRadioRegArray[1] = (uint8_t)((synthWord>>13)&(0x000000FF));
+  anaRadioRegArray[2] = (uint8_t)((synthWord>>5)&(0x000000FF));
+  anaRadioRegArray[3] = (uint8_t)(((synthWord&0x0000001F)<<3)| s_vectcBandRegValue[band]);
+  
+  /* Configures the needed Analog Radio registers */
+  g_xStatus = SpiritSpiWriteRegisters(SYNT3_BASE, 4, anaRadioRegArray);
+  
+  if(xDoVcoCalibrationWA==S_ENABLE)
+    return SpiritManagementWaVcoCalibration();
+  
+  return 0;
+}
+
+/**
+* @brief  To say to the set frequency base if do or not the VCO calibration WA.
+* @param  S_ENABLE or S_DISABLE the WA procedure.
+* @retval None.
+*/
+void SpiritRadioVcoCalibrationWAFB(SpiritFunctionalState xNewstate)
+{
+  xDoVcoCalibrationWA=xNewstate;
+}
+
+/**
+* @brief  Returns the base carrier frequency.
+* @param  None.
+* @retval uint32_t Base carrier frequency expressed in Hz as unsigned word.
+*/
+uint32_t SpiritRadioGetFrequencyBase(void)
+{
+  uint32_t synthWord;
+  BandSelect band;
+  
+  /* Reads the synth word */
+  synthWord = SpiritRadioGetSynthWord();
+  
+  /* Reads the operating band */
+  band = SpiritRadioGetBand();
+  
+  uint8_t cRefDiv = (uint8_t)SpiritRadioGetRefDiv() + 1;
+  
+  /* Calculates the frequency base and return it */
+  return (uint32_t)round(synthWord*(((double)s_lXtalFrequency)/(FBASE_DIVIDER*cRefDiv*s_vectcBHalfFactor[band])));
+}
+
+
+/**
+* @brief  Returns the actual channel center frequency.
+* @param  None.
+* @retval uint32_t Actual channel center frequency expressed in Hz.
+*/
+uint32_t SpiritRadioGetCenterFrequency(void)
+{
+  int32_t offset;
+  uint8_t channel;
+  uint32_t fBase;
+  uint32_t channelSpace;
+  
+  /* Reads the frequency base */
+  fBase = SpiritRadioGetFrequencyBase();
+  
+  /* Reads the frequency offset */
+  offset = SpiritRadioGetFrequencyOffset();
+  
+  /* Reads the channel space */
+  channelSpace = SpiritRadioGetChannelSpace();
+  
+  /* Reads the channel number */
+  channel = SpiritRadioGetChannel();
+  
+  /* Calculates the channel center frequency and return it */
+  return (uint32_t)(fBase +  offset + (uint32_t)(channelSpace*channel));
+  
+}
+
+
+/**
+* @brief  Returns the mantissa and exponent, whose value used in the datarate formula
+*         will give the datarate value closer to the given datarate.
+* @param  fDatarate datarate expressed in bps. This parameter ranging between 100 and 500000.
+* @param  pcM pointer to the returned mantissa value.
+* @param  pcE pointer to the returned exponent value.
+* @retval None.
+*/
+void SpiritRadioSearchDatarateME(uint32_t lDatarate, uint8_t* pcM, uint8_t* pcE)
+{
+  volatile SpiritBool find = S_FALSE;
+  int8_t i=15;
+  uint8_t cMantissaTmp;
+  uint8_t cDivider = 0;
+  
+  /* Check the parameters */
+  s_assert_param(IS_DATARATE(lDatarate));
+  
+  cDivider = (uint8_t)SpiritRadioGetDigDiv();
+  
+  /* Search in the datarate array the exponent value */
+  while(!find && i>=0)
+  {
+    if(lDatarate>=(s_lXtalFrequency>>(20-i+cDivider)))
+    {
+      find = S_TRUE;
+    }
+    else
+    {
+      i--;
+    }
+  }
+  i<0 ? i=0 : i;
+  *pcE = i;
+  
+  /* Calculates the mantissa value according to the datarate formula */
+  cMantissaTmp = (lDatarate*((uint32_t)1<<(23-i)))/(s_lXtalFrequency>>(5+cDivider))-256;
+  
+  /* Finds the mantissa value with less approximation */
+  int16_t mantissaCalculation[3];
+  for(uint8_t j=0;j<3;j++)
+  {
+    if((cMantissaTmp+j-1))
+    {
+      mantissaCalculation[j]=lDatarate-(((256+cMantissaTmp+j-1)*(s_lXtalFrequency>>(5+cDivider)))>>(23-i));
+    }
+    else
+    {
+      mantissaCalculation[j]=0x7FFF;
+    }
+  }
+  uint16_t mantissaCalculationDelta = 0xFFFF;
+  for(uint8_t j=0;j<3;j++)
+  {
+    if(S_ABS(mantissaCalculation[j])<mantissaCalculationDelta)
+    {
+      mantissaCalculationDelta = S_ABS(mantissaCalculation[j]);
+      *pcM = cMantissaTmp+j-1;
+    }
+  }
+  
+}
+
+
+/**
+* @brief  Returns the mantissa and exponent for a given bandwidth.
+*         Even if it is possible to pass as parameter any value in the below mentioned range,
+*         the API will search the closer value according to a fixed table of channel
+*         bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, returning the corresponding mantissa
+*         and exponent value.
+* @param  lBandwidth bandwidth expressed in Hz. This parameter ranging between 1100 and 800100.
+* @param  pcM pointer to the returned mantissa value.
+* @param  pcE pointer to the returned exponent value.
+* @retval None.
+*/
+void SpiritRadioSearchChannelBwME(uint32_t lBandwidth, uint8_t* pcM, uint8_t* pcE)
+{
+  int8_t i, i_tmp;
+  uint8_t cDivider = 1;
+  
+    /* Search in the channel filter bandwidth table the exponent value */
+  if(SpiritRadioGetDigDiv())
+  {
+    cDivider = 2;
+  }
+  else
+  {
+    cDivider = 1;
+  }
+    
+  s_assert_param(IS_CH_BW(lBandwidth,s_lXtalFrequency/cDivider));
+  
+  uint32_t lChfltFactor = (s_lXtalFrequency/cDivider)/100;
+  
+  for(i=0;i<90 && (lBandwidth<(uint32_t)((s_vectnBandwidth26M[i]*lChfltFactor)/2600));i++);
+  
+  if(i!=0)
+  {
+    /* Finds the mantissa value with less approximation */
+    i_tmp=i;
+    int16_t chfltCalculation[3];
+    for(uint8_t j=0;j<3;j++) 
+    {
+      if(((i_tmp+j-1)>=0) || ((i_tmp+j-1)<=89))
+      {
+        chfltCalculation[j] = lBandwidth - (uint32_t)((s_vectnBandwidth26M[i_tmp+j-1]*lChfltFactor)/2600);
+      }
+      else
+      {
+        chfltCalculation[j] = 0x7FFF;
+      }
+    }
+    uint16_t chfltDelta = 0xFFFF;
+    
+    for(uint8_t j=0;j<3;j++)
+    {
+      if(S_ABS(chfltCalculation[j])<chfltDelta)
+      {
+        chfltDelta = S_ABS(chfltCalculation[j]);
+        i=i_tmp+j-1;
+      }    
+    }
+  }
+  (*pcE) = (uint8_t)(i/9);
+  (*pcM) = (uint8_t)(i%9);
+  
+}
+
+/**
+* @brief  Returns the mantissa and exponent, whose value used in the frequency deviation formula
+*         will give a frequency deviation value most closer to the given frequency deviation.
+* @param  fFDev frequency deviation expressed in Hz. This parameter can be a value in the range [F_Xo*8/2^18, F_Xo*7680/2^18].
+* @param  pcM pointer to the returned mantissa value.
+* @param  pcE pointer to the returned exponent value.
+* @retval None.
+*/
+void SpiritRadioSearchFreqDevME(uint32_t lFDev, uint8_t* pcM, uint8_t* pcE)
+{
+  uint8_t i;
+  uint32_t a,bp,b=0;
+  float xtalDivtmp=(float)s_lXtalFrequency/(((uint32_t)1)<<18);
+  
+  /* Check the parameters */
+  s_assert_param(IS_F_DEV(lFDev,s_lXtalFrequency));
+  
+  for(i=0;i<10;i++)
+  {
+    a=(uint32_t)(xtalDivtmp*(uint32_t)(7.5*(1<<i)));
+    if(lFDev<a)
+      break;
+  }
+  (*pcE) = i;
+  
+  for(i=0;i<8;i++)
+  {
+    bp=b;
+    b=(uint32_t)(xtalDivtmp*(uint32_t)((8.0+i)/2*(1<<(*pcE))));
+    if(lFDev<b)
+      break;
+  }
+  
+  (*pcM)=i;
+  if((lFDev-bp)<(b-lFDev))
+    (*pcM)--;
+  
+}
+
+
+/**
+* @brief  Sets the datarate.
+* @param  fDatarate datarate expressed in bps. This value shall be in the range
+*         [100 500000].
+* @retval None.
+*/
+void SpiritRadioSetDatarate(uint32_t lDatarate)
+{
+  uint8_t drE, tempRegValue[2];
+  
+  /* Check the parameters */
+  s_assert_param(IS_DATARATE(lDatarate));
+  
+  /* Calculates the datarate mantissa and exponent */
+  SpiritRadioSearchDatarateME(lDatarate, &tempRegValue[0], &drE);
+  
+  /* Reads the MOD_O register*/
+  SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue[1]);
+  
+  /* Mask the other fields and set the datarate exponent */
+  tempRegValue[1] &= 0xF0;
+  tempRegValue[1] |= drE;
+  
+  /* Writes the Datarate registers */
+  g_xStatus = SpiritSpiWriteRegisters(MOD1_BASE, 2, tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the datarate.
+* @param  None.
+* @retval uint32_t Settled datarate expressed in bps.
+*/
+uint32_t SpiritRadioGetDatarate(void)
+{
+  uint8_t tempRegValue[2];
+  uint8_t cDivider=0;
+  
+  /* Reads the datarate registers for mantissa and exponent */
+  g_xStatus = SpiritSpiReadRegisters(MOD1_BASE, 2, tempRegValue);
+  
+  /* Calculates the datarate */
+  cDivider = (uint8_t)SpiritRadioGetDigDiv(); 
+  
+  return (((s_lXtalFrequency>>(5+cDivider))*(256+tempRegValue[0]))>>(23-(tempRegValue[1]&0x0F)));
+}
+
+
+/**
+* @brief  Sets the frequency deviation.
+* @param  fFDev frequency deviation expressed in Hz. Be sure that this value
+*         is in the correct range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz.
+* @retval None.
+*/
+void SpiritRadioSetFrequencyDev(uint32_t lFDev)
+{
+  uint8_t FDevM, FDevE, tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_F_DEV(lFDev, s_lXtalFrequency));
+  
+  /* Calculates the frequency deviation mantissa and exponent */
+  SpiritRadioSearchFreqDevME(lFDev, &FDevM, &FDevE);
+  
+  /* Reads the FDEV0 register */
+  SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
+  
+  /* Mask the other fields and set the frequency deviation mantissa and exponent */
+  tempRegValue &= 0x08;
+  tempRegValue |= ((FDevE<<4)|(FDevM));
+  
+  /* Writes the Frequency deviation register */
+  g_xStatus = SpiritSpiWriteRegisters(FDEV0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the frequency deviation.
+* @param  None.
+* @retval uint32_t Frequency deviation value expressed in Hz.
+*         This value will be in the range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz.
+*/
+uint32_t SpiritRadioGetFrequencyDev(void)
+{
+  uint8_t tempRegValue, FDevM, FDevE;  
+
+  
+  /* Reads the frequency deviation register for mantissa and exponent */
+  g_xStatus = SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
+  FDevM = tempRegValue&0x07;
+  FDevE = (tempRegValue&0xF0)>>4;
+  
+  /* Calculates the frequency deviation and return it */
+  //return (((s_lXtalFrequency>>6)*(8+FDevM))>>(13-FDevE));
+  
+  return (uint32_t)((float)s_lXtalFrequency/(((uint32_t)1)<<18)*(uint32_t)((8.0+FDevM)/2*(1<<FDevE)));
+   
+}
+
+
+/**
+* @brief  Sets the channel filter bandwidth.
+* @param  lBandwidth channel filter bandwidth expressed in Hz. This parameter shall be in the range [1100 800100]
+*         Even if it is possible to pass as parameter any value in the above mentioned range,
+*         the API will search the most closer value according to a fixed table of channel
+*         bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet. To verify the settled channel bandwidth
+*         it is possible to use the SpiritRadioGetChannelBW() API.
+* @retval None.
+*/
+void SpiritRadioSetChannelBW(uint32_t lBandwidth)
+{
+  uint8_t bwM, bwE, tempRegValue;
+  
+  /* Search in the channel filter bandwidth table the exponent value */
+  if(SpiritRadioGetDigDiv())
+  {
+    s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency/2)));
+  }
+  else
+  {
+    s_assert_param(IS_CH_BW(lBandwidth,(s_lXtalFrequency)));
+  } 
+  
+  /* Calculates the channel bandwidth mantissa and exponent */
+  SpiritRadioSearchChannelBwME(lBandwidth, &bwM, &bwE);
+  tempRegValue = (bwM<<4)|(bwE);
+  
+  /* Writes the Channel filter register */
+  g_xStatus = SpiritSpiWriteRegisters(CHFLT_BASE, 1, &tempRegValue);
+  
+}
+
+/**
+* @brief  Returns the channel filter bandwidth.
+* @param  None.
+* @retval uint32_t Channel filter bandwidth expressed in Hz.
+*/
+uint32_t SpiritRadioGetChannelBW(void)
+{
+  uint8_t tempRegValue, bwM, bwE;
+  
+  /* Reads the channel filter register for mantissa and exponent */
+  g_xStatus = SpiritSpiReadRegisters(CHFLT_BASE, 1, &tempRegValue);
+  bwM = (tempRegValue&0xF0)>>4;
+  bwE = tempRegValue&0x0F;
+  
+  /* Reads the channel filter bandwidth from the look-up table and return it */
+  return (uint32_t)(100.0*s_vectnBandwidth26M[bwM+(bwE*9)]*s_lXtalFrequency/26e6);
+  
+}
+
+
+/**
+* @brief  Sets the modulation type.
+* @param  xModulation modulation to set.
+*         This parameter shall be of type @ref ModulationSelect .
+* @retval None.
+*/
+void SpiritRadioSetModulation(ModulationSelect xModulation)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_MODULATION_SELECTED(xModulation));
+  
+  /* Reads the modulation register */
+  SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
+  
+  /* Mask the other fields and set the modulation type */
+  tempRegValue &=0x8F;
+  tempRegValue |= xModulation;
+  
+  /* Writes the modulation register */
+  g_xStatus = SpiritSpiWriteRegisters(MOD0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the modulation type used.
+* @param  None.
+* @retval ModulationSelect Settled modulation type.
+*/
+ModulationSelect SpiritRadioGetModulation(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the modulation register MOD0*/
+  g_xStatus = SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
+  
+  /* Return the modulation type */
+  return (ModulationSelect)(tempRegValue&0x70);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the Continuous Wave transmit mode.
+* @param  xNewState new state for power ramping.
+*         This parameter can be: S_ENABLE or S_DISABLE .
+* @retval None.
+*/
+void SpiritRadioCWTransmitMode(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the modulation register MOD0 and mask the CW field */
+  SpiritSpiReadRegisters(MOD0_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |=MOD0_CW;
+  }
+  else
+  {
+    tempRegValue &= (~MOD0_CW);
+  }
+  
+  /* Writes the new value in the MOD0 register */
+  g_xStatus = SpiritSpiWriteRegisters(MOD0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Sets the OOK Peak Decay.
+* @param  xOokDecay Peak decay control for OOK.
+*         This parameter shall be of type @ref OokPeakDecay .
+* @retval None.
+*/
+void SpiritRadioSetOokPeakDecay(OokPeakDecay xOokDecay)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_OOK_PEAK_DECAY(xOokDecay));
+  
+  /* Reads the RSSI_FLT register */
+  SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+  
+  /* Mask the other fields and set OOK Peak Decay */
+  tempRegValue &= 0xFC;
+  tempRegValue |= xOokDecay;
+  
+  /* Writes the RSSI_FLT register to set the new OOK peak dacay value */
+  g_xStatus = SpiritSpiWriteRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the OOK Peak Decay.
+* @param  None
+* @retval OokPeakDecay Ook peak decay value.
+*/
+OokPeakDecay SpiritRadioGetOokPeakDecay(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the OOK peak decay register RSSI_FLT_BASE*/
+  g_xStatus = SpiritSpiReadRegisters(RSSI_FLT_BASE, 1, &tempRegValue);
+  
+  /* Returns the OOK peak decay */
+  return (OokPeakDecay) (tempRegValue & 0x03);
+  
+}
+
+/**
+* @brief  Returns the PA register value that corresponds to the passed dBm power.
+* @param  lFbase Frequency base expressed in Hz.
+* @param  fPowerdBm Desired power in dBm.
+* @retval Register value as byte.
+* @note The power interpolation curves used by this function have been extracted
+*       by measurements done on the divisional evaluation boards.
+*/
+uint8_t SpiritRadioGetdBm2Reg(uint32_t lFBase, float fPowerdBm)
+{
+  uint8_t i=0;
+  uint8_t j=0;
+  float fReg;
+  
+  if(IS_FREQUENCY_BAND_HIGH(lFBase))
+  {
+    i=0;
+    if(lFBase<900000000) i=1;// 868   
+  }
+  else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
+  {
+    i=2;
+  }
+  else if(IS_FREQUENCY_BAND_LOW(lFBase))
+  {
+    i=3;
+  }
+  else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
+  {
+    i=4;
+  }
+  
+  j=1;
+  if(fPowerdBm>0 && 13.0/fPowerFactors[i][2]-fPowerFactors[i][3]/fPowerFactors[i][2]<fPowerdBm)
+      j=0;
+  else if(fPowerdBm<=0 && 40.0/fPowerFactors[i][2]-fPowerFactors[i][3]/fPowerFactors[i][2]>fPowerdBm)
+      j=2;
+
+  fReg=fPowerFactors[i][2*j]*fPowerdBm+fPowerFactors[i][2*j+1];
+  
+  if(fReg<1)
+    fReg=1;
+  else if(fReg>90) 
+    fReg=90;
+  
+  return ((uint8_t)fReg);
+}
+
+
+/**
+* @brief  Returns the dBm power that corresponds to the value of PA register.
+* @param  lFbase Frequency base expressed in Hz.
+* @param  cPowerReg Register value of the PA.
+* @retval Power in dBm as float.
+* @note The power interpolation curves used by this function have been extracted
+*       by measurements done on the divisional evaluation boards.
+*/
+float SpiritRadioGetReg2dBm(uint32_t lFBase, uint8_t cPowerReg)
+{
+  uint8_t i=0;
+  uint8_t j=0;
+  float fPower;
+  
+  if(cPowerReg==0 || cPowerReg>90)
+    return (-130.0);
+  
+  if(IS_FREQUENCY_BAND_HIGH(lFBase))
+  {
+    i=0;
+    if(lFBase<900000000) i=1;// 868   
+  }
+  else if(IS_FREQUENCY_BAND_MIDDLE(lFBase))
+  {
+    i=2;
+  }
+  else if(IS_FREQUENCY_BAND_LOW(lFBase))
+  {
+    i=3;
+  }
+  else if(IS_FREQUENCY_BAND_VERY_LOW(lFBase))
+  {
+    i=4;
+  }
+  
+  j=1;
+  if(cPowerReg<13) j=0;
+  else if(cPowerReg>40) j=2;
+  
+  fPower=(((float)cPowerReg)/fPowerFactors[i][2*j]-fPowerFactors[i][2*j+1]/fPowerFactors[i][2*j]);
+  
+  return fPower;
+}
+
+/**
+* @brief  Configures the Power Amplifier Table and registers with value expressed in dBm.
+* @param  cPALevelMaxIndex number of levels to set. This parameter shall be in the range [0:7].
+* @param  cWidth step width expressed in terms of bit period units Tb/8.
+*         This parameter shall be in the range [1:4].
+* @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
+*         @arg LOAD_0_PF    No additional PA load capacitor
+*         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
+*         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
+*         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
+* @param  pfPAtabledBm pointer to an array of PA values in dbm between [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dbm.
+*         The first element shall be the lower level (PA_LEVEL[0]) value and the last element
+*         the higher level one (PA_LEVEL[paLevelMaxIndex]).
+* @retval None.
+*/
+void SpiritRadioSetPATabledBm(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, float* pfPAtabledBm)
+{
+  uint8_t palevel[9], address, paLevelValue;
+  uint32_t lFBase=SpiritRadioGetFrequencyBase();
+
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cPALevelMaxIndex));
+  s_assert_param(IS_PA_STEP_WIDTH(cWidth));
+  s_assert_param(IS_PA_LOAD_CAP(xCLoad));
+  
+  /* Check the PA level in dBm is in the range and calculate the PA_LEVEL value
+  to write in the corresponding register using the linearization formula */
+  for(int i=0; i<=cPALevelMaxIndex; i++)
+  {
+    s_assert_param(IS_PAPOWER_DBM(*pfPAtabledBm));
+    paLevelValue=SpiritRadioGetdBm2Reg(lFBase,(*pfPAtabledBm));
+    palevel[cPALevelMaxIndex-i]=paLevelValue;
+    pfPAtabledBm++;
+  }
+  
+  /* Sets the PA_POWER[0] register */
+  palevel[cPALevelMaxIndex+1]=xCLoad|(cWidth-1)<<3|cPALevelMaxIndex;
+  
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cPALevelMaxIndex;
+  
+  /* Configures the PA_POWER registers */
+  g_xStatus = SpiritSpiWriteRegisters(address, cPALevelMaxIndex+2, palevel);
+  
+}
+
+
+/**
+* @brief  Returns the Power Amplifier Table and registers, returning values in dBm.
+* @param  pcPALevelMaxIndex pointer to the number of levels settled.
+*         This parameter will be in the range [0:7].
+* @param  pfPAtabledBm pointer to an array of 8 elements containing the PA value in dbm.
+*         The first element will be the PA_LEVEL_0 and the last element
+*         will be PA_LEVEL_7. Any value higher than PA_UPPER_LIMIT implies no output
+*         power (output stage is in high impedance).
+* @retval None.
+*/
+void SpiritRadioGetPATabledBm(uint8_t* pcPALevelMaxIndex, float* pfPAtabledBm)
+{
+  uint8_t palevelvect[9];
+  uint32_t lFBase=SpiritRadioGetFrequencyBase();
+  
+  /* Reads the PA_LEVEL_x registers and the PA_POWER_0 register */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER8_BASE, 9, palevelvect);
+  
+  /* Fill the PAtable */
+  for(int i=7; i>=0; i--)
+  {
+    (*pfPAtabledBm)=SpiritRadioGetReg2dBm(lFBase,palevelvect[i]);
+    pfPAtabledBm++;
+  }
+  
+  /* Return the settled index */
+  *pcPALevelMaxIndex = palevelvect[8]&0x07;
+  
+}
+
+
+
+
+
+
+/**
+* @brief  Sets a specific PA_LEVEL register, with a value given in dBm.
+* @param  cIndex PA_LEVEL to set. This parameter shall be in the range [0:7].
+* @param  fPowerdBm PA value to write expressed in dBm . Be sure that this values is in the
+*         correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm.
+* @retval None.
+* @note This function makes use of the @ref SpiritRadioGetdBm2Reg fcn to interpolate the 
+*       power value.
+*/
+void SpiritRadioSetPALeveldBm(uint8_t cIndex, float fPowerdBm)
+{
+  uint8_t address, paLevelValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cIndex));
+  s_assert_param(IS_PAPOWER_DBM(fPowerdBm));
+  
+  /* interpolate the power level */
+  paLevelValue=SpiritRadioGetdBm2Reg(SpiritRadioGetFrequencyBase(),fPowerdBm);
+
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cIndex;
+  
+  /* Configures the PA_LEVEL register */
+  g_xStatus = SpiritSpiWriteRegisters(address, 1, &paLevelValue);
+  
+}
+
+
+/**
+* @brief  Returns a specific PA_LEVEL register, returning a value in dBm.
+* @param  cIndex PA_LEVEL to read. This parameter shall be in the range [0:7]
+* @retval float Settled power level expressed in dBm. A value
+*         higher than PA_UPPER_LIMIT dBm implies no output power
+*         (output stage is in high impedance).
+* @note This function makes use of the @ref SpiritRadioGetReg2dBm fcn to interpolate the 
+*       power value.
+*/
+float SpiritRadioGetPALeveldBm(uint8_t cIndex)
+{
+  uint8_t address, paLevelValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cIndex));
+  
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cIndex;
+  
+  /* Reads the PA_LEVEL[cIndex] register */
+  g_xStatus = SpiritSpiReadRegisters(address, 1, &paLevelValue);
+  
+  return SpiritRadioGetReg2dBm(SpiritRadioGetFrequencyBase(),paLevelValue);
+}
+
+
+/**
+* @brief  Configures the Power Amplifier Table and registers.
+* @param  cPALevelMaxIndex number of levels to set. This parameter shall be in the range [0:7].
+* @param  cWidth step width expressed in terms of bit period units Tb/8.
+*         This parameter shall be in the range [1:4].
+* @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
+*         @arg LOAD_0_PF    No additional PA load capacitor
+*         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
+*         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
+*         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
+* @param  pcPAtable pointer to an array of PA values in the range [0: 90], where 0 implies no
+*         output power, 1 will be the maximum level and 90 the minimum one
+*         The first element shall be the lower level (PA_LEVEL[0]) value and the last element
+*         the higher level one (PA_LEVEL[paLevelMaxIndex]).
+* @retval None.
+*/
+void SpiritRadioSetPATable(uint8_t cPALevelMaxIndex, uint8_t cWidth, PALoadCapacitor xCLoad, uint8_t* pcPAtable)
+{
+  uint8_t palevel[9], address;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cPALevelMaxIndex));
+  s_assert_param(IS_PA_STEP_WIDTH(cWidth));
+  s_assert_param(IS_PA_LOAD_CAP(xCLoad));
+  
+  /* Check the PA levels are in the range */
+  for(int i=0; i<=cPALevelMaxIndex; i++)
+  {
+    s_assert_param(IS_PAPOWER(*pcPAtable));
+    palevel[cPALevelMaxIndex-i]=*pcPAtable;
+    pcPAtable++;
+  }
+  
+  /* Sets the PA_POWER[0] register */
+  palevel[cPALevelMaxIndex+1]=xCLoad|((cWidth-1)<<3)|cPALevelMaxIndex;
+  
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cPALevelMaxIndex;
+  
+  /* Configures the PA_POWER registers */
+  g_xStatus = SpiritSpiWriteRegisters(address, cPALevelMaxIndex+2, palevel);
+  
+}
+
+
+/**
+* @brief  Returns the Power Amplifier Table and registers.
+* @param  pcPALevelMaxIndex pointer to the number of levels settled.
+*         This parameter shall be in the range [0:7].
+* @param  pcPAtable pointer to an array of 8 elements containing the PA value.
+*         The first element will be the PA_LEVEL_0 and the last element
+*         will be PA_LEVEL_7. Any value equals to 0 implies that level has
+*         no output power (output stage is in high impedance).
+* @retval None
+*/
+void SpiritRadioGetPATable(uint8_t* pcPALevelMaxIndex, uint8_t* pcPAtable)
+{
+  uint8_t palevelvect[9];
+  
+  /* Reads the PA_LEVEL_x registers and the PA_POWER_0 register */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER8_BASE, 9, palevelvect);
+  
+  /* Fill the PAtable */
+  for(int i=7; i>=0; i--)
+  {
+    *pcPAtable = palevelvect[i];
+    pcPAtable++;
+  }
+  
+  /* Return the settled index */
+  *pcPALevelMaxIndex = palevelvect[8]&0x07;
+  
+}
+
+
+/**
+* @brief  Sets a specific PA_LEVEL register.
+* @param  cIndex PA_LEVEL to set. This parameter shall be in the range [0:7].
+* @param  cPower PA value to write in the register. Be sure that this values is in the
+*         correct range [0 : 90].
+* @retval None.
+*/
+void SpiritRadioSetPALevel(uint8_t cIndex, uint8_t cPower)
+{
+  uint8_t address;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cIndex));
+  s_assert_param(IS_PAPOWER(cPower));
+  
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cIndex;
+  
+  /* Configures the PA_LEVEL register */
+  g_xStatus = SpiritSpiWriteRegisters(address, 1, &cPower);
+  
+}
+
+
+/**
+* @brief  Returns a specific PA_LEVEL register.
+* @param  cIndex PA_LEVEL to read. This parameter shall be in the range [0:7].
+* @retval uint8_t PA_LEVEL value. A value equal to zero
+*         implies no output power (output stage is in high impedance).
+*/
+uint8_t SpiritRadioGetPALevel(uint8_t cIndex)
+{
+  uint8_t address, tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cIndex));
+  
+  /* Sets the base address */
+  address=PA_POWER8_BASE+7-cIndex;
+  
+  /* Reads the PA_LEVEL[cIndex] register and return the value */
+  g_xStatus = SpiritSpiReadRegisters(address, 1, &tempRegValue);
+  return tempRegValue;
+  
+}
+
+
+/**
+* @brief  Sets the output stage additional load capacitor bank.
+* @param  xCLoad one of the possible value of the enum type PALoadCapacitor.
+*         @arg LOAD_0_PF    No additional PA load capacitor
+*         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
+*         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
+*         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
+* @retval None.
+*/
+void SpiritRadioSetPACwc(PALoadCapacitor xCLoad)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_LOAD_CAP(xCLoad));
+  
+  /* Reads the PA_POWER_0 register */
+  SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the CWC[1:0] field and write the new value */
+  tempRegValue &= 0x3F;
+  tempRegValue |= xCLoad;
+  
+  /* Configures the PA_POWER_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the output stage additional load capacitor bank.
+* @param  None.
+* @retval PALoadCapacitor Output stage additional load capacitor bank.
+*         This parameter can be:
+*         @arg LOAD_0_PF    No additional PA load capacitor
+*         @arg LOAD_1_2_PF  1.2pF additional PA load capacitor
+*         @arg LOAD_2_4_PF  2.4pF additional PA load capacitor
+*         @arg LOAD_3_6_PF  3.6pF additional PA load capacitor
+*/
+PALoadCapacitor SpiritRadioGetPACwc(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the PA_POWER_0 register */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the CWC[1:0] field and return the value*/
+  return (PALoadCapacitor)(tempRegValue & 0xC0);
+  
+}
+
+
+/**
+* @brief  Sets a specific PA_LEVEL_MAX_INDEX.
+* @param  cIndex PA_LEVEL_MAX_INDEX to set. This parameter shall be in the range [0:7].
+* @retval None
+*/
+void SpiritRadioSetPALevelMaxIndex(uint8_t cIndex)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_MAX_INDEX(cIndex));
+  
+  /* Reads the PA_POWER_0 register */
+  SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the PA_LEVEL_MAX_INDEX[1:0] field and write the new value */
+  tempRegValue &= 0xF8;
+  tempRegValue |= cIndex;
+  
+  /* Configures the PA_POWER_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the actual PA_LEVEL_MAX_INDEX.
+* @param  None.
+* @retval uint8_t Actual PA_LEVEL_MAX_INDEX. This parameter will be in the range [0:7].
+*/
+uint8_t SpiritRadioGetPALevelMaxIndex(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the PA_POWER_0 register */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the PA_LEVEL_MAX_INDEX[1:0] field and return the value */
+  return (tempRegValue & 0x07);
+  
+}
+
+
+/**
+* @brief  Sets a specific PA_RAMP_STEP_WIDTH.
+* @param  cWidth step width expressed in terms of bit period units Tb/8.
+*         This parameter shall be in the range [1:4].
+* @retval None.
+*/
+void SpiritRadioSetPAStepWidth(uint8_t cWidth)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_PA_STEP_WIDTH(cWidth));
+  
+  /* Reads the PA_POWER_0 register */
+  SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the PA_RAMP_STEP_WIDTH[1:0] field and write the new value */
+  tempRegValue &= 0xE7;
+  tempRegValue |= (cWidth-1)<<3;
+  
+  /* Configures the PA_POWER_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the actual PA_RAMP_STEP_WIDTH.
+* @param  None.
+* @retval uint8_t Step width value expressed in terms of bit period units Tb/8.
+*         This parameter will be in the range [1:4].
+*/
+uint8_t SpiritRadioGetPAStepWidth(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the PA_POWER_0 register */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask the PA_RAMP_STEP_WIDTH[1:0] field and return the value */
+  tempRegValue &= 0x18;
+  return  ((tempRegValue>>3)+1);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the Power Ramping.
+* @param  xNewState new state for power ramping.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioPARamping(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
+  SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PA_POWER0_PA_RAMP_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~PA_POWER0_PA_RAMP_MASK);
+  }
+  
+  /* Sets the PA_POWER_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+}
+
+/**
+* @brief  Returns the Power Ramping enable bit.
+* @param  xNewState new state for power ramping.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+SpiritFunctionalState SpiritRadioGetPARamping(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
+  g_xStatus = SpiritSpiReadRegisters(PA_POWER0_BASE, 1, &tempRegValue);
+  
+  /* Mask and return data */
+  return (SpiritFunctionalState)((tempRegValue>>5) & 0x01);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the AFC.
+* @param  xNewState new state for AFC.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioAFC(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AFC_2 register and configure the AFC Enabled field */
+  SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AFC2_AFC_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AFC2_AFC_MASK);
+  }
+  
+  /* Sets the AFC_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the AFC freeze on sync word detection.
+* @param  xNewState new state for AFC freeze on sync word detection.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioAFCFreezeOnSync(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AFC_2 register and configure the AFC Freeze on Sync field */
+  SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AFC2_AFC_FREEZE_ON_SYNC_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AFC2_AFC_FREEZE_ON_SYNC_MASK);
+  }
+  
+  /* Sets the AFC_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Sets the AFC working mode.
+* @param  xMode the AFC mode. This parameter can be one of the values defined in @ref AFCMode :
+*         @arg AFC_SLICER_CORRECTION     AFC loop closed on slicer
+*         @arg AFC_2ND_IF_CORRECTION     AFC loop closed on 2nd conversion stage
+* @retval None.
+*/
+void SpiritRadioSetAFCMode(AFCMode xMode)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_AFC_MODE(xMode));
+  
+  /* Reads the AFC_2 register and configure the AFC Mode field */
+  SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  if(xMode == AFC_2ND_IF_CORRECTION)
+  {
+    tempRegValue |= AFC_2ND_IF_CORRECTION;
+  }
+  else
+  {
+    tempRegValue &= (~AFC_2ND_IF_CORRECTION);
+  }
+  
+  /* Sets the AFC_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AFC working mode.
+* @param  None.
+* @retval AFCMode Settled AFC mode. This parameter will be one of the values defined in @ref AFCMode :
+*         @arg AFC_SLICER_CORRECTION     AFC loop closed on slicer
+*         @arg AFC_2ND_IF_CORRECTION     AFC loop closed on 2nd conversion stage
+*/
+AFCMode SpiritRadioGetAFCMode(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC_2 register */
+  g_xStatus = SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+  /* Mask the AFC Mode field and returns the value */
+  return (AFCMode)(tempRegValue & 0x20);
+  
+}
+
+
+/**
+* @brief  Sets the AFC peak detector leakage.
+* @param  cLeakage the peak detector leakage. This parameter shall be in the range:
+*         [0:31].
+* @retval None.
+*/
+void SpiritRadioSetAFCPDLeakage(uint8_t cLeakage)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_AFC_PD_LEAKAGE(cLeakage));
+  
+  /* Reads the AFC_2 register and configure the AFC PD leakage field */
+  SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  tempRegValue &= 0xE0;
+  tempRegValue |= cLeakage;
+  
+  /* Sets the AFC_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AFC peak detector leakage.
+* @param  None.
+* @retval uint8_t Peak detector leakage value. This parameter will be in the range:
+*         [0:31].
+*/
+uint8_t SpiritRadioGetAFCPDLeakage(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC_2 register */
+  g_xStatus = SpiritSpiReadRegisters(AFC2_BASE, 1, &tempRegValue);
+  
+  /* Mask the AFC PD leakage field and return the value */
+  return (tempRegValue & 0x1F);
+  
+}
+
+
+/**
+* @brief  Sets the length of the AFC fast period expressed as number of samples.
+* @param  cLength length of the fast period in number of samples.
+* @retval None.
+*/
+void SpiritRadioSetAFCFastPeriod(uint8_t cLength)
+{
+  /* Sets the AFC_1 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC1_BASE, 1, &cLength);
+  
+}
+
+
+/**
+* @brief  Returns the AFC fast period expressed as number of samples.
+* @param  None.
+* @retval uint8_t Length of the fast period in number of samples.
+*/
+uint8_t SpiritRadioGetAFCFastPeriod(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC 1 register and return the value */
+  g_xStatus = SpiritSpiReadRegisters(AFC1_BASE, 1, &tempRegValue);
+  
+  return tempRegValue;
+  
+}
+
+
+/**
+* @brief  Sets the AFC loop gain in fast mode.
+* @param  cGain AFC loop gain in fast mode. This parameter shall be in the range:
+*         [0:15].
+* @retval None.
+*/
+void SpiritRadioSetAFCFastGain(uint8_t cGain)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_AFC_FAST_GAIN(cGain));
+  
+  /* Reads the AFC_0 register and configure the AFC Fast Gain field */
+  SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
+  tempRegValue &= 0x0F;
+  tempRegValue |= cGain<<4;
+  
+  /* Sets the AFC_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AFC loop gain in fast mode.
+* @param  None.
+* @retval uint8_t AFC loop gain in fast mode. This parameter will be in the range:
+*         [0:15].
+*/
+uint8_t SpiritRadioGetAFCFastGain(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC_0 register, mask the AFC Fast Gain field and return the value  */
+  g_xStatus = SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
+  
+  return ((tempRegValue & 0xF0)>>4);
+  
+}
+
+
+/**
+* @brief  Sets the AFC loop gain in slow mode.
+* @param  cGain AFC loop gain in slow mode. This parameter shall be in the range:
+*         [0:15].
+* @retval None.
+*/
+void SpiritRadioSetAFCSlowGain(uint8_t cGain)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_AFC_SLOW_GAIN(cGain));
+  
+  /* Reads the AFC_0 register and configure the AFC Slow Gain field */
+  SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
+  tempRegValue &= 0xF0;
+  tempRegValue |= cGain;
+  
+  /* Sets the AFC_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AFC0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AFC loop gain in slow mode.
+* @param  None.
+* @retval uint8_t AFC loop gain in slow mode. This parameter will be in the range:
+*         [0:15].
+*/
+uint8_t SpiritRadioGetAFCSlowGain(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC_0 register, mask the AFC Slow Gain field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(AFC0_BASE, 1, &tempRegValue);
+  
+  return (tempRegValue & 0x0F);
+  
+}
+
+
+/**
+* @brief  Returns the AFC correction from the corresponding register.
+* @param  None.
+* @retval int8_t AFC correction, read from the corresponding register.
+*         This parameter will be in the range [-128:127].
+*/
+int8_t SpiritRadioGetAFCCorrectionReg(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AFC_CORR register, cast the read value as signed char and return it */
+  g_xStatus = SpiritSpiReadRegisters(AFC_CORR_BASE, 1, &tempRegValue);
+  
+  return (int8_t)tempRegValue;
+  
+}
+
+
+/**
+* @brief  Returns the AFC correction expressed in Hz.
+* @param  None.
+* @retval int32_t AFC correction expressed in Hz
+*         according to the following formula:<ul>
+*         <li> Fafc[Hz]= (Fdig/(12*2^10))*AFC_CORR  where </li>
+*         <li> AFC_CORR is the value read in the AFC_CORR register </li> </ul>
+*/
+int32_t SpiritRadioGetAFCCorrectionHz(void)
+{
+  int8_t correction;
+  uint32_t xtal = s_lXtalFrequency;
+  
+  /* Reads the AFC correction register */
+  correction = SpiritRadioGetAFCCorrectionReg();
+  
+  if(xtal>DOUBLE_XTAL_THR)
+  {
+    xtal /= 2;
+  }
+  
+  /* Calculates and return the Frequency Correction */
+  return (int32_t)(xtal/(12*pow(2,10))*correction);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the AGC.
+* @param  xNewState new state for AGC.
+*         This parameter can be: S_ENABLE or S_DISABLE
+* @retval None.
+*/
+void SpiritRadioAGC(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AGCCTRL_0 register and configure the AGC Enabled field */
+  SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AGCCTRL0_AGC_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AGCCTRL0_AGC_MASK);
+  }
+  
+  /* Sets the AGCCTRL_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Sets the AGC working mode.
+* @param  xMode the AGC mode. This parameter can be one of the values defined in @ref AGCMode :
+*         @arg AGC_LINEAR_MODE     AGC works in linear mode
+*         @arg AGC_BINARY_MODE     AGC works in binary mode
+* @retval None.
+*/
+void SpiritRadioSetAGCMode(AGCMode xMode)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_AGC_MODE(xMode));
+  
+  /* Reads the AGCCTRL_0 register and configure the AGC Mode field */
+  SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  if(xMode == AGC_BINARY_MODE)
+  {
+    tempRegValue |= AGC_BINARY_MODE;
+  }
+  else
+  {
+    tempRegValue &= (~AGC_BINARY_MODE);
+  }
+  
+  /* Sets the AGCCTRL_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC working mode.
+* @param  None.
+* @retval AGCMode Settled AGC mode.  This parameter can be one of the values defined in @ref AGCMode :
+*         @arg AGC_LINEAR_MODE     AGC works in linear mode
+*         @arg AGC_BINARY_MODE     AGC works in binary mode
+*/
+AGCMode SpiritRadioGetAGCMode(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_0 register, mask the AGC Mode field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+  return  (AGCMode)(tempRegValue & 0x40);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the AGC freeze on steady state.
+* @param  xNewState new state for AGC freeze on steady state.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioAGCFreezeOnSteady(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AGCCTRL_2 register and configure the AGC Freeze On Steady field */
+  SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AGCCTRL2_FREEZE_ON_STEADY_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AGCCTRL2_FREEZE_ON_STEADY_MASK);
+  }
+  
+  /* Sets the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Enable or Disable the AGC freeze on sync detection.
+* @param  xNewState new state for AGC freeze on sync detection.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioAGCFreezeOnSync(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AGCCTRL_2 register and configure the AGC Freeze On Sync field */
+  SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AGCCTRL2_FREEZE_ON_SYNC_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AGCCTRL2_FREEZE_ON_SYNC_MASK);
+  }
+  
+  /* Sets the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Enable or Disable the AGC to start with max attenuation.
+* @param  xNewState new state for AGC start with max attenuation mode.
+*         This parameter can be: S_ENABLE or S_DISABLE.
+* @retval None.
+*/
+void SpiritRadioAGCStartMaxAttenuation(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue = 0x00;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the AGCCTRL_2 register and configure the AGC Start Max Attenuation field */
+  SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= AGCCTRL2_START_MAX_ATTENUATION_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~AGCCTRL2_START_MAX_ATTENUATION_MASK);
+  }
+  
+  /* Sets the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Sets the AGC measure time.
+* @param  nTime AGC measure time expressed in us. This parameter shall be in the range [0, 393216/F_Xo].
+* @retval None.
+*/
+void SpiritRadioSetAGCMeasureTimeUs(uint16_t nTime)
+{
+  uint8_t tempRegValue, measure;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_MEASURE_TIME_US(nTime,s_lXtalFrequency));
+  
+  /* Reads the AGCCTRL_2 register */
+  SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+  /* Calculates the measure time value to write in the register */
+  measure = (uint8_t)lroundf(log2((float)nTime/1e6 * s_lXtalFrequency/12));
+  (measure>15) ? (measure=15):(measure);
+  
+  /* Mask the MEAS_TIME field and write the new value */
+  tempRegValue &= 0xF0;
+  tempRegValue |= measure;
+  
+  /* Sets the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC measure time.
+* @param  None.
+* @retval uint16_t AGC measure time expressed in us. This parameter will be in the range [0, 393216/F_Xo].
+*/
+uint16_t SpiritRadioGetAGCMeasureTimeUs(void)
+{
+  uint8_t measure;
+  
+  /* Reads the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &measure);
+  
+  /* Mask the MEAS_TIME field */
+  measure &= 0x0F;
+  
+  /* Calculates the measure time value to write in the register */
+  return (uint16_t)((12.0/s_lXtalFrequency)*(float)pow(2,measure)*1e6);
+  
+}
+
+
+/**
+* @brief  Sets the AGC measure time.
+* @param  cTime AGC measure time to write in the MEAS_TIME field of AGCCTRL_2 register.
+*         This parameter shall be in the range [0:15].
+* @retval None.
+*/
+void SpiritRadioSetAGCMeasureTime(uint8_t cTime)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_MEASURE_TIME(cTime));
+  
+  /* Reads the AGCCTRL_2 register */
+  SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+  /* Mask the MEAS_TIME field and write the new value */
+  tempRegValue &= 0xF0;
+  tempRegValue |= cTime;
+  
+  /* Sets the AGCCTRL_2 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC measure time.
+* @param  None.
+* @retval uint8_t AGC measure time read from the MEAS_TIME field of AGCCTRL_2 register.
+*         This parameter will be in the range [0:15].
+*/
+uint8_t SpiritRadioGetAGCMeasureTime(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_2 register, mask the MEAS_TIME field and return the value  */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL2_BASE, 1, &tempRegValue);
+  
+  return (tempRegValue & 0x0F);
+  
+}
+
+
+/**
+* @brief  Sets the AGC hold time.
+* @param  cTime AGC hold time expressed in us. This parameter shall be in the range[0, 756/F_Xo].
+* @retval None.
+*/
+void SpiritRadioSetAGCHoldTimeUs(uint8_t cTime)
+{
+  uint8_t tempRegValue, hold;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_HOLD_TIME_US(cTime,s_lXtalFrequency));
+  
+  /* Reads the AGCCTRL_0 register */
+  SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+  /* Calculates the hold time value to write in the register */
+  hold = (uint8_t)lroundf(((float)cTime/1e6 * s_lXtalFrequency)/12);
+  (hold>63) ? (hold=63):(hold);
+  
+  /* Mask the HOLD_TIME field and write the new value */
+  tempRegValue &= 0xC0;
+  tempRegValue |= hold;
+  
+  /* Sets the AGCCTRL_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC hold time.
+* @param  None.
+* @retval uint8_t AGC hold time expressed in us. This parameter will be in the range:
+*         [0, 756/F_Xo].
+*/
+uint8_t SpiritRadioGetAGCHoldTimeUs(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_0 register */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+  /* Mask the HOLD_TIME field */
+  tempRegValue &= 0x3F;
+  
+  /* Calculates the hold time value and return it */
+  return (uint8_t)lroundf ((12.0/s_lXtalFrequency)*(tempRegValue*1e6));
+  
+}
+
+
+/**
+* @brief  Sets the AGC hold time.
+* @param  cTime AGC hold time to write in the HOLD_TIME field of AGCCTRL_0 register.
+*         This parameter shall be in the range [0:63].
+* @retval None.
+*/
+void SpiritRadioSetAGCHoldTime(uint8_t cTime)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_HOLD_TIME(cTime));
+  
+  /* Reads the AGCCTRL_0 register */
+  SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+  /* Mask the HOLD_TIME field and write the new value */
+  tempRegValue &= 0xC0;
+  tempRegValue |= cTime;
+  
+  /* Sets the AGCCTRL_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC hold time.
+* @param  None.
+* @retval uint8_t AGC hold time read from the HOLD_TIME field of AGCCTRL_0 register.
+*         This parameter will be in the range [0:63].
+*/
+uint8_t SpiritRadioGetAGCHoldTime(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_0 register, mask the MEAS_TIME field and return the value  */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL0_BASE, 1, &tempRegValue);
+  
+  return (tempRegValue & 0x3F);
+  
+}
+
+
+/**
+* @brief  Sets the AGC high threshold.
+* @param  cHighThreshold AGC high threshold to write in the THRESHOLD_HIGH field of AGCCTRL_1 register.
+*         This parameter shall be in the range [0:15].
+* @retval None.
+*/
+void SpiritRadioSetAGCHighThreshold(uint8_t cHighThreshold)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_THRESHOLD(cHighThreshold));
+  
+  /* Reads the AGCCTRL_1 register */
+  SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+  /* Mask the THRESHOLD_HIGH field and write the new value */
+  tempRegValue &= 0x0F;
+  tempRegValue |= cHighThreshold<<4;
+  
+  /* Sets the AGCCTRL_1 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC high threshold.
+* @param  None.
+* @retval uint8_t AGC high threshold read from the THRESHOLD_HIGH field of AGCCTRL_1 register.
+*         This parameter will be in the range [0:15].
+*/
+uint8_t SpiritRadioGetAGCHighThreshold(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_1 register, mask the THRESHOLD_HIGH field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+  return ((tempRegValue & 0xF0)>>4);
+  
+}
+
+
+/**
+* @brief  Sets the AGC low threshold.
+* @param  cLowThreshold AGC low threshold to write in the THRESHOLD_LOW field of AGCCTRL_1 register.
+*         This parameter shall be in the range [0:15].
+* @retval None.
+*/
+void SpiritRadioSetAGCLowThreshold(uint8_t cLowThreshold)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_AGC_THRESHOLD(cLowThreshold));
+  
+  /* Reads the AGCCTRL_1 register */
+  SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+  /* Mask the THRESHOLD_LOW field and write the new value */
+  tempRegValue &= 0xF0;
+  tempRegValue |= cLowThreshold;
+  
+  /* Sets the AGCCTRL_1 register */
+  g_xStatus = SpiritSpiWriteRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the AGC low threshold.
+* @param  None.
+* @retval uint8_t AGC low threshold read from the THRESHOLD_LOW field of AGCCTRL_1 register.
+*         This parameter will be in the range [0:15].
+*/
+uint8_t SpiritRadioGetAGCLowThreshold(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the AGCCTRL_1 register, mask the THRESHOLD_LOW field and return the value  */
+  g_xStatus = SpiritSpiReadRegisters(AGCCTRL1_BASE, 1, &tempRegValue);
+  
+  return (tempRegValue & 0x0F);
+  
+}
+
+
+/**
+* @brief  Sets the clock recovery algorithm.
+* @param  xMode the Clock Recovery mode. This parameter can be one of the values defined in @ref ClkRecMode :
+*         @arg CLK_REC_PLL     PLL alogrithm for clock recovery
+*         @arg CLK_REC_DLL     DLL alogrithm for clock recovery
+* @retval None.
+*/
+void SpiritRadioSetClkRecMode(ClkRecMode xMode)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_CLK_REC_MODE(xMode));
+  
+  /* Reads the FDEV_0 register */
+  SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
+  
+  /* Mask the CLOCK_REC_ALGO_SEL field and write the new value */
+  tempRegValue &= 0xF7;
+  tempRegValue |= (uint8_t)xMode;
+  
+  /* Sets the FDEV_0 register */
+  g_xStatus = SpiritSpiWriteRegisters(FDEV0_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the Clock Recovery working mode.
+* @param  None.
+* @retval ClkRecMode Clock Recovery mode. This parameter can be one of the values defined in @ref ClkRecMode :
+*         @arg CLK_REC_PLL     PLL alogrithm for clock recovery
+*         @arg CLK_REC_DLL     DLL alogrithm for clock recovery
+*/
+ClkRecMode SpiritRadioGetClkRecMode(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the FDEV_0 register, mask the CLOCK_REC_ALGO_SEL field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(FDEV0_BASE, 1, &tempRegValue);
+  
+  return (ClkRecMode)(tempRegValue & 0x08);
+  
+}
+
+
+/**
+* @brief  Sets the clock recovery proportional gain.
+* @param  cPGain the Clock Recovery proportional gain to write in the CLK_REC_P_GAIN field of CLOCKREC register.
+*         It represents is log2 value of the clock recovery proportional gain.
+*          This parameter shall be in the range [0:7].
+* @retval None.
+*/
+void SpiritRadioSetClkRecPGain(uint8_t cPGain)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_CLK_REC_P_GAIN(cPGain));
+  
+  /* Reads the CLOCKREC register */
+  SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  /* Mask the CLK_REC_P_GAIN field and write the new value */
+  tempRegValue &= 0x1F;
+  tempRegValue |= (cPGain<<5);
+  
+  /* Sets the CLOCKREC register */
+  g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the log2 of the clock recovery proportional gain.
+* @param  None.
+* @retval uint8_t Clock Recovery proportional gain read from the CLK_REC_P_GAIN field of CLOCKREC register.
+*         This parameter will be in the range [0:7].
+*/
+uint8_t SpiritRadioGetClkRecPGain(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the CLOCKREC register, mask the CLK_REC_P_GAIN field and return the value  */
+  g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  return ((tempRegValue & 0xEF)>>5);
+  
+}
+
+
+/**
+* @brief  Sets the clock recovery integral gain.
+* @param  cIGain the Clock Recovery integral gain to write in the CLK_REC_I_GAIN field of CLOCKREC register.
+*         This parameter shall be in the range [0:15].
+* @retval None.
+*/
+void SpiritRadioSetClkRecIGain(uint8_t cIGain)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_CLK_REC_I_GAIN(cIGain));
+  
+  /* Reads the CLOCKREC register */
+  SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  /* Mask the CLK_REC_P_GAIN field and write the new value */
+  tempRegValue &= 0xF0;
+  tempRegValue |= cIGain;
+  
+  /* Sets the CLOCKREC register */
+  g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the clock recovery integral gain.
+* @param  None.
+* @retval uint8_t Clock Recovery integral gain read from the
+*         CLK_REC_I_GAIN field of CLOCKREC register.
+*         This parameter will be in the range [0:15].
+*/
+uint8_t SpiritRadioGetClkRecIGain(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the CLOCKREC register, mask the CLK_REC_I_GAIN field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  return (tempRegValue & 0x0F);
+  
+}
+
+
+/**
+* @brief  Sets the postfilter length for clock recovery algorithm.
+* @param  xLength the postfilter length in symbols. This parameter can be one of the values defined in @ref PstFltLength :
+*         @arg PSTFLT_LENGTH_8     Postfilter length is 8 symbols
+*         @arg PSTFLT_LENGTH_16    Postfilter length is 16 symbols
+* @retval None.
+*/
+void SpiritRadioSetClkRecPstFltLength(PstFltLength xLength)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameter */
+  s_assert_param(IS_PST_FLT_LENGTH(xLength));
+  
+  /* Reads the CLOCKREC register */
+  SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  /* Mask the PSTFLT_LEN field and write the new value */
+  tempRegValue &= 0xEF;
+  tempRegValue |= (uint8_t)xLength;
+  
+  /* Sets the CLOCKREC register */
+  g_xStatus = SpiritSpiWriteRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+}
+
+
+/**
+* @brief  Returns the postfilter length for clock recovery algorithm.
+* @param  None.
+* @retval PstFltLength Postfilter length in symbols. This parameter can be one of the values defined in @ref PstFltLength :
+*         @arg PSTFLT_LENGTH_8     Postfilter length is 8 symbols
+*         @arg PSTFLT_LENGTH_16    Postfilter length is 16 symbols
+*/
+PstFltLength SpiritRadioGetClkRecPstFltLength(void)
+{
+  uint8_t tempRegValue;
+  
+  /* Reads the CLOCKREC register, mask the PSTFLT_LEN field and return the value */
+  g_xStatus = SpiritSpiReadRegisters(CLOCKREC_BASE, 1, &tempRegValue);
+  
+  return (PstFltLength)(tempRegValue & 0x10);
+  
+}
+
+
+/**
+* @brief  Enables or Disables the received data blanking when the CS is under the threshold.
+* @param  xNewState new state of this mode.
+*         This parameter can be: S_ENABLE or S_DISABLE .
+* @retval None.
+*/
+void SpiritRadioCsBlanking(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the ANT_SELECT_CONF_BASE and mask the CS_BLANKING BIT field */
+  SpiritSpiReadRegisters(ANT_SELECT_CONF_BASE, 1, &tempRegValue);
+  
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= ANT_SELECT_CS_BLANKING_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~ANT_SELECT_CS_BLANKING_MASK);
+  }
+  
+  /* Writes the new value in the ANT_SELECT_CONF register */
+  g_xStatus = SpiritSpiWriteRegisters(ANT_SELECT_CONF_BASE, 1, &tempRegValue);
+  
+  
+}
+
+/**
+* @brief  Enables or Disables the persistent RX mode.
+* @param  xNewState new state of this mode.
+*         This parameter can be: S_ENABLE or S_DISABLE .
+* @retval None.
+*/
+void SpiritRadioPersistenRx(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */
+  SpiritSpiReadRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+  
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL0_PERS_RX_MASK;
+  }
+  else
+  {
+    tempRegValue &= (~PROTOCOL0_PERS_RX_MASK);
+  }
+  
+  /* Writes the new value in the PROTOCOL0_BASE register */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL0_BASE, 1, &tempRegValue);
+  
+}
+
+/**
+* @brief  Enables or Disables the synthesizer reference divider.
+* @param  xNewState new state for synthesizer reference divider.
+*         This parameter can be: S_ENABLE or S_DISABLE .
+* @retval None.
+*/
+void SpiritRadioSetRefDiv(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the SYNTH_CONFIG1_BASE and mask the REFDIV bit field */
+  SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+  
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue |= 0x80;
+  }
+  else
+  {
+    tempRegValue &= 0x7F;
+  }
+  
+  /* Writes the new value in the SYNTH_CONFIG1_BASE register */
+  g_xStatus = SpiritSpiWriteRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+  
+}
+
+/**
+* @brief  Get the the synthesizer reference divider state.
+* @param  void.
+* @retval None.
+*/
+SpiritFunctionalState SpiritRadioGetRefDiv(void)
+{
+  uint8_t tempRegValue;
+  
+  g_xStatus = SpiritSpiReadRegisters(SYNTH_CONFIG1_BASE, 1, &tempRegValue);
+  
+  if(((tempRegValue>>7)&0x1))
+  {
+    return S_ENABLE;
+  }
+  else
+  {
+    return S_DISABLE;
+  }
+  
+}
+
+/**
+* @brief  Enables or Disables the synthesizer reference divider.
+* @param  xNewState new state for synthesizer reference divider.
+*         This parameter can be: S_ENABLE or S_DISABLE .
+* @retval None.
+*/
+void SpiritRadioSetDigDiv(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+  
+  /* Check the parameters */
+  s_assert_param(IS_SPIRIT_FUNCTIONAL_STATE(xNewState));
+  
+  /* Reads the XO_RCO_TEST_BASE and mask the PD_CLKDIV bit field */
+  SpiritSpiReadRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
+  
+  if(xNewState == S_ENABLE)
+  {
+    tempRegValue &= 0xf7;
+  }
+  else
+  {
+    
+    tempRegValue |= 0x08;
+  }
+  
+  /* Writes the new value in the XO_RCO_TEST_BASE register */
+  g_xStatus = SpiritSpiWriteRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
+  
+}
+
+/**
+* @brief  Get the the synthesizer reference divider state.
+* @param  void.
+* @retval None.
+*/
+SpiritFunctionalState SpiritRadioGetDigDiv(void)
+{
+  uint8_t tempRegValue;
+  
+  g_xStatus = SpiritSpiReadRegisters(XO_RCO_TEST_BASE, 1, &tempRegValue);
+  
+  if(((tempRegValue>>3)&0x1))
+  {
+    return S_DISABLE;
+  }
+  else
+  {
+    return S_ENABLE;
+  }
+  
+}
+
+/**
+* @brief  Returns the XTAL frequency.
+* @param  void.
+* @retval uint32_t XTAL frequency.
+*/
+uint32_t SpiritRadioGetXtalFrequency(void)
+{
+  return s_lXtalFrequency; 
+}
+
+/**
+* @brief  Sets the XTAL frequency.
+* @param  uint32_t XTAL frequency.
+* @retval void.
+*/
+void SpiritRadioSetXtalFrequency(uint32_t lXtalFrequency)
+{
+  s_lXtalFrequency = lXtalFrequency; 
+}
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Timer.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Timer.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,700 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Timer.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   Configuration and management of SPIRIT timers.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Timer.h"
+#include "SPIRIT_Radio.h"
+#include "MCU_Interface.h"
+
+
+
+
+/**
+ * @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/**
+ * @addtogroup SPIRIT_Timer
+ * @{
+ */
+
+
+/**
+ * @defgroup Timer_Private_TypesDefinitions             Timer Private Types Definitions
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Timer_Private_Defines                      Timer Private Defines
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Timer_Private_Macros                       Timer Private Macros
+ * @{
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Timer_Private_Variables                    Timer Private Variables
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Timer_Private_FunctionPrototypes            Timer Private Function Prototypes
+ * @{
+ */
+
+/**
+ *@}
+ */
+
+
+/**
+ * @defgroup Timer_Private_Functions                    Timer Private Functions
+ * @{
+ */
+
+/**
+ * @brief  Enables or Disables the LDCR mode.
+ * @param  xNewState new state for LDCR mode.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritTimerLdcrMode(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+  /* Mask the read value to enable or disable the LDC mode */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL2_LDC_MODE_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL2_LDC_MODE_MASK;
+  }
+
+  /* Writes the register to Enable or Disable the LDCR mode */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL2_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Enables or Disables the LDCR timer reloading with the value stored in the LDCR_RELOAD registers.
+ * @param  xNewState new state for LDCR reloading.
+ *         This parameter can be: S_ENABLE or S_DISABLE.
+ * @retval None.
+ */
+void SpiritTimerLdcrAutoReload(SpiritFunctionalState xNewState)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  /* Mask te read value to enable or disable the reload on sync mode */
+  if(xNewState==S_ENABLE)
+  {
+    tempRegValue |= PROTOCOL1_LDC_RELOAD_ON_SYNC_MASK;
+  }
+  else
+  {
+    tempRegValue &= ~PROTOCOL1_LDC_RELOAD_ON_SYNC_MASK;
+  }
+
+  /* Writes the register to Enable or Disable the Auto Reload */
+  g_xStatus = SpiritSpiWriteRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+}
+
+
+/**
+ * @brief  Returns the LDCR timer reload bit.
+ * @param  None.
+ * @retval SpiritFunctionalState: value of the reload bit.
+ */
+SpiritFunctionalState SpiritTimerLdcrGetAutoReload(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the register value */
+  g_xStatus = SpiritSpiReadRegisters(PROTOCOL1_BASE, 1, &tempRegValue);
+
+  return (SpiritFunctionalState)(tempRegValue & 0x80);
+
+}
+
+/**
+ * @brief  Sets the RX timeout timer initialization registers with the values of COUNTER and PRESCALER according to the formula: Trx=PRESCALER*COUNTER*Tck.
+ *         Remember that it is possible to have infinite RX_Timeout writing 0 in the RX_Timeout_Counter and/or RX_Timeout_Prescaler registers.
+ * @param  cCounter value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @param  cPrescaler value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetRxTimeout(uint8_t cCounter , uint8_t cPrescaler)
+{
+  uint8_t tempRegValue[2]={cPrescaler,cCounter};
+
+  /* Writes the prescaler and counter value for RX timeout in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS5_RX_TIMEOUT_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the RX timeout timer counter and prescaler from the desired value in ms. it is possible to fix the RX_Timeout to
+ *         a minimum value of 50.417us to a maximum value of about 3.28 s.
+ * @param  fDesiredMsec desired timer value.
+ *         This parameter must be a float.
+ * @retval None
+ */
+
+void SpiritTimerSetRxTimeoutMs(float fDesiredMsec)
+{
+  uint8_t tempRegValue[2];
+
+  /* Computes the counter and prescaler value */
+  SpiritTimerComputeRxTimeoutValues(fDesiredMsec , &tempRegValue[1] , &tempRegValue[0]);
+
+  /* Writes the prescaler and counter value for RX timeout in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS5_RX_TIMEOUT_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the RX timeout timer counter. If it is equal to 0 the timeout is infinite.
+ * @param  cCounter value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetRxTimeoutCounter(uint8_t cCounter)
+{
+  /* Writes the counter value for RX timeout in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS4_RX_TIMEOUT_COUNTER_BASE, 1, &cCounter);
+
+}
+
+
+/**
+ * @brief  Sets the RX timeout timer prescaler. If it is equal to 0 the timeout is infinite.
+ * @param  cPrescaler value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None
+ */
+void SpiritTimerSetRxTimeoutPrescaler(uint8_t cPrescaler)
+{
+  /* Writes the prescaler value for RX timeout in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS5_RX_TIMEOUT_PRESCALER_BASE, 1, &cPrescaler);
+
+}
+
+
+/**
+ * @brief  Returns the RX timeout timer.
+ * @param  pfTimeoutMsec pointer to the variable in which the timeout expressed in milliseconds has to be stored.
+ *         If the returned value is 0, it means that the RX_Timeout is infinite.
+ *         This parameter must be a float*.
+ * @param  pcCounter pointer to the variable in which the timer counter has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @param  pcPrescaler pointer to the variable in which the timer prescaler has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @retval None.
+ */
+void SpiritTimerGetRxTimeout(float* pfTimeoutMsec, uint8_t* pcCounter , uint8_t* pcPrescaler)
+{
+  uint8_t tempRegValue[2];
+
+  /* Reads the RX timeout registers value */
+  g_xStatus = SpiritSpiReadRegisters(TIMERS5_RX_TIMEOUT_PRESCALER_BASE, 2, tempRegValue);
+
+  /* Returns values */
+  (*pcPrescaler) = tempRegValue[0];
+  (*pcCounter) = tempRegValue[1];
+    
+  float nXtalFrequency = (float)SpiritRadioGetXtalFrequency();
+  if(nXtalFrequency>DOUBLE_XTAL_THR) {
+    nXtalFrequency /= 2.0;
+  }
+  nXtalFrequency /= 1000.0;
+  *pfTimeoutMsec = (float)((tempRegValue[0]+1)*tempRegValue[1]*(1210.0/nXtalFrequency));
+  
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer initialization registers with the values of
+ *         COUNTER and PRESCALER according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where
+ *         Tck = 28.818 us. The minimum vale of the wakeup timeout is 28.818us (PRESCALER and
+ *         COUNTER equals to 0) and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals
+ *         to 255).
+ * @param  cCounter value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @param  cPrescaler value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimer(uint8_t cCounter , uint8_t cPrescaler)
+{
+  uint8_t tempRegValue[2]={cPrescaler,cCounter};
+
+  /* Writes the counter and prescaler value of wake-up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS3_LDC_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer counter and prescaler from the desired value in ms,
+ *         according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us.
+ *         The minimum vale of the wakeup timeout is 28.818us (PRESCALER and COUNTER equals to 0)
+ *         and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals to 255).
+ * @param  fDesiredMsec desired timer value.
+ *         This parameter must be a float.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimerMs(float fDesiredMsec)
+{
+  uint8_t tempRegValue[2];
+
+  /* Computes counter and prescaler */
+  SpiritTimerComputeWakeUpValues(fDesiredMsec , &tempRegValue[1] , &tempRegValue[0]);
+
+  /* Writes the counter and prescaler value of wake-up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS3_LDC_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer counter. Remember that this value is incresead by one in the Twu calculation.
+ *         Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us
+ * @param  cCounter value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimerCounter(uint8_t cCounter)
+{
+  /* Writes the counter value for Wake_Up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS2_LDC_COUNTER_BASE, 1, &cCounter);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer prescaler. Remember that this value is incresead by one in the Twu calculation.
+ *         Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us
+ * @param  cPrescaler value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimerPrescaler(uint8_t cPrescaler)
+{
+  /* Writes the prescaler value for Wake_Up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS3_LDC_PRESCALER_BASE, 1, &cPrescaler);
+
+}
+
+
+/**
+ * @brief  Returns the LDCR wake up timer, according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us.
+ * @param  pfWakeUpMsec pointer to the variable in which the wake-up time expressed in milliseconds has to be stored.
+ *         This parameter must be a float*.
+ * @param  pcCounter pointer to the variable in which the timer counter has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @param  pcPrescaler pointer to the variable in which the timer prescaler has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @retval None.
+ */
+void SpiritTimerGetWakeUpTimer(float* pfWakeUpMsec, uint8_t* pcCounter , uint8_t* pcPrescaler)
+{
+  uint8_t tempRegValue[2];
+  //uint32_t xtal=SpiritRadioGetXtalFrequency();
+  float rco_freq;
+  
+  rco_freq=(float)SpiritTimerGetRcoFrequency();
+  
+  /* Reads the Wake_Up timer registers value */
+  g_xStatus = SpiritSpiReadRegisters(TIMERS3_LDC_PRESCALER_BASE, 2, tempRegValue);
+
+  /* Returns values */
+  (*pcPrescaler)=tempRegValue[0];
+  (*pcCounter)=tempRegValue[1];
+  *pfWakeUpMsec = (float)((((*pcPrescaler)+1)*((*pcCounter)+1)*(1000.0/rco_freq)));
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer reloading registers with the values of
+ *         COUNTER and PRESCALER according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where
+ *         Tck = 28.818 us. The minimum vale of the wakeup timeout is 28.818us (PRESCALER and
+ *         COUNTER equals to 0) and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals
+ *         to 255).
+ * @param  cCounter reload value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @param  cPrescaler reload value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimerReload(uint8_t cCounter , uint8_t cPrescaler)
+{
+  uint8_t tempRegValue[2]={cPrescaler,cCounter};
+
+  /* Writes the counter and prescaler value of reload wake-up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS1_LDC_RELOAD_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up reload timer counter and prescaler from the desired value in ms,
+ *         according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us.
+ *         The minimum vale of the wakeup timeout is 28.818us (PRESCALER and COUNTER equals to 0)
+ *         and the maximum value is about 1.89 s (PRESCALER anc COUNTER equals to 255).
+ * @param  fDesiredMsec desired timer value.
+ *         This parameter must be a float.
+ * @retval None.
+ */
+void SpiritTimerSetWakeUpTimerReloadMs(float fDesiredMsec)
+{
+  uint8_t tempRegValue[2];
+
+  /* Computes counter and prescaler */
+  SpiritTimerComputeWakeUpValues(fDesiredMsec , &tempRegValue[1] , &tempRegValue[0]);
+
+  /* Writes the counter and prescaler value of reload wake-up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS1_LDC_RELOAD_PRESCALER_BASE, 2, tempRegValue);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer reload counter. Remember that this value is incresead by one in the Twu calculation.
+ *         Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us
+ * @param  cCounter value for the timer counter.
+ *         This parameter must be an uint8_t.
+ * @retval None
+ */
+void SpiritTimerSetWakeUpTimerReloadCounter(uint8_t cCounter)
+{
+  /* Writes the counter value for reload Wake_Up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS0_LDC_RELOAD_COUNTER_BASE, 1, &cCounter);
+
+}
+
+
+/**
+ * @brief  Sets the LDCR wake up timer reload prescaler. Remember that this value is incresead by one in the Twu calculation.
+ *         Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us
+ * @param  cPrescaler value for the timer prescaler.
+ *         This parameter must be an uint8_t.
+ * @retval None
+ */
+void SpiritTimerSetWakeUpTimerReloadPrescaler(uint8_t cPrescaler)
+{
+  /* Writes the prescaler value for reload Wake_Up timer in the corresponding register */
+  g_xStatus = SpiritSpiWriteRegisters(TIMERS1_LDC_RELOAD_PRESCALER_BASE, 1, &cPrescaler);
+
+}
+
+
+/**
+ * @brief  Returns the LDCR wake up reload timer, according to the formula: Twu=(PRESCALER +1)*(COUNTER+1)*Tck, where Tck = 28.818 us.
+ * @param  pfWakeUpReloadMsec pointer to the variable in which the wake-up reload time expressed in milliseconds has to be stored.
+ *         This parameter must be a float*.
+ * @param  pcCounter pointer to the variable in which the timer counter has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @param  pcPrescaler pointer to the variable in which the timer prescaler has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @retval None.
+ */
+void SpiritTimerGetWakeUpTimerReload(float* pfWakeUpReloadMsec, uint8_t* pcCounter , uint8_t* pcPrescaler)
+{
+  uint8_t tempRegValue[2];
+  //uint32_t xtal=SpiritRadioGetXtalFrequency();
+  float rco_freq;
+  
+  rco_freq=(float)SpiritTimerGetRcoFrequency();
+  
+  /* Reads the reload Wake_Up timer registers value */
+  g_xStatus = SpiritSpiReadRegisters(TIMERS1_LDC_RELOAD_PRESCALER_BASE, 2, tempRegValue);
+
+  /* Returns values */
+  (*pcPrescaler)=tempRegValue[0];
+  (*pcCounter)=tempRegValue[1];
+  *pfWakeUpReloadMsec = (float)((((*pcPrescaler)+1)*((*pcCounter)+1)*(1000.0/rco_freq)));
+
+}
+
+/**
+ * @brief  Computes and returns the RCO frequency. 
+ *         This frequency depends on the xtal frequency and the XTAL bit in register 0x01.
+ * @retval RCO frequency in Hz as an uint16_t.
+ */
+uint16_t SpiritTimerGetRcoFrequency(void)
+{
+  uint16_t rco_freq=34700;
+  uint32_t xtal=SpiritRadioGetXtalFrequency();
+  
+  if(xtal>30000000) xtal/=2;
+  
+  if(xtal==25000000)
+  {
+    uint8_t xtal_flag;
+    SpiritSpiReadRegisters(0x01, 1, &xtal_flag);
+    xtal_flag=(xtal_flag&0x40);
+    
+    if(xtal_flag==0)
+    {
+      rco_freq=36100;
+    }
+    else
+    {
+      rco_freq=33300;
+    }
+  }
+  
+  return rco_freq;
+}
+
+/**
+ * @brief  Computes the values of the wakeup timer counter and prescaler from the user time expressed in millisecond.
+ *         The prescaler and the counter values are computed maintaining the prescaler value as
+ *         small as possible in order to obtain the best resolution, and in the meantime minimizing the error.
+ * @param  fDesiredMsec desired wakeup timeout in millisecs.
+ *         This parameter must be a float. Since the counter and prescaler are 8 bit registers the maximum
+ *         reachable value is maxTime = fTclk x 256 x 256.
+ * @param  pcCounter pointer to the variable in which the value for the wakeup timer counter has to be stored.
+ *         This parameter must be a uint8_t*.
+ * @param  pcPrescaler pointer to the variable in which the value for the wakeup timer prescaler has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @retval None
+ */
+void SpiritTimerComputeWakeUpValues(float fDesiredMsec , uint8_t* pcCounter , uint8_t* pcPrescaler)
+{
+  float rco_freq,err;
+  uint32_t n;
+  
+  rco_freq=((float)SpiritTimerGetRcoFrequency())/1000;
+  
+  /* N cycles in the time base of the timer: 
+     - clock of the timer is RCO frequency
+     - divide times 1000 more because we have an input in ms (variable rco_freq is already this frequency divided by 1000)
+  */
+  n=(uint32_t)(fDesiredMsec*rco_freq);
+    
+  /* check if it is possible to reach that target with prescaler and counter of spirit1 */
+  if(n/0xFF>0xFD)
+  {
+    /* if not return the maximum possible value */
+    (*pcCounter) = 0xFF;
+    (*pcPrescaler) = 0xFF;
+    return;
+  }
+  
+  /* prescaler is really 2 as min value */
+  (*pcPrescaler)=(n/0xFF)+2;
+  (*pcCounter) = n / (*pcPrescaler);
+  
+  /* check if the error is minimum */
+  err=S_ABS((float)(*pcCounter)*(*pcPrescaler)/rco_freq-fDesiredMsec);
+  
+  if((*pcCounter)<=254)
+  {
+    if(S_ABS((float)((*pcCounter)+1)*(*pcPrescaler)/rco_freq-fDesiredMsec)<err)
+      (*pcCounter)=(*pcCounter)+1;
+  }
+    
+  /* decrement prescaler and counter according to the logic of this timer in spirit1 */
+  (*pcPrescaler)--;
+  if((*pcCounter)>1)
+    (*pcCounter)--;
+  else
+    (*pcCounter)=1;
+}
+
+
+/**
+ * @brief  Computes the values of the rx_timeout timer counter and prescaler from the user time expressed in millisecond.
+ *         The prescaler and the counter values are computed maintaining the prescaler value as
+ *         small as possible in order to obtain the best resolution, and in the meantime minimizing the error.
+ * @param  fDesiredMsec desired rx_timeout in millisecs.
+ *         This parameter must be a float. Since the counter and prescaler are 8 bit registers the maximum
+ *         reachable value is maxTime = fTclk x 255 x 255.
+ * @param  pcCounter pointer to the variable in which the value for the rx_timeout counter has to be stored.
+ *         This parameter must be a uint8_t*.
+ * @param  pcPrescaler pointer to the variable in which the value for the rx_timeout prescaler has to be stored.
+ *         This parameter must be an uint8_t*.
+ * @retval None
+ */
+void SpiritTimerComputeRxTimeoutValues(float fDesiredMsec , uint8_t* pcCounter , uint8_t* pcPrescaler)
+{
+  uint32_t nXtalFrequency = SpiritRadioGetXtalFrequency();
+  uint32_t n;
+  float err;
+  
+  /* if xtal is doubled divide it by 2 */
+  if(nXtalFrequency>DOUBLE_XTAL_THR) {
+    nXtalFrequency >>= 1;
+  }
+  
+  /* N cycles in the time base of the timer: 
+     - clock of the timer is xtal/1210
+     - divide times 1000 more because we have an input in ms
+  */
+  n=(uint32_t)(fDesiredMsec*nXtalFrequency/1210000);
+  
+  /* check if it is possible to reach that target with prescaler and counter of spirit1 */
+  if(n/0xFF>0xFD)
+  {
+    /* if not return the maximum possible value */
+    (*pcCounter) = 0xFF;
+    (*pcPrescaler) = 0xFF;
+    return;
+  }
+  
+  /* prescaler is really 2 as min value */
+  (*pcPrescaler)=(n/0xFF)+2;
+  (*pcCounter) = n / (*pcPrescaler);
+  
+  /* check if the error is minimum */
+  err=S_ABS((float)(*pcCounter)*(*pcPrescaler)*1210000/nXtalFrequency-fDesiredMsec);
+  
+  if((*pcCounter)<=254)
+  {
+    if(S_ABS((float)((*pcCounter)+1)*(*pcPrescaler)*1210000/nXtalFrequency-fDesiredMsec)<err)
+      (*pcCounter)=(*pcCounter)+1;
+  }
+    
+  /* decrement prescaler and counter according to the logic of this timer in spirit1 */
+  (*pcPrescaler)--;
+  if((*pcCounter)>1)
+    (*pcCounter)--;
+  else
+    (*pcCounter)=1;
+}
+
+
+/**
+ * @brief  Sets the RX timeout stop conditions.
+ * @param  xStopCondition new stop condition.
+ *         This parameter can be any value of @ref RxTimeoutStopCondition.
+ * @retval None
+ */
+void SpiritTimerSetRxTimeoutStopCondition(RxTimeoutStopCondition xStopCondition)
+{
+  uint8_t tempRegValue[2];
+
+  /* Check the parameters */
+  s_assert_param(IS_RX_TIMEOUT_STOP_CONDITION(xStopCondition));
+
+  /* Reads value on the PKT_FLT_OPTIONS and PROTOCOL2 register */
+  g_xStatus = SpiritSpiReadRegisters(PCKT_FLT_OPTIONS_BASE, 2, tempRegValue);
+
+  tempRegValue[0] &= 0xBF;
+  tempRegValue[0] |= ((xStopCondition & 0x08)  << 3);
+
+  tempRegValue[1] &= 0x1F;
+  tempRegValue[1] |= (xStopCondition << 5);
+
+  /* Writes value on the PKT_FLT_OPTIONS and PROTOCOL2 register */
+  g_xStatus = SpiritSpiWriteRegisters(PCKT_FLT_OPTIONS_BASE, 2, tempRegValue);
+
+}
+
+/**
+ * @brief  Sends the LDC_RELOAD command to SPIRIT. Reload the LDC timer with the value stored in the LDC_PRESCALER / COUNTER registers.
+ * @param  None.
+ * @retval None
+ */
+void SpiritTimerReloadStrobe(void)
+{
+  /* Sends the CMD_LDC_RELOAD command */
+  g_xStatus = SpiritSpiCommandStrobes(COMMAND_LDC_RELOAD);
+
+}
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+/**
+ *@}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Types.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/SPIRIT1_Library/Src/SPIRIT_Types.c	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,225 @@
+/**
+  ******************************************************************************
+  * @file    SPIRIT_Types.c
+  * @author  VMA division - AMS
+  * @version 3.2.2
+  * @date    08-July-2015
+  * @brief   File for SPIRIT types.
+  * @details
+  *
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "SPIRIT_Types.h"
+#include "MCU_Interface.h"
+
+
+/** @addtogroup SPIRIT_Libraries
+ * @{
+ */
+
+
+/** @addtogroup SPIRIT_Types
+ * @{
+ */
+
+
+/** @defgroup Types_Private_TypesDefinitions    Types Private Types Definitions
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Types_Private_Defines             Types Private Defines
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Types_Private_Macros               Types Private Macros
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Types_Private_Variables             Types Private Variables
+ * @{
+ */
+
+/**
+ * @brief  Spirit Status global variable.
+ *         This global variable of @ref SpiritStatus type is updated on every SPI transaction
+ *         to maintain memory of Spirit Status.
+ */
+
+volatile SpiritStatus g_xStatus;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Types_Private_FunctionPrototypes       Types Private FunctionPrototypes
+ * @{
+ */
+
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup Types_Private_Functions                 Types Private Functions
+ * @{
+ */
+
+#ifdef  SPIRIT_USE_FULL_ASSERT
+/**
+ * @brief  Reports the name of the source file and the source line number
+ *         where the assert_param error has occurred.
+ * @param file  pointer to the source file name
+ * @param line  assert_param error line source number
+ * @retval : None
+ */
+void s_assert_failed(uint8_t* file, uint32_t line)
+{
+  /* User can add his own implementation to report the file name and line number */
+  printf("Wrong parameters value: file %s on line %d\r\n", file, (int)line);
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+#elif SPIRIT_USE_VCOM_ASSERT
+
+#include "SDK_EVAL_VC_General.h"
+
+/**
+ * @brief  Reports the name of the source file and the source line number
+ *         where the assert_param error has occurred.
+ * @param file pointer to the source file name
+ * @param line  assert_param error line source number
+ * @param expression: string representing the assert failed expression
+ * @retval : None
+ */
+void s_assert_failed(uint8_t* file, uint32_t line, char* expression)
+{
+
+  printf("\n\rVCOM DEBUG: Incorrect parameter. Please reboot.\n\r");
+  printf("%s:%d \n\r",file,line);
+  printf("The expression %s returned FALSE.\n\r", expression);
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+
+#elif SPIRIT_USE_FRAME_ASSERT
+
+#include "SdkUsbProtocol.h"
+
+/**
+ * @brief Sends a notify frame with a payload indicating the name 
+ *        of the assert failed.
+ * @param expression: string representing the assert failed expression
+ * @retval : None
+ */
+void s_assert_failed(char* expression)
+{
+  char pcPayload[100];
+  uint16_t i;
+  
+  for(i = 0 ; expression[i]!='(' ; i++);
+  expression[i]='\0';
+  
+  strcpy(pcPayload, &expression[3]);
+  
+  //sprintf(pcPayload, "The expression %s returned FALSE.\n\r", expression);
+  SpiritNotifyAssertFailed(pcPayload);
+
+}
+
+#endif
+
+
+/**
+ * @brief  Updates the gState (the global variable used to maintain memory of Spirit Status)
+ *         reading the MC_STATE register of SPIRIT.
+ * @param  None
+ * @retval None
+ */
+void SpiritRefreshStatus(void)
+{
+  uint8_t tempRegValue;
+
+  /* Reads the MC_STATUS register to update the g_xStatus */
+  g_xStatus = SpiritSpiReadRegisters(MC_STATE1_BASE, 1, &tempRegValue);
+}
+
+
+/**
+ * @}
+ */
+
+
+
+/**
+ * @}
+ */
+
+
+
+/**
+ * @}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_gpio.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_gpio.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,224 @@
+/**
+******************************************************************************
+* @file    radio_gpio.h
+* @author  System Lab - NOIDA
+* @version V1.0.0
+* @date    15-May-2014
+* @brief   This file contains all the functions prototypes for the gpio  
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*      without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported Variables ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __RADIO_GPIO_H
+#define __RADIO_GPIO_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+/* Includes ------------------------------------------------------------------*/
+#ifdef USE_STM32L1XX_NUCLEO
+#include "stm32l1xx_hal.h"
+#endif
+
+#ifdef USE_STM32F4XX_NUCLEO
+#include "stm32f4xx_hal.h"
+#endif
+#include "SPIRIT_Types.h"
+  
+/**
+ * @addtogroup BSP
+ * @{
+ */
+
+
+/* Exported types ------------------------------------------------------------*/
+  /* MCU GPIO pin working mode for GPIO */
+typedef enum                                                                                          
+{
+    RADIO_MODE_GPIO_IN  = 0x00,   /*!< Work as GPIO input */
+    RADIO_MODE_EXTI_IN,           /*!< Work as EXTI */
+    RADIO_MODE_GPIO_OUT,          /*!< Work as GPIO output */
+}RadioGpioMode;  
+
+ /* MCU GPIO pin enumeration for GPIO */
+typedef enum 
+{
+  RADIO_GPIO_0     = 0x00, /*!< GPIO_0 selected */
+  RADIO_GPIO_1     = 0x01, /*!< GPIO_1 selected */
+  RADIO_GPIO_2     = 0x02, /*!< GPIO_2 selected */
+  RADIO_GPIO_3     = 0x03, /*!< GPIO_3 selected */
+  RADIO_GPIO_SDN   = 0x04, /*!< GPIO_SDN selected */
+} 
+RadioGpioPin;   
+
+  
+/* Exported constants --------------------------------------------------------*/
+  
+  
+/* Exported macro ------------------------------------------------------------*/
+ /* MCU GPIO pin working mode for GPIO */
+#define IS_RADIO_GPIO_MODE(MODE) (((MODE) == RADIO_MODE_GPIO_IN) || \
+                               ((MODE) == RADIO_MODE_EXTI_IN) || \
+                               ((MODE) == RADIO_MODE_GPIO_OUT))
+
+/* Number of Arduino pins used for RADIO GPIO interface */
+#define RADIO_GPIO_NUMBER    ((uint8_t)5)
+
+/* MCU GPIO pin enumeration for GPIO */
+#define IS_RADIO_GPIO_PIN(PIN)   (((PIN) == RADIO_GPIO_0) || \
+                               ((PIN) == RADIO_GPIO_1) || \
+                               ((PIN) == RADIO_GPIO_2) || \
+                               ((PIN) == RADIO_GPIO_3) || \
+                               ((PIN) == RADIO_GPIO_SDN))
+
+/* Define for RADIO board */
+#if !defined (USE_SPIRIT1_DEFAULT)
+ #define USE_SPIRIT1_DEFAULT
+#endif  
+
+/* @defgroup Radio_Gpio_config_Define */
+/*NOTE: GPIO0, GPIO1, GPIO2 of SPIRIT1 is not used in the shield*/
+
+#define RADIO_GPIO_0_PORT                          GPIOC
+#define RADIO_GPIO_0_PIN                           GPIO_PIN_1
+#define RADIO_GPIO_0_CLOCK_ENABLE()                __GPIOC_CLK_ENABLE()
+#define RADIO_GPIO_0_CLOCK_DISABLE()               __GPIOC_CLK_ENABLE()   
+#define RADIO_GPIO_0_SPEED                         GPIO_SPEED_HIGH
+#define RADIO_GPIO_0_PUPD                          GPIO_NOPULL
+#define RADIO_GPIO_0_EXTI_LINE                     GPIO_PIN_1
+#define RADIO_GPIO_0_EXTI_MODE                     GPIO_MODE_IT_FALLING
+#define RADIO_GPIO_0_EXTI_IRQN                     EXTI1_IRQn 
+#define RADIO_GPIO_0_EXTI_PREEMPTION_PRIORITY      2
+#define RADIO_GPIO_0_EXTI_SUB_PRIORITY             2
+#define RADIO_GPIO_0_EXTI_IRQ_HANDLER              EXTI1_IRQHandler
+
+#define RADIO_GPIO_1_PORT                          GPIOB
+#define RADIO_GPIO_1_PIN                           GPIO_PIN_0
+#define RADIO_GPIO_1_CLOCK_ENABLE()                __GPIOB_CLK_ENABLE()
+#define RADIO_GPIO_1_CLOCK_DISABLE()               __GPIOB_CLK_ENABLE()   
+#define RADIO_GPIO_1_SPEED                         GPIO_SPEED_HIGH
+#define RADIO_GPIO_1_PUPD                          GPIO_NOPULL
+#define RADIO_GPIO_1_EXTI_LINE                     GPIO_PIN_0
+#define RADIO_GPIO_1_EXTI_MODE                     GPIO_MODE_IT_FALLING
+#define RADIO_GPIO_1_EXTI_IRQN                     EXTI0_IRQn 
+#define RADIO_GPIO_1_EXTI_PREEMPTION_PRIORITY      2
+#define RADIO_GPIO_1_EXTI_SUB_PRIORITY             2
+#define RADIO_GPIO_1_EXTI_IRQ_HANDLER              EXTI0_IRQHandler
+
+#define RADIO_GPIO_2_PORT                          GPIOA
+#define RADIO_GPIO_2_PIN                           GPIO_PIN_4
+#define RADIO_GPIO_2_CLOCK_ENABLE()                __GPIOA_CLK_ENABLE()
+#define RADIO_GPIO_2_CLOCK_DISABLE()               __GPIOA_CLK_ENABLE()   
+#define RADIO_GPIO_2_SPEED                         GPIO_SPEED_HIGH
+#define RADIO_GPIO_2_PUPD                          GPIO_NOPULL
+#define RADIO_GPIO_2_EXTI_LINE                     GPIO_PIN_4
+#define RADIO_GPIO_2_EXTI_MODE                     GPIO_MODE_IT_FALLING
+#define RADIO_GPIO_2_EXTI_IRQN                     EXTI4_IRQn 
+#define RADIO_GPIO_2_EXTI_PREEMPTION_PRIORITY      2
+#define RADIO_GPIO_2_EXTI_SUB_PRIORITY             2
+#define RADIO_GPIO_2_EXTI_IRQ_HANDLER              EXTI4_IRQHandler
+
+
+#if defined (USE_SPIRIT1_DEFAULT)
+
+
+#define RADIO_GPIO_3_PORT                          GPIOC
+#define RADIO_GPIO_3_PIN                           GPIO_PIN_7
+#define RADIO_GPIO_3_CLOCK_ENABLE()              __GPIOC_CLK_ENABLE()
+#define RADIO_GPIO_3_CLOCK_DISABLE()             __GPIOC_CLK_DISABLE()   
+#define RADIO_GPIO_3_SPEED                         GPIO_SPEED_HIGH
+#define RADIO_GPIO_3_PUPD                          GPIO_NOPULL
+#define RADIO_GPIO_3_EXTI_LINE                     GPIO_PIN_7
+#define RADIO_GPIO_3_EXTI_MODE                     GPIO_MODE_IT_FALLING
+#define RADIO_GPIO_3_EXTI_IRQN                     EXTI9_5_IRQn 
+#define RADIO_GPIO_3_EXTI_PREEMPTION_PRIORITY      2
+#define RADIO_GPIO_3_EXTI_SUB_PRIORITY             2
+#define RADIO_GPIO_3_EXTI_IRQ_HANDLER              EXTI9_5_IRQHandler
+
+#else
+
+#define RADIO_GPIO_3_PORT                        GPIOA
+#define RADIO_GPIO_3_PIN                         GPIO_PIN_0
+#define RADIO_GPIO_3_CLOCK_ENABLE()                __GPIOA_CLK_ENABLE()
+#define RADIO_GPIO_3_CLOCK_DISABLE()               __GPIOA_CLK_DISABLE() 
+#define RADIO_GPIO_3_SPEED                       GPIO_SPEED_HIGH
+#define RADIO_GPIO_3_PUPD                        GPIO_NOPULL
+#define RADIO_GPIO_3_EXTI_LINE                   GPIO_PIN_0
+#define RADIO_GPIO_3_EXTI_MODE                   GPIO_MODE_IT_FALLING
+#define RADIO_GPIO_3_EXTI_IRQN                   EXTI0_IRQn
+#define RADIO_GPIO_3_EXTI_PREEMPTION_PRIORITY    2
+#define RADIO_GPIO_3_EXTI_SUB_PRIORITY           2
+#define RADIO_GPIO_3_EXTI_IRQ_HANDLER            EXTI0_IRQHandler
+
+#endif
+
+#define RADIO_GPIO_SDN_PORT                        GPIOA
+#define RADIO_GPIO_SDN_PIN                         GPIO_PIN_10
+#define RADIO_GPIO_SDN_CLOCK_ENABLE()            __GPIOA_CLK_ENABLE()
+#define RADIO_GPIO_SDN_CLOCK_DISABLE()           __GPIOA_CLK_DISABLE()
+#define RADIO_GPIO_SDN_SPEED                       GPIO_SPEED_HIGH
+#define RADIO_GPIO_SDN_PUPD                        GPIO_PULLUP
+
+
+#define RADIO_GPIO_IRQ		RADIO_GPIO_3
+#define SPIRIT_GPIO_IRQ         SPIRIT_GPIO_3
+
+/* Exported Variables ------------------------------------------------------------*/
+  
+  
+/* Exported functions ------------------------------------------------------- */
+FlagStatus RadioGpioGetLevel(RadioGpioPin xGpio);
+void RadioGpioSetLevel(RadioGpioPin xGpio, GPIO_PinState xState);
+void SdkEvalEnterShutdown(void);
+void SdkEvalExitShutdown(void);
+SpiritFlagStatus SdkEvalCheckShutdown(void);
+void RadioGpioInit(RadioGpioPin xGpio, RadioGpioMode xGpioMode);
+void RadioGpioInterruptCmd(RadioGpioPin xGpio, uint8_t nPreemption, uint8_t nSubpriority, FunctionalState xNewState);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__RADIO_GPIO_H */
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_shield_config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/libs/spirit1/X-NUCLEO-IDS01Ax/radio_shield_config.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,120 @@
+/**
+******************************************************************************
+* @file    radio_shield_config.h
+* @author  System Lab - NOIDA
+* @version V1.0.0
+* @date    15-May-2014
+* @brief   This file contains definitions for:
+*          - LEDs and push-button available on RF shields
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*       without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (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 __RADIO_SHIELD_CONFIG_H
+#define __RADIO_SHIELD_CONFIG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#ifdef USE_STM32L1XX_NUCLEO
+// #include "stm32l1xx_hal.h"
+#endif
+
+#ifdef USE_STM32F4XX_NUCLEO
+// #include "stm32f4xx_hal.h"
+#endif
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup X-NUCLEO-IDS02Ax
+  * @{
+  */
+
+/** @addtogroup RADIO_SHILED_LOW_LEVEL
+  * @{
+  */   
+   
+/* Exported types ------------------------------------------------------------*/
+typedef enum 
+{
+  RADIO_SHIELD_LED = 0
+} Led_t;
+ 
+
+
+/* Exported constants --------------------------------------------------------*/
+
+
+/* Exported macro ------------------------------------------------------------*/
+ /** @addtogroup RF_SHIELD_CONFIG_LOW_LEVEL_LED
+ * @{
+ */
+#define RADIO_SHIELD_LEDn                               ((uint8_t)1)
+
+#define RADIO_SHIELD_LED_GPIO_PIN                      GPIO_PIN_4                         /*Rx Indicator LED*/
+#define RADIO_SHIELD_LED_GPIO_PORT                     GPIOB
+#define RADIO_SHIELD_LED_GPIO_CLK_ENABLE()           __GPIOB_CLK_ENABLE()  
+#define RADIO_SHIELD_LED_GPIO_CLK_DISABLE()          __GPIOB_CLK_DISABLE()
+
+
+/* Exported Variables ------------------------------------------------------------*/
+
+
+/* Exported functions ------------------------------------------------------- */
+void RadioShieldLedInit(Led_t Led);
+void RadioShieldLedOn(Led_t Led);
+void RadioShieldLedOff(Led_t Led);
+void RadioShieldLedToggle(Led_t Led);                 
+                
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RADIO_SHIELD_CONFIG_H */
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/source/radio_spi.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/source/radio_spi.cpp	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,335 @@
+/**
+******************************************************************************
+* @file    radio_spi.c
+* @author  System Lab - NOIDA
+* @version V1.0.0
+* @date    15-May-2014
+* @brief   This file provides code for the configuration of the SPI instances.
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*     without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+******************************************************************************
+*/
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "radio_spi.h"
+
+#include "SimpleSpirit1.h"
+
+
+/**
+ * @addtogroup BSP
+ * @{
+ */
+
+
+/**
+ * @addtogroup X-NUCLEO-IDS02Ax
+ * @{
+ */
+
+
+/**
+ * @defgroup RADIO_SPI_Private_TypesDefinitions       RADIO_SPI Private Types Definitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup RADIO_SPI_Private_Defines                RADIO_SPI Private Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup RADIO_SPI_Private_Macros                 RADIO_SPI Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup RADIO_SPI_Private_Variables              RADIO_SPI Private Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup RADIO_SPI_Private_FunctionPrototypes     RADIO_SPI Private Function Prototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup RADIO_SPI_Private_Functions              RADIO_SPI Private Functions
+ * @{
+ */
+
+/**
+* @}
+*/
+
+/**
+* @brief  Write single or multiple RF Transceivers register
+* @param  cRegAddress: base register's address to be write
+* @param  cNbBytes: number of registers and bytes to be write
+* @param  pcBuffer: pointer to the buffer of values have to be written into registers
+* @retval StatusBytes
+*/
+StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+	return SimpleSpirit1::Instance().SdkEvalSpiWriteRegisters(cRegAddress, cNbBytes, pcBuffer);
+}
+
+StatusBytes SimpleSpirit1::SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+  uint8_t aHeader[2] = {0};
+  uint16_t tmpstatus = 0x0000;
+  StatusBytes *pStatus=(StatusBytes *)&tmpstatus;
+
+  /* Built the aHeader bytes */
+  aHeader[0] = WRITE_HEADER;
+  aHeader[1] = cRegAddress;
+
+  /* Puts the SPI chip select low to start the transaction */
+  chip_sync_select();
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus = _spi.write(aHeader[0]);
+  tmpstatus = tmpstatus << 8;
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus |= _spi.write(aHeader[1]);
+
+  /* Writes the registers according to the number of bytes */
+  for (int index = 0; index < cNbBytes; index++)
+  {
+	  _spi.write(pcBuffer[index]);
+  }
+
+  /* Puts the SPI chip select high to end the transaction */
+  chip_sync_unselect();
+
+  return *pStatus;
+}
+
+
+/**
+* @brief  Read single or multiple SPIRIT1 register
+* @param  cRegAddress: base register's address to be read
+* @param  cNbBytes: number of registers and bytes to be read
+* @param  pcBuffer: pointer to the buffer of registers' values read
+* @retval StatusBytes
+*/
+StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+	return SimpleSpirit1::Instance().SdkEvalSpiReadRegisters(cRegAddress, cNbBytes, pcBuffer);
+}
+
+StatusBytes SimpleSpirit1::SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+  uint16_t tmpstatus = 0x00;
+  StatusBytes *pStatus = (StatusBytes *)&tmpstatus;
+
+  uint8_t aHeader[2] = {0};
+
+  /* Built the aHeader bytes */
+  aHeader[0] = READ_HEADER;
+  aHeader[1] = cRegAddress;
+
+  /* Put the SPI chip select low to start the transaction */
+  chip_sync_select();
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus = _spi.write(aHeader[0]);
+  tmpstatus = tmpstatus << 8;
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus |= _spi.write(aHeader[1]);
+
+  for (int index = 0; index < cNbBytes; index++)
+  {
+	  pcBuffer[index] = _spi.write(0xFF);
+  }
+
+  /* Put the SPI chip select high to end the transaction */
+  chip_sync_unselect();
+
+  return *pStatus;
+}
+
+
+/**
+* @brief  Send a command
+* @param  cCommandCode: command code to be sent
+* @retval StatusBytes
+*/
+StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode)
+{
+	return SimpleSpirit1::Instance().SdkEvalSpiCommandStrobes(cCommandCode);
+}
+
+StatusBytes SimpleSpirit1::SdkEvalSpiCommandStrobes(uint8_t cCommandCode)
+{
+  uint8_t aHeader[2] = {0};
+  uint16_t tmpstatus = 0x0000;
+
+  StatusBytes *pStatus = (StatusBytes *)&tmpstatus;
+
+  /* Built the aHeader bytes */
+  aHeader[0] = COMMAND_HEADER;
+  aHeader[1] = cCommandCode;
+
+  /* Puts the SPI chip select low to start the transaction */
+  chip_sync_select();
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus = _spi.write(aHeader[0]);
+  tmpstatus = tmpstatus<<8;
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus |= _spi.write(aHeader[1]);
+
+  /* Puts the SPI chip select high to end the transaction */
+  chip_sync_unselect();
+
+  return *pStatus;
+}
+
+
+/**
+* @brief  Write data into TX FIFO
+* @param  cNbBytes: number of bytes to be written into TX FIFO
+* @param  pcBuffer: pointer to data to write
+* @retval StatusBytes
+*/
+StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+	return SimpleSpirit1::Instance().SdkEvalSpiWriteFifo(cNbBytes, pcBuffer);
+}
+
+StatusBytes SimpleSpirit1::SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+  uint16_t tmpstatus = 0x0000;
+  StatusBytes *pStatus = (StatusBytes *)&tmpstatus;
+
+  uint8_t aHeader[2] = {0};
+
+  /* Built the aHeader bytes */
+  aHeader[0] = WRITE_HEADER;
+  aHeader[1] = LINEAR_FIFO_ADDRESS;
+
+  /* Put the SPI chip select low to start the transaction */
+  chip_sync_select();
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus = _spi.write(aHeader[0]);
+  tmpstatus = tmpstatus<<8;
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus |= _spi.write(aHeader[1]);
+
+  /* Writes the registers according to the number of bytes */
+  for (int index = 0; index < cNbBytes; index++)
+  {
+	  _spi.write(pcBuffer[index]);
+  }
+
+  /* Put the SPI chip select high to end the transaction */
+  chip_sync_unselect();
+
+  return *pStatus;
+}
+
+/**
+* @brief  Read data from RX FIFO
+* @param  cNbBytes: number of bytes to read from RX FIFO
+* @param  pcBuffer: pointer to data read from RX FIFO
+* @retval StatusBytes
+*/
+StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+	return SimpleSpirit1::Instance().SdkEvalSpiReadFifo(cNbBytes, pcBuffer);
+}
+
+StatusBytes SimpleSpirit1::SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer)
+{
+  uint16_t tmpstatus = 0x0000;
+  StatusBytes *pStatus = (StatusBytes *)&tmpstatus;
+
+  uint8_t aHeader[2];
+
+  /* Built the aHeader bytes */
+  aHeader[0]=READ_HEADER;
+  aHeader[1]=LINEAR_FIFO_ADDRESS;
+
+  /* Put the SPI chip select low to start the transaction */
+  chip_sync_select();
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus = _spi.write(aHeader[0]);
+  tmpstatus = tmpstatus<<8;
+
+  /* Write the aHeader bytes and read the SPIRIT1 status bytes */
+  tmpstatus |= _spi.write(aHeader[1]);
+
+  for (int index = 0; index < cNbBytes; index++)
+  {
+	  pcBuffer[index] = _spi.write(0xFF);
+  }
+
+  /* Put the SPI chip select high to end the transaction */
+  chip_sync_unselect();
+
+  return *pStatus;
+}
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/stm-spirit1-rf-driver/NanostackRfPhySpirit1.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/stm-spirit1-rf-driver/NanostackRfPhySpirit1.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,54 @@
+#ifndef NANOSTACK_RF_PHY_SPIRIT1_H_
+#define NANOSTACK_RF_PHY_SPIRIT1_H_
+
+#include <stdint.h>
+
+#include "NanostackRfPhy.h"
+#include "PinNames.h"
+
+// Arduino pin defaults for convenience
+#if !defined(SPIRIT1_SPI_MOSI)
+#define SPIRIT1_SPI_MOSI   D11
+#endif
+#if !defined(SPIRIT1_SPI_MISO)
+#define SPIRIT1_SPI_MISO   D12
+#endif
+#if !defined(SPIRIT1_SPI_SCLK)
+#define SPIRIT1_SPI_SCLK   D13
+#endif
+#if !defined(SPIRIT1_DEV_IRQ)
+#define SPIRIT1_DEV_IRQ    D9
+#endif
+#if !defined(SPIRIT1_DEV_CS)
+#define SPIRIT1_DEV_CS     D10
+#endif
+#if !defined(SPIRIT1_DEV_SDN)
+#define SPIRIT1_DEV_SDN    D2
+#endif
+#if !defined(SPIRIT1_BRD_LED)
+#define SPIRIT1_BRD_LED    NC
+#endif
+
+class NanostackRfPhySpirit1 : public NanostackRfPhy {
+public:
+    NanostackRfPhySpirit1(PinName spi_mosi, PinName spi_miso, PinName spi_sclk,
+    		PinName dev_irq,  PinName dev_cs, PinName dev_sdn, PinName brd_led);
+    ~NanostackRfPhySpirit1();
+    int8_t rf_register();
+    void rf_unregister();
+    void get_mac_address(uint8_t *mac);
+    void set_mac_address(uint8_t *mac);
+
+private:
+    void rf_init(void);
+
+    const PinName _spi_mosi;
+    const PinName _spi_miso;
+    const PinName _spi_sclk;
+    const PinName _dev_irq;
+    const PinName _dev_cs;
+    const PinName _dev_sdn;
+    const PinName _brd_led;
+};
+
+#endif /* NANOSTACK_RF_PHY_SPIRIT1_H_ */
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/stm-spirit1-rf-driver/SimpleSpirit1.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/stm-spirit1-rf-driver/SimpleSpirit1.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,467 @@
+/*** Mbed Includes ***/
+#include "mbed.h"
+#include "mbed_debug.h"
+
+
+/*** Cube Includes ***/
+#include "SPIRIT_Radio.h"
+#include "SPIRIT_Management.h"
+#include "SPIRIT_Commands.h"
+#include "MCU_Interface.h"
+
+
+/*** Contiki Lib Includes ***/
+#include "spirit1.h"
+#include "spirit1-config.h"
+#include "spirit1-const.h"
+
+
+// betzw: enable beyond macro if you want debug messages also from IRQ handler
+// #define DEBUG_IRQ
+
+
+/*** Macros from Cube Implementation ***/
+#define CLEAR_TXBUF()			(spirit_tx_len = 0)
+#define IS_RXBUF_EMPTY()        (spirit_rx_len == 0)
+#define CLEAR_RXBUF()			do { 					\
+									spirit_rx_len = 0;	\
+									_spirit_rx_pos = 0; \
+								} while(0)
+
+
+/*** Macros from Cube Implementation ***/
+/* transceiver state. */
+#define ON     0
+#define OFF    1
+
+
+/*** Missing Cube External Declarations ***/
+extern "C" void SpiritManagementSetFrequencyBase(uint32_t);
+
+
+/*** UnlockedSPI for Usage in IRQ context ***/
+class UnlockedSPI : public SPI {
+public:
+    UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
+        SPI(mosi, miso, sclk) { }
+    virtual ~UnlockedSPI() {}
+    virtual void lock() { }
+    virtual void unlock() { }
+};
+
+
+/*** A Simple Spirit1 Class ***/
+// NOTE: must be a singleton (due to mix of MBED/CUBE code)!!!
+// NOTE: implementation is IRQ-save but (intentionally) NOT thread-safe!!!
+class SimpleSpirit1 {
+ protected:
+	static SimpleSpirit1 *_singleton;
+
+    /** Communication Interface Instance Variables **/
+	UnlockedSPI _spi; // betzw - NOTE: Morpho/Zio pins are valid only for NUCLEO-F401RE
+              	  	  // mosi: PA_7 (D11)
+					  // miso: PA_6 (D12)
+              	  	  // sclk: PB_3 (D3) or
+              	  	  //       PA_5 (D13) (only in case you unmount R4 & mount R7,
+              	  	  //                  (note: in this case you may not use LED1 on some platforms)
+              	  	  // bits: 8-bit
+              	  	  // mode: 0
+              	  	  // ordr: MSB
+              	  	  // freq: max 10MHz
+    InterruptIn _irq; // PC_7 (D9) (falling)
+    DigitalOut _chip_select; // PB_6 (D10) ('1' == chip unselected)
+    DigitalOut _shut_down; // PA_10 (D2) ('1' == shut_down)
+    DigitalOut _led; // PB_4 (D5) (optional)
+
+    Callback<void(int)> _current_irq_callback;
+    Timeout _rx_receiving_timeout;
+
+    void rx_timeout_handler(void) {
+    	set_ready_state();
+	    cmd_strobe(SPIRIT1_STROBE_RX);
+#ifdef DEBUG_IRQ
+	    debug("\n\r%s (%d)\n\r", __func__, __LINE__);
+#endif
+    }
+
+    void start_rx_timeout(void) {
+    	_rx_receiving_timeout.attach_us(Callback<void()>(this, &SimpleSpirit1::rx_timeout_handler), 100 * 1000); // 100ms
+    }
+
+    void stop_rx_timeout(void) {
+    	_rx_receiving_timeout.detach();
+    }
+
+    /** Static Variables from Cube Implementation **/
+    /*
+     * The buffers which hold incoming data.
+     * The +1 because of the first byte,
+     * which will contain the length of the packet.
+     */
+    volatile uint16_t spirit_tx_len;
+    volatile bool _spirit_tx_started;
+    volatile uint16_t spirit_rx_len;
+    volatile uint16_t _spirit_rx_pos;
+    volatile bool _spirit_rx_err;
+    uint8_t spirit_rx_buf[MAX_PACKET_LEN];
+    volatile bool _is_receiving;
+
+    /** Status Variables from Cube Implementation **/
+    unsigned int spirit_on;
+    uint8_t last_rssi; //MGR
+    uint8_t last_sqi;  //MGR
+
+    /** Low Level Instance Variables **/
+    unsigned int _nr_of_irq_disables;
+
+    /** Low Level Instance Methods **/
+    void disable_spirit_irq(void) {
+    	_irq.disable_irq();
+    	_nr_of_irq_disables++;
+#ifndef NDEBUG
+    	debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+    }
+
+    void enable_spirit_irq(void) {
+#ifndef NDEBUG
+    	debug_if(_nr_of_irq_disables == 0, "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
+#endif
+    	if(--_nr_of_irq_disables == 0)
+    		_irq.enable_irq();
+    }
+
+    void chip_select() { _chip_select = 0; }
+    void chip_unselect() { _chip_select = 1; }
+
+    void enter_shutdown() {
+    	_shut_down = 1;
+    	wait_ms(5); // wait 5 milliseconds (to allow Spirit1 to shut down)
+    }
+
+    void exit_shutdown() {
+    	_shut_down = 0;
+    	wait_ms(10); // wait 10 milliseconds (to allow Spirit1 a proper boot-up sequence)
+    }
+
+    void cs_to_sclk_delay(void) {
+    	wait_us(1); // heuristic value
+    }
+
+    /**
+     * @brief      Write and read a buffer to/from the SPI peripheral device at the same time
+     *             in 8-bit data mode using synchronous SPI communication.
+     * @param[in]  pBufferToWrite pointer to the buffer of data to send.
+     * @param[out] pBufferToRead pointer to the buffer to read data into.
+     * @param[in]  NumBytes number of bytes to read and write.
+     * @retval     0 if ok.
+     * @retval     -1 if data format error.
+     * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
+     *             before calling this function and to enable them again after.
+     */
+    void spi_write_read(uint8_t* pBufferToWrite, uint8_t* pBufferToRead, uint16_t NumBytes)
+    {
+        /* Read and write data at the same time. */
+    	for (int i = 0; i < NumBytes; i++) {
+            pBufferToRead[i] = _spi.write(pBufferToWrite[i]);
+    	}
+    }
+
+    /** Radio Instance Methods **/
+    void radio_set_xtal_freq(uint32_t freq) {
+    	SpiritRadioSetXtalFrequency(freq);
+    }
+
+    void radio_set_pa_level_dbm(uint8_t cIndex, float fPowerdBm) {
+    	SpiritRadioSetPALeveldBm(cIndex, fPowerdBm);
+    }
+
+    void radio_set_pa_level_max_index(uint8_t cIndex) {
+    	SpiritRadioSetPALevelMaxIndex(cIndex);
+    }
+
+    uint8_t radio_init(SRadioInit *init_struct) {
+    	return SpiritRadioInit(init_struct);
+    }
+
+    void radio_persistent_rx(SpiritFunctionalState xNewState) {
+    	SpiritRadioPersistenRx(xNewState);
+    }
+
+    void radio_afc_freeze_on_sync(SpiritFunctionalState xNewState) {
+    	SpiritRadioAFCFreezeOnSync(xNewState);
+    }
+
+    /** Packet System Instance Methods **/
+    void pkt_basic_init(PktBasicInit* pxPktBasicInit) {
+    	SpiritPktBasicInit(pxPktBasicInit);
+    }
+
+    void pkt_basic_set_payload_length(uint16_t nPayloadLength) {
+    	SpiritPktBasicSetPayloadLength(nPayloadLength);
+    }
+
+    uint16_t pkt_basic_get_received_pkt_length(void) {
+    	return SpiritPktBasicGetReceivedPktLength();
+    }
+
+	/** IRQ Instance Methods **/
+    void irq_de_init(SpiritIrqs* pxIrqInit) {
+    	SpiritIrqDeInit(pxIrqInit);
+    }
+
+    void irq_clear_status(void) {
+    	SpiritIrqClearStatus();
+    }
+
+    void irq_set_status(IrqList xIrq, SpiritFunctionalState xNewState) {
+    	SpiritIrq(xIrq, xNewState);
+    }
+
+    void irq_get_status(SpiritIrqs* pxIrqStatus) {
+    	SpiritIrqGetStatus(pxIrqStatus);
+    }
+
+    /** Management Instance Methods **/
+    void mgmt_set_freq_base(uint32_t freq) {
+    	SpiritManagementSetFrequencyBase(freq);
+    }
+
+    void mgmt_refresh_status(void) {
+    	SpiritRefreshStatus();
+    }
+
+    /** Spirit GPIO Instance Methods **/
+    void spirit_gpio_init(SGpioInit* pxGpioInitStruct) {
+    	SpiritGpioInit(pxGpioInitStruct);
+    }
+
+	/** Qi Instance Methods **/
+    void qi_set_sqi_threshold(SqiThreshold xSqiThr) {
+    	SpiritQiSetSqiThreshold(xSqiThr);
+    }
+
+    void qi_sqi_check(SpiritFunctionalState xNewState) {
+    	SpiritQiSqiCheck(xNewState);
+    }
+
+    void qi_set_rssi_threshold_dbm(int nDbmValue) {
+    	SpiritQiSetRssiThresholddBm(nDbmValue);
+    }
+
+    float qi_get_rssi_dbm() {
+    	last_rssi = qi_get_rssi();
+    	return get_last_rssi_dbm();
+    }
+
+    uint8_t qi_get_rssi() {
+    	return SpiritQiGetRssi();
+    }
+
+    uint8_t qi_get_sqi() {
+    	return SpiritQiGetSqi();
+    }
+
+    /** Timer Instance Methods **/
+    void timer_set_rx_timeout_stop_condition(RxTimeoutStopCondition xStopCondition) {
+    	SpiritTimerSetRxTimeoutStopCondition(xStopCondition);
+    }
+
+    void timer_set_rx_timeout_counter(uint8_t cCounter) {
+    	SpiritTimerSetRxTimeoutCounter(cCounter);
+    }
+
+    void timer_set_infinite_rx_timeout(void) {
+    	timer_set_rx_timeout_counter(0);
+    }
+
+    /** CSMA/CA Instance Methods **/
+    void csma_ca_state(SpiritFunctionalState xNewState) {
+    	SpiritCsma(xNewState);
+    }
+
+    void csma_ca_init(CsmaInit* pxCsmaInit) {
+    	csma_ca_state(S_DISABLE); // Disabled at init
+    	SpiritCsmaInit(pxCsmaInit);
+    	SpiritCsmaSeedReloadMode(S_DISABLE); // always disable seed reload
+    }
+
+    /** Command Instance Methods**/
+    void cmd_strobe(uint8_t cmd) {
+    	SpiritCmdStrobeCommand((SpiritCmd)cmd);
+    }
+
+    void cmd_strobe_flush_rx_fifo() {
+    	SpiritCmdStrobeCommand(CMD_FLUSHRXFIFO);
+    }
+
+    /** SPI Instance Methods **/
+    StatusBytes spi_write_linear_fifo(uint8_t cNbBytes, uint8_t* pcBuffer) {
+    	return SdkEvalSpiWriteFifo(cNbBytes, pcBuffer);
+    }
+
+    StatusBytes spi_read_linear_fifo(uint8_t cNbBytes, uint8_t* pcBuffer) {
+    	return SdkEvalSpiReadFifo(cNbBytes, pcBuffer);
+    }
+
+    /** Linear FIFO Instance Methods **/
+    uint8_t linear_fifo_read_num_elements_rx_fifo(void) {
+    	return SpiritLinearFifoReadNumElementsRxFifo();
+    }
+
+    uint8_t linear_fifo_read_num_elements_tx_fifo(void) {
+    	return SpiritLinearFifoReadNumElementsTxFifo();
+    }
+
+    void linear_fifo_set_almost_full_thr_rx(uint8_t cThrRxFifo) {
+    	SpiritLinearFifoSetAlmostFullThresholdRx(cThrRxFifo);
+    }
+
+    /** Calibration Instance Methods **/
+    void calibration_rco(SpiritFunctionalState xNewState) {
+    	SpiritCalibrationRco(xNewState);
+    }
+
+    /** Internal Spirit Methods */
+    void set_ready_state(void);
+    uint8_t refresh_state(void);
+
+    /** Friend Functions **/
+    friend StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+    friend StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+    friend StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
+    friend StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+    friend StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+
+    /** Sdk Instance Methods **/
+    StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+    StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+    StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
+    StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+    StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+
+    /** Helper Instance Methods **/
+    void chip_sync_select() {
+    	disable_spirit_irq();
+    	chip_select();
+    	cs_to_sclk_delay();
+    }
+
+    void chip_sync_unselect() {
+    	chip_unselect();
+    	enable_spirit_irq();
+    }
+
+    /** Init Instance Method **/
+    void init();
+
+    /** Spirit Irq Callback */
+    void IrqHandler();
+
+    /** Constructor **/
+    SimpleSpirit1(PinName mosi, PinName miso, PinName sclk,
+		  PinName irq, PinName cs, PinName sdn,
+		  PinName led);
+
+    /** Destructor **/
+    ~SimpleSpirit1(void); // should never be called!
+
+public:
+    enum {
+    	RX_DONE,
+    	TX_DONE,
+		TX_ERR
+    };
+
+    static SimpleSpirit1& CreateInstance(PinName mosi, PinName miso, PinName sclk,
+    		PinName irq, PinName cs, PinName sdn,
+			PinName led = NC) {
+
+    	if(_singleton == NULL) {
+    		_singleton = new SimpleSpirit1(mosi, miso, sclk,
+    				irq, cs, sdn, led);
+    		_singleton->init();
+    	} else {
+    		error("SimpleSpirit1 singleton already created!\n");
+    	}
+
+    	return *_singleton;
+    }
+
+    static SimpleSpirit1& Instance() {
+    	if(_singleton == NULL) {
+    		error("SimpleSpirit1 must be created before used!\n");
+    	}
+
+    	return *_singleton;
+    }
+
+    /** Attach a function to be called by the Spirit Irq handler when packet has arrived
+     *
+     *  @param func A void() callback, or 0 to set as none
+     *
+     *  @note  Function 'func' will be executed in interrupt context!
+     */
+    void attach_irq_callback(Callback<void(int)> func) {
+    	_current_irq_callback = func;
+    }
+
+    /** Switch Radio On/Off **/
+    int on(void);
+    int off(void);
+
+    /** Set Channel **/
+    void set_channel(uint8_t channel) {
+    	SpiritRadioSetChannel(channel);
+    }
+
+    /** Send a Buffer **/
+    int send(const void *payload, unsigned int payload_len);
+
+    /** Read into Buffer **/
+    int read(void *buf, unsigned int bufsize);
+
+    /** Perform a Clear-Channel Assessment (CCA) to find out if there is
+        a packet in the air or not.
+        Returns 1 if packet has been seen.
+      */
+    int channel_clear(void);
+
+    /** Check if the radio driver has just received a packet **/
+    int get_pending_packet(void);
+
+    /** Is radio currently receiving **/
+    bool is_receiving(void) {
+    	return _is_receiving;
+    }
+
+    /** Get latest value of RSSI (in dBm) **/
+    float get_last_rssi_dbm(void) {
+    	get_last_rssi_raw();
+		return (-120.0+((float)(last_rssi-20))/2);
+    }
+
+    /** Get latest value of RSSI (as Spirit1 raw value) **/
+    uint8_t get_last_rssi_raw(void) {
+    	if(last_rssi == 0) {
+    		last_rssi = qi_get_rssi();
+    	}
+    	return last_rssi;
+    }
+
+    /** Get latest value of LQI (scaled to 8-bit) **/
+    uint8_t get_last_sqi(void) {
+    	const uint8_t max_sqi = 8 * ((SYNC_LENGTH>>1)+1);
+    	if(last_sqi == 0) {
+    		last_sqi = qi_get_sqi();
+    	}
+    	if(last_sqi > max_sqi) last_sqi = max_sqi;
+
+    	return (last_sqi * 255 / max_sqi);
+    }
+
+    /** Reset Board **/
+    void reset_board() {
+    	init();
+    }
+};
diff -r 000000000000 -r 615f90842ce8 stm-spirit1-rf-driver/stm-spirit1-rf-driver/radio_spi.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stm-spirit1-rf-driver/stm-spirit1-rf-driver/radio_spi.h	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,185 @@
+/**
+******************************************************************************
+* @file    radio_spi.h
+* @author  System Lab - NOIDA
+* @version V1.0.0
+* @date    15-May-2014
+* @brief   This file contains all the functions prototypes for SPI .
+******************************************************************************
+* @attention
+*
+* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*   1. Redistributions of source code must retain the above copyright notice,
+*      this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above copyright notice,
+*      this list of conditions and the following disclaimer in the documentation
+*      and/or other materials provided with the distribution.
+*   3. Neither the name of STMicroelectronics nor the names of its contributors
+*      may be used to endorse or promote products derived from this software
+*      without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (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 __RADIO_SPI_H
+#define __RADIO_SPI_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+/* Includes ------------------------------------------------------------------*/
+#ifdef USE_STM32L1XX_NUCLEO
+// #include "stm32l1xx_hal.h"
+#endif
+
+#ifdef USE_STM32F4XX_NUCLEO
+// #include "stm32f4xx_hal.h"
+#endif
+#include "SPIRIT_Config.h"
+#include "radio_spi.h" 
+// #include "spirit1-arch.h"
+
+/**
+ * @addtogroup BSP
+ * @{
+ */ 
+  
+/* Exported types ------------------------------------------------------------*/
+
+  
+/* Exported constants --------------------------------------------------------*/
+  
+  
+/* Exported macro ------------------------------------------------------------*/
+  /* Define for SPIRIT1 board  */  
+ #if !defined (USE_SPIRIT1_DEFAULT)
+ #define USE_SPIRIT1_DEFAULT
+#endif
+  
+/* SPIRIT1_Spi_config */ 
+/* SPI1 */  
+#define RADIO_SPI                                 SPI1
+#define RADIO_SPI_CLK_ENABLE()                  __SPI1_CLK_ENABLE()
+#define RADIO_SPI_CLK_DISABLE()                 __SPI1_CLK_DISABLE()
+
+#define RADIO_SPI_MISO_PORT                      GPIOA
+#define RADIO_SPI_MISO_PIN                       GPIO_PIN_6
+#define RADIO_SPI_MISO_CLOCK_ENABLE()            __GPIOA_CLK_ENABLE()
+#define RADIO_SPI_MISO_CLOCK_DISABLE()           __GPIOA_CLK_DISABLE() 
+  
+#define RADIO_SPI_MOSI_PORT                      GPIOA
+#define RADIO_SPI_MOSI_PIN                       GPIO_PIN_7
+#define RADIO_SPI_MOSI_CLOCK_ENABLE()            __GPIOA_CLK_ENABLE()
+#define RADIO_SPI_MOSI_CLOCK_DISABLE()           __GPIOA_CLK_DISABLE()   
+  
+ 
+ 
+#ifdef USE_SPIRIT1_DEFAULT    
+
+#define RADIO_SPI_SCK_PORT                      GPIOB
+#define RADIO_SPI_SCK_PIN                       GPIO_PIN_3
+#define RADIO_SPI_SCK_CLOCK_ENABLE()            __GPIOB_CLK_ENABLE()
+#define RADIO_SPI_SCK_CLOCK_DISABLE()           __GPIOB_CLK_DISABLE()
+
+  
+#define RADIO_SPI_CS_PORT                        GPIOB
+#define RADIO_SPI_CS_PIN                         GPIO_PIN_6
+#define RADIO_SPI_CS_CLOCK_ENABLE()            __GPIOB_CLK_ENABLE()
+#define RADIO_SPI_CS_CLOCK_DISABLE()           __GPIOB_CLK_DISABLE()
+ 
+#else 
+ 
+#define RADIO_SPI_SCK_PORT                      GPIOB
+#define RADIO_SPI_SCK_PIN                       GPIO_PIN_3
+#define RADIO_SPI_SCK_CLOCK_ENABLE()            __GPIOB_CLK_ENABLE()
+#define RADIO_SPI_SCK_CLOCK_DISABLE()           __GPIOB_CLK_DISABLE()
+
+  
+#define RADIO_SPI_CS_PORT                        GPIOB
+#define RADIO_SPI_CS_PIN                         GPIO_PIN_6
+#define RADIO_SPI_CS_CLOCK_ENABLE()            __GPIOB_CLK_ENABLE()
+#define RADIO_SPI_CS_CLOCK_DISABLE()           __GPIOB_CLK_DISABLE()
+    
+#endif  
+  
+/* Maximum Timeout values for flags waiting loops. These timeouts are not based
+   on accurate values, they just guarantee that the application will not remain
+   stuck if the SPI communication is corrupted.
+   You may modify these timeout values depending on CPU frequency and application
+   conditions (interrupts routines ...) */    
+#define RADIO_SPI_TIMEOUT_MAX                   ((uint32_t)1000)
+
+/* SPIRIT1_Spi_config_Private_Defines */  
+#define CS_TO_SCLK_DELAY     0x0200//FIXME what is this doing?
+#define CLK_TO_CS_DELAY      0x0001
+  
+/* SPIRIT1_Spi_config_Headers */
+#define HEADER_WRITE_MASK     0x00                                /*!< Write mask for header byte*/
+#define HEADER_READ_MASK      0x01                                /*!< Read mask for header byte*/
+#define HEADER_ADDRESS_MASK   0x00                                /*!< Address mask for header byte*/
+#define HEADER_COMMAND_MASK   0x80                                /*!< Command mask for header byte*/
+  
+#define LINEAR_FIFO_ADDRESS 0xFF                                  /*!< Linear FIFO address*/
+  
+/* SPIRIT1_Spi_config_Private_FunctionPrototypes */
+#define SPI_ENTER_CRITICAL()         IRQ_DISABLE()
+#define SPI_EXIT_CRITICAL()          IRQ_ENABLE()
+  
+/* SPIRIT1_Spi_config_Private_Functions */
+#define RadioSpiCSLow()        HAL_GPIO_WritePin(RADIO_SPI_CS_PORT, RADIO_SPI_CS_PIN, GPIO_PIN_RESET)
+#define RadioSpiCSHigh()       HAL_GPIO_WritePin(RADIO_SPI_CS_PORT, RADIO_SPI_CS_PIN, GPIO_PIN_SET)
+  
+/* SPIRIT1_Spi_config_Private_Macros */
+#define BUILT_HEADER(add_comm, w_r) (add_comm | w_r)                             /*!< macro to build the header byte*/
+#define WRITE_HEADER        BUILT_HEADER(HEADER_ADDRESS_MASK, HEADER_WRITE_MASK) /*!< macro to build the write 
+                                                                                                         header byte*/
+#define READ_HEADER         BUILT_HEADER(HEADER_ADDRESS_MASK, HEADER_READ_MASK)  /*!< macro to build the read 
+                                                                                                         header byte*/
+#define COMMAND_HEADER      BUILT_HEADER(HEADER_COMMAND_MASK, HEADER_WRITE_MASK) /*!< macro to build the command 
+                                                                                                         header byte*/
+  
+  
+  
+/* Exported Variables --------------------------------------------------------*/
+  
+  
+/* Exported functions ------------------------------------------------------- */ 
+void SdkEvalSpiInit(void);
+// void SpiCSGpioSetLevel(GPIO_PinState xState);
+StatusBytes SdkEvalSpiWriteRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiCommandStrobes(uint8_t cCommandCode);
+StatusBytes SdkEvalSpiWriteFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+StatusBytes SdkEvalSpiReadFifo(uint8_t cNbBytes, uint8_t* pcBuffer);
+
+  
+#ifdef __cplusplus
+}
+#endif
+#endif /*__RADIO_SPI_H */
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 615f90842ce8 type-yd-driver.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/type-yd-driver.lib	Wed Jul 12 10:52:58 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/MACRUM/code/type-yd-driver/#35a2186cf186