mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6547 from marcuschangarm/feature-nrf52
Update Nordic NRF52 based targets to SDK 14.2pull/6688/merge
commit
6634e4606d
|
@ -20,7 +20,7 @@
|
|||
#include "greentea-client/test_env.h"
|
||||
#include "mbed.h"
|
||||
#include "cmsis.h"
|
||||
#ifdef TARGET_NRF5 // for all NRF5x targets
|
||||
#if defined(TARGET_NRF5) || defined(TARGET_NRF5x) // for all NRF5x targets
|
||||
#include "nrf_nvic.h" // for __NRF_NVIC_APP_IRQS_0 / __NRF_NVIC_APP_IRQS_1
|
||||
#endif
|
||||
|
||||
|
@ -30,7 +30,7 @@ bool test_are_interrupts_enabled(void)
|
|||
{
|
||||
// NRF5x targets don't disable interrupts when in critical section, instead they mask application interrupts this is due to BLE stack
|
||||
// (BLE to be operational requires some interrupts to be always enabled)
|
||||
#ifdef TARGET_NRF52_DK
|
||||
#ifdef TARGET_NRF52
|
||||
// check if APP interrupts are masked for NRF52_DK board
|
||||
return (((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0) || ((NVIC->ISER[1] & __NRF_NVIC_APP_IRQS_1) != 0));
|
||||
#elif TARGET_NRF5
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
# Change Log
|
||||
|
||||
## [v2.5.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.3) (2016-02-16)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.2...v2.5.3)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix for compilation errors with S110 softdevice in btle.cpp [\#109](https://github.com/ARMmbed/ble-nrf51822/pull/109) ([ddavidebor](https://github.com/ddavidebor))
|
||||
|
||||
## [v2.5.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.2) (2016-02-16)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.1...v2.5.2)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Sync develop against master [\#113](https://github.com/ARMmbed/ble-nrf51822/pull/113) ([pan-](https://github.com/pan-))
|
||||
- Fix incorrect handles of characteristics descriptors. [\#112](https://github.com/ARMmbed/ble-nrf51822/pull/112) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.5.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.1) (2016-01-27)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.0...v2.5.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Remove Gap::state updates from this module [\#108](https://github.com/ARMmbed/ble-nrf51822/pull/108) ([andresag01](https://github.com/andresag01))
|
||||
- merge version [\#106](https://github.com/ARMmbed/ble-nrf51822/pull/106) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.5.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.0) (2016-01-12)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.4.1...v2.5.0)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix access to enum member [\#105](https://github.com/ARMmbed/ble-nrf51822/pull/105) ([pan-](https://github.com/pan-))
|
||||
- Hotfix dependency [\#104](https://github.com/ARMmbed/ble-nrf51822/pull/104) ([pan-](https://github.com/pan-))
|
||||
- Finish implementation of getAddressesFromBondTable [\#103](https://github.com/ARMmbed/ble-nrf51822/pull/103) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.4.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.4.1) (2016-01-11)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.4.0...v2.4.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- merge branch develop \(v2.4.0\) [\#100](https://github.com/ARMmbed/ble-nrf51822/pull/100) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.4.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.4.0) (2016-01-10)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.3.1...v2.4.0)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add implementation of experimental whitelisting API [\#99](https://github.com/ARMmbed/ble-nrf51822/pull/99) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.3.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.3.1) (2016-01-07)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.3.0...v2.3.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Update yotta module dependencies [\#98](https://github.com/ARMmbed/ble-nrf51822/pull/98) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.3.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.3.0) (2015-12-23)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.10...v2.3.0)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Implementation of Characteristic descriptor discovery [\#74](https://github.com/ARMmbed/ble-nrf51822/pull/74) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.2.10](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.10) (2015-12-23)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.9...v2.2.10)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- nRF5xn::init don't verify if errors have occurred during btle\_init [\#59](https://github.com/ARMmbed/ble-nrf51822/issues/59)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- A call to shutdown does not clear the state of some components of BLE API [\#85](https://github.com/ARMmbed/ble-nrf51822/issues/85)
|
||||
- Memory allocation issue on the NRF51DK board. [\#76](https://github.com/ARMmbed/ble-nrf51822/issues/76)
|
||||
- Terrible handling of initLen / minLen and variable length characteristics. [\#56](https://github.com/ARMmbed/ble-nrf51822/issues/56)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix shutdown of Gap instance to avoid NULL refs [\#96](https://github.com/ARMmbed/ble-nrf51822/pull/96) ([andresag01](https://github.com/andresag01))
|
||||
- Add check for return code of ble\_init [\#95](https://github.com/ARMmbed/ble-nrf51822/pull/95) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.2.9](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.9) (2015-12-18)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.8...v2.2.9)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Cannot open source input file "system\_nrf51.h" [\#52](https://github.com/ARMmbed/ble-nrf51822/issues/52)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Remove occurrence of deprecated appearance enum [\#92](https://github.com/ARMmbed/ble-nrf51822/pull/92) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.2.8](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.8) (2015-12-16)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.7...v2.2.8)
|
||||
|
||||
## [v2.2.7](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.7) (2015-12-15)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.6...v2.2.7)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Replace deprecated inclusions of mbed.h [\#89](https://github.com/ARMmbed/ble-nrf51822/pull/89) ([andresag01](https://github.com/andresag01))
|
||||
- Improve shutdown to clear BLE API and not just SD [\#87](https://github.com/ARMmbed/ble-nrf51822/pull/87) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.2.6](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.6) (2015-12-15)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.5...v2.2.6)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- follow the extraction of address related types from Gap.h into BLEProtocol.h [\#88](https://github.com/ARMmbed/ble-nrf51822/pull/88) ([rgrover](https://github.com/rgrover))
|
||||
|
||||
## [v2.2.5](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.5) (2015-12-11)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.3...v2.2.5)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Added SecurityManager::setLinkSecurity call for elevating security settings on a particular connection. [\#86](https://github.com/ARMmbed/ble-nrf51822/pull/86) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
|
||||
## [v2.2.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.3) (2015-12-10)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.2...v2.2.3)
|
||||
|
||||
## [v2.2.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.2) (2015-12-08)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.1...v2.2.2)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Add -Wno-unused-function to supress-warnings.cmake [\#83](https://github.com/ARMmbed/ble-nrf51822/pull/83) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.2.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.1) (2015-12-08)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.0...v2.2.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- WIP: UUID endian change [\#82](https://github.com/ARMmbed/ble-nrf51822/pull/82) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
|
||||
## [v2.2.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.0) (2015-12-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.4...v2.2.0)
|
||||
|
||||
## [v2.1.4](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.4) (2015-12-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.3...v2.1.4)
|
||||
|
||||
## [v2.1.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.3) (2015-12-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.2...v2.1.3)
|
||||
|
||||
## [v2.1.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.2) (2015-12-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.1...v2.1.2)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Allow GattAttributes to have variable length [\#81](https://github.com/ARMmbed/ble-nrf51822/pull/81) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.1.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.1) (2015-12-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.0...v2.1.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fixed endianness bug in nRF5xServiceDiscovery::processDiscoverUUIDResponse so it is consistent with BLE API. [\#80](https://github.com/ARMmbed/ble-nrf51822/pull/80) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
- Fixed bug in nRF5xGap.setAddress where random adresses where not set properly. [\#79](https://github.com/ARMmbed/ble-nrf51822/pull/79) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
- Separate concept of minlen and len for BLE chars [\#78](https://github.com/ARMmbed/ble-nrf51822/pull/78) ([andresag01](https://github.com/andresag01))
|
||||
- Split nordic sdk into its own module [\#75](https://github.com/ARMmbed/ble-nrf51822/pull/75) ([LiyouZhou](https://github.com/LiyouZhou))
|
||||
|
||||
## [v2.1.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.0) (2015-11-27)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.8...v2.1.0)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Update to sdk 8.1 [\#77](https://github.com/ARMmbed/ble-nrf51822/pull/77) ([LiyouZhou](https://github.com/LiyouZhou))
|
||||
|
||||
## [v2.0.8](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.8) (2015-11-26)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.7...v2.0.8)
|
||||
|
||||
## [v2.0.7](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.7) (2015-11-26)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.6...v2.0.7)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- test2000 [\#72](https://github.com/ARMmbed/ble-nrf51822/issues/72)
|
||||
- test1000000 [\#71](https://github.com/ARMmbed/ble-nrf51822/issues/71)
|
||||
- test4 [\#70](https://github.com/ARMmbed/ble-nrf51822/issues/70)
|
||||
- test3 [\#69](https://github.com/ARMmbed/ble-nrf51822/issues/69)
|
||||
- test2 [\#68](https://github.com/ARMmbed/ble-nrf51822/issues/68)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- use Extern c around \#include to use nordic sdk headers implemented in C [\#73](https://github.com/ARMmbed/ble-nrf51822/pull/73) ([LiyouZhou](https://github.com/LiyouZhou))
|
||||
|
||||
## [v2.0.6](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.6) (2015-11-17)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.5...v2.0.6)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- test [\#66](https://github.com/ARMmbed/ble-nrf51822/issues/66)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- add Nordic's license agreement. [\#67](https://github.com/ARMmbed/ble-nrf51822/pull/67) ([rgrover](https://github.com/rgrover))
|
||||
|
||||
## [v2.0.5](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.5) (2015-11-16)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.4...v2.0.5)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Post radio notification callback through minar [\#65](https://github.com/ARMmbed/ble-nrf51822/pull/65) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.0.4](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.4) (2015-11-13)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.3...v2.0.4)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix assembly sequence to start bootloader in GCC [\#64](https://github.com/ARMmbed/ble-nrf51822/pull/64) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v2.0.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.3) (2015-11-09)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.2...v2.0.3)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Added watchdog header file from Nordic SDK 8.1 [\#62](https://github.com/ARMmbed/ble-nrf51822/pull/62) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
|
||||
## [v2.0.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.2) (2015-11-03)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/mbedos-release-15-11...v2.0.2)
|
||||
|
||||
## [mbedos-release-15-11](https://github.com/ARMmbed/ble-nrf51822/tree/mbedos-release-15-11) (2015-11-03)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.1...mbedos-release-15-11)
|
||||
|
||||
## [v2.0.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.1) (2015-11-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.0...v2.0.1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Ensure that the initialization flags is set to false if the BLE stack is shutdown properly. [\#58](https://github.com/ARMmbed/ble-nrf51822/pull/58) ([pan-](https://github.com/pan-))
|
||||
|
||||
## [v2.0.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.0) (2015-11-02)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v1.1.0...v2.0.0)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Nordic SDK and SoftDevice [\#57](https://github.com/ARMmbed/ble-nrf51822/issues/57)
|
||||
- shouldn't eab6631cb be merged into master? [\#54](https://github.com/ARMmbed/ble-nrf51822/issues/54)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Introduced changes for memory savings [\#55](https://github.com/ARMmbed/ble-nrf51822/pull/55) ([andresag01](https://github.com/andresag01))
|
||||
|
||||
## [v1.1.0](https://github.com/ARMmbed/ble-nrf51822/tree/v1.1.0) (2015-10-28)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v1.0.0...v1.1.0)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- target dependencies in module.json [\#50](https://github.com/ARMmbed/ble-nrf51822/issues/50)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- When connecting, if no scanning parameters are passed, use values from Gap parent. [\#53](https://github.com/ARMmbed/ble-nrf51822/pull/53) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
|
||||
## [v1.0.0](https://github.com/ARMmbed/ble-nrf51822/tree/v1.0.0) (2015-10-19)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/mbedos-techcon-oob2...v1.0.0)
|
||||
|
||||
## [mbedos-techcon-oob2](https://github.com/ARMmbed/ble-nrf51822/tree/mbedos-techcon-oob2) (2015-10-19)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.8...mbedos-techcon-oob2)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- rename the bootloader files with \_fota in the name? [\#51](https://github.com/ARMmbed/ble-nrf51822/issues/51)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Update S110 detection macros, again [\#49](https://github.com/ARMmbed/ble-nrf51822/pull/49) ([jpbrucker](https://github.com/jpbrucker))
|
||||
- Error check number of characteristics [\#48](https://github.com/ARMmbed/ble-nrf51822/pull/48) ([Timmmm](https://github.com/Timmmm))
|
||||
|
||||
## [v0.4.8](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.8) (2015-09-25)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.7...v0.4.8)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Error real cause loss in nRF5xGattServer.cpp [\#44](https://github.com/ARMmbed/ble-nrf51822/issues/44)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- rgrover patch fixed [\#47](https://github.com/ARMmbed/ble-nrf51822/pull/47) ([fabiencomte](https://github.com/fabiencomte))
|
||||
- Update S110 detection macros [\#43](https://github.com/ARMmbed/ble-nrf51822/pull/43) ([jpbrucker](https://github.com/jpbrucker))
|
||||
- remove some unnecessary include paths [\#42](https://github.com/ARMmbed/ble-nrf51822/pull/42) ([autopulated](https://github.com/autopulated))
|
||||
- Add FOTA bootloader image [\#41](https://github.com/ARMmbed/ble-nrf51822/pull/41) ([jpbrucker](https://github.com/jpbrucker))
|
||||
|
||||
## [v0.4.7](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.7) (2015-08-13)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.6...v0.4.7)
|
||||
|
||||
## [v0.4.6](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.6) (2015-08-11)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.5...v0.4.6)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- remove duplication of global static variable BLE\_EVT\_BUFFER [\#39](https://github.com/ARMmbed/ble-nrf51822/issues/39)
|
||||
- clearScanResponse\(\) [\#30](https://github.com/ARMmbed/ble-nrf51822/issues/30)
|
||||
- Debug builds fail due to missing bsp.h [\#11](https://github.com/ARMmbed/ble-nrf51822/issues/11)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Disable GattClient features when using S110 SoftDevice [\#38](https://github.com/ARMmbed/ble-nrf51822/pull/38) ([jpbrucker](https://github.com/jpbrucker))
|
||||
|
||||
## [v0.4.5](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.5) (2015-08-10)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.4...v0.4.5)
|
||||
|
||||
## [v0.4.4](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.4) (2015-08-07)
|
||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.3...v0.4.4)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- nrf51822 hangs after calling sd\_flash\_page\_erase\(\) [\#35](https://github.com/ARMmbed/ble-nrf51822/issues/35)
|
||||
- nRF5xn::getVersion return \(Unknown\) with version 8 soft device [\#29](https://github.com/ARMmbed/ble-nrf51822/issues/29)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Changed Gap:: to GapAdvertisingParams:: because of change in BLE [\#34](https://github.com/ARMmbed/ble-nrf51822/pull/34) ([jslater8](https://github.com/jslater8))
|
||||
- Select the clock source dynamically on SoftDevice initialisation [\#32](https://github.com/ARMmbed/ble-nrf51822/pull/32) ([jpbrucker](https://github.com/jpbrucker))
|
||||
- Add S110 SoftDevice compatibility [\#28](https://github.com/ARMmbed/ble-nrf51822/pull/28) ([jpbrucker](https://github.com/jpbrucker))
|
||||
|
||||
## [v0.4.3](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.3) (2015-07-22)
|
||||
**Closed issues:**
|
||||
|
||||
- Target polling failed [\#24](https://github.com/ARMmbed/ble-nrf51822/issues/24)
|
||||
- support handling of HVX Events \(notifications and indications\). [\#22](https://github.com/ARMmbed/ble-nrf51822/issues/22)
|
||||
- provide an implementation for GattServer::areUpdatesEnabled\(\) [\#21](https://github.com/ARMmbed/ble-nrf51822/issues/21)
|
||||
- getValueHandle\(\) returns characteristicIndex instead of attribute-handle [\#20](https://github.com/ARMmbed/ble-nrf51822/issues/20)
|
||||
- Clash With Definition And Enum Naming [\#16](https://github.com/ARMmbed/ble-nrf51822/issues/16)
|
||||
- Errors in GCC build [\#14](https://github.com/ARMmbed/ble-nrf51822/issues/14)
|
||||
- bring s110 support back [\#10](https://github.com/ARMmbed/ble-nrf51822/issues/10)
|
||||
- Allow adding a User Description descriptor to a GattCharacteristic. [\#9](https://github.com/ARMmbed/ble-nrf51822/issues/9)
|
||||
- device\_manager\_peripheral.c includes app\_trace.h [\#7](https://github.com/ARMmbed/ble-nrf51822/issues/7)
|
||||
- linking esb\_gcc.a \(nrf51822 enhanced shock burst\) with mbed [\#5](https://github.com/ARMmbed/ble-nrf51822/issues/5)
|
||||
- The app\_timer usage may conflict [\#2](https://github.com/ARMmbed/ble-nrf51822/issues/2)
|
||||
- Nordic License [\#1](https://github.com/ARMmbed/ble-nrf51822/issues/1)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Develop [\#25](https://github.com/ARMmbed/ble-nrf51822/pull/25) ([zoujixing](https://github.com/zoujixing))
|
||||
- Remove unnecessary 'compiler\_abstraction.h' to get rid of duplicate '… [\#23](https://github.com/ARMmbed/ble-nrf51822/pull/23) ([adfernandes](https://github.com/adfernandes))
|
||||
- restructure for minimal yotta compatibility [\#15](https://github.com/ARMmbed/ble-nrf51822/pull/15) ([autopulated](https://github.com/autopulated))
|
||||
- Fix various GCC compilation issues. [\#12](https://github.com/ARMmbed/ble-nrf51822/pull/12) ([adfernandes](https://github.com/adfernandes))
|
||||
- Fix for GCC lost in SDK v8.0 update [\#8](https://github.com/ARMmbed/ble-nrf51822/pull/8) ([rosterloh](https://github.com/rosterloh))
|
||||
- new target DELTA\_DFCM\_NNN40 with nrf51822 chip, config internal RC crystal. [\#6](https://github.com/ARMmbed/ble-nrf51822/pull/6) ([Marcomissyou](https://github.com/Marcomissyou))
|
||||
- Updated return value for nRF51GattServer::updateValue. Will now report w... [\#4](https://github.com/ARMmbed/ble-nrf51822/pull/4) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
- Added optional data and length fields to the return struct for authorize... [\#3](https://github.com/ARMmbed/ble-nrf51822/pull/3) ([marcuschangarm](https://github.com/marcuschangarm))
|
||||
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
|
@ -0,0 +1,6 @@
|
|||
This module contains softdevice which comes with The Nordic Softdevice License Agreement,
|
||||
a BSD-like licence for binary distributions, offered by Nordic for use in mbed. Some
|
||||
other files come from the mbed SDK, and are licensed under Apache-2.0. 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. The Nordic Semiconductor Softdevice
|
||||
License Agreement can be found in softdevice_nrf51822_licence_agreement.txt.
|
|
@ -0,0 +1,13 @@
|
|||
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.
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "ble-nrf51822",
|
||||
"version": "2.7.1",
|
||||
"description": "Nordic stack and drivers for the mbed BLE API.",
|
||||
"keywords": [
|
||||
"Bluetooth",
|
||||
"BLE",
|
||||
"mbed",
|
||||
"mbed-official"
|
||||
],
|
||||
"author": "Rohit Grover",
|
||||
"repository": {
|
||||
"url": "git@github.com:ARMmbed/ble-nRF51822.git",
|
||||
"type": "git"
|
||||
},
|
||||
"homepage": "https://developer.mbed.org/teams/Nordic-Semiconductor/",
|
||||
"licenses": [
|
||||
{
|
||||
"url": "https://spdx.org/licenses/Apache-2.0",
|
||||
"type": "Apache-2.0"
|
||||
},
|
||||
{
|
||||
"type": "LicenseRef-softdevice_nrf51822_licence_agreement.txt"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"ble": "^2.6.0",
|
||||
"nrf51-sdk": "^2.4.0"
|
||||
},
|
||||
"extraIncludes": [
|
||||
"source/btle",
|
||||
"source/btle/custom",
|
||||
"source/common"
|
||||
],
|
||||
"targetDependencies": {}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* S110/S120/S130 License Agreement
|
||||
*
|
||||
* Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved.
|
||||
*
|
||||
* Redistribution. Redistribution and use in binary form, without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* • Redistributions must reproduce the above copyright notice and the following
|
||||
* disclaimer in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* • Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* • No reverse engineering, decompilation, or disassembly of this software is
|
||||
* permitted.
|
||||
*
|
||||
* DISCLAIMER.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* /
|
|
@ -0,0 +1,490 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#include "common/common.h"
|
||||
#include "nordic_common.h"
|
||||
|
||||
#include "btle.h"
|
||||
#include "btle_clock.h"
|
||||
|
||||
#include "ble_flash.h"
|
||||
#include "ble_conn_params.h"
|
||||
|
||||
#include "btle_gap.h"
|
||||
#include "custom/custom_helper.h"
|
||||
|
||||
#include "ble/GapEvents.h"
|
||||
#include "nRF5xn.h"
|
||||
|
||||
// This is a C++ file, so C11 _Static_assert (works with -std=gnu99 on GCC) won't work
|
||||
#undef STATIC_ASSERT_SIMPLE
|
||||
#undef STATIC_ASSERT_MSG
|
||||
|
||||
// FIXME : We can't use mbed_assert.h because we're using these macros within functions
|
||||
#define STATIC_ASSERT_MSG(EXPR, MSG)
|
||||
#define STATIC_ASSERT_SIMPLE(EXPR)
|
||||
|
||||
#warning FIXME : We can't use mbed_assert.h because we're using these within functions
|
||||
|
||||
#ifdef S110
|
||||
#define IS_LEGACY_DEVICE_MANAGER_ENABLED 1
|
||||
#elif defined(S130) || defined(S132)
|
||||
#define IS_LEGACY_DEVICE_MANAGER_ENABLED 0
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#if (IS_LEGACY_DEVICE_MANAGER_ENABLED)
|
||||
#include "pstorage.h"
|
||||
#include "device_manager.h"
|
||||
#else
|
||||
#include "nrf_fstorage.h"
|
||||
#include "fds.h"
|
||||
#include "peer_manager.h"
|
||||
#include "ble_conn_state.h"
|
||||
#endif
|
||||
|
||||
#include "nrf_sdh.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
}
|
||||
|
||||
#include "headers/ble_hci.h"
|
||||
|
||||
#include "nRF5XPalGattClient.h"
|
||||
|
||||
|
||||
// Make this volatile at it will be set in interrupt context
|
||||
volatile bool isEventsSignaled = false;
|
||||
|
||||
extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name);
|
||||
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name);
|
||||
|
||||
// Before SDK 14, the softdevice handler is implemented within the SDK
|
||||
// In SDK 14+, we have to implement it as we're using the "polling" mode for the SD
|
||||
extern "C" void SD_EVT_IRQHandler(void); // export the softdevice event handler for registration by nvic-set-vector.
|
||||
|
||||
#if NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
static void btle_handler(const ble_evt_t *p_ble_evt, void *p_context);
|
||||
#else
|
||||
static void btle_handler(ble_evt_t *p_ble_evt);
|
||||
#endif
|
||||
|
||||
#if !NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
static void sys_evt_dispatch(uint32_t sys_evt)
|
||||
{
|
||||
#if (IS_LEGACY_DEVICE_MANAGER_ENABLED)
|
||||
pstorage_sys_event_handler(sys_evt);
|
||||
#else
|
||||
// Forward Softdevice events to the fstorage module
|
||||
fs_sys_event_handler(sys_evt);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function is called in interrupt context to handle BLE events; i.e. pull
|
||||
* system and user events out of the pending events-queue of the BLE stack. The
|
||||
* BLE stack signals the availability of events by the triggering the SWI2
|
||||
* interrupt, which forwards the handling to this function.
|
||||
*
|
||||
* The event processing loop is implemented in intern_softdevice_events_execute().
|
||||
*
|
||||
* This function will signal to the user code by calling signalEventsToProcess
|
||||
* that their is events to process and BLE::processEvents should be called.
|
||||
*/
|
||||
static uint32_t signalEvent()
|
||||
{
|
||||
if(isEventsSignaled == false) {
|
||||
isEventsSignaled = true;
|
||||
nRF5xn::Instance(BLE::DEFAULT_INSTANCE).signalEventsToProcess(BLE::DEFAULT_INSTANCE);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
error_t btle_init(void)
|
||||
{
|
||||
nrf_clock_lf_cfg_t clockConfiguration;
|
||||
ret_code_t err_code;
|
||||
|
||||
// register softdevice handler vector
|
||||
NVIC_SetVector(SD_EVT_IRQn, (uint32_t) SD_EVT_IRQHandler);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 5)
|
||||
err_code = nrf_sdh_enable_request();
|
||||
ASSERT_STATUS(err_code);
|
||||
#else
|
||||
// Configure the LF clock according to values provided by btle_clock.h.
|
||||
// It is input from the chain of the yotta configuration system.
|
||||
clockConfiguration.source = LFCLK_CONF_SOURCE;
|
||||
clockConfiguration.xtal_accuracy = LFCLK_CONF_ACCURACY;
|
||||
clockConfiguration.rc_ctiv = LFCLK_CONF_RC_CTIV;
|
||||
clockConfiguration.rc_temp_ctiv = LFCLK_CONF_RC_TEMP_CTIV;
|
||||
|
||||
SOFTDEVICE_HANDLER_INIT(&clockConfiguration, signalEvent);
|
||||
#endif
|
||||
|
||||
// Enable BLE stack
|
||||
#if (NRF_SD_BLE_API_VERSION >= 5)
|
||||
// Configure softdevice manually
|
||||
// We could have used nrf_sdh_ble_default_cfg_set() but it's tightly coupled with the macros defined in sdk_config.h
|
||||
ble_cfg_t ble_cfg;
|
||||
uint32_t ram_start = 0;
|
||||
|
||||
// Recover start address of application's RAM
|
||||
err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
|
||||
ASSERT_STATUS(err_code);
|
||||
|
||||
// First configure GAP parameters, including the maximum number of connections
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.conn_cfg.conn_cfg_tag = NRF_CONNECTION_TAG;
|
||||
ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = TOTAL_LINK_COUNT;
|
||||
ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH; // FIXME?
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// GAP - Configure the number of peripheral and central links
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.conn_cfg.conn_cfg_tag = NRF_CONNECTION_TAG;
|
||||
ble_cfg.gap_cfg.role_count_cfg.periph_role_count = PERIPHERAL_LINK_COUNT;
|
||||
ble_cfg.gap_cfg.role_count_cfg.central_role_count = CENTRAL_LINK_COUNT;
|
||||
ble_cfg.gap_cfg.role_count_cfg.central_sec_count = CENTRAL_LINK_COUNT ?
|
||||
BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT : 0;
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Configure GATT
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.conn_cfg.conn_cfg_tag = NRF_CONNECTION_TAG;
|
||||
ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Number of custom UUIDs
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = UUID_TABLE_MAX_ENTRIES;
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// GATT Server attribute table size
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = GATTS_ATTR_TAB_SIZE;
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// GATT Server, Service Changed characteristic
|
||||
memset(&ble_cfg, 0, sizeof(ble_cfg_t));
|
||||
ble_cfg.gatts_cfg.service_changed.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
|
||||
|
||||
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_SERVICE_CHANGED, &ble_cfg, ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Enable BLE stack in softdevice
|
||||
err_code = nrf_sdh_ble_enable(&ram_start);
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
#else
|
||||
ble_enable_params_t ble_enable_params;
|
||||
err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
|
||||
PERIPHERAL_LINK_COUNT,
|
||||
&ble_enable_params);
|
||||
|
||||
ble_enable_params.gatts_enable_params.attr_tab_size = GATTS_ATTR_TAB_SIZE;
|
||||
ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
|
||||
ble_enable_params.common_enable_params.vs_uuid_count = UUID_TABLE_MAX_ENTRIES;
|
||||
|
||||
if(err_code != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (softdevice_enable(&ble_enable_params) != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Peer Manger must been initialised prior any other call to its API (this file and btle_security_pm.cpp)
|
||||
pm_init();
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
ble_gap_addr_t addr;
|
||||
if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
|
||||
return ERROR_INVALID_PARAM;
|
||||
}
|
||||
#else
|
||||
ble_gap_privacy_params_t privacy_params = {0};
|
||||
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
|
||||
pm_privacy_set(&privacy_params);
|
||||
#endif
|
||||
|
||||
// From SDK 14 onwards event handlers are registered differently
|
||||
// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.0.0%2Fmigration.html
|
||||
#if NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
// Register a handler for our BLE events.
|
||||
NRF_SDH_BLE_OBSERVER(m_ble_observer, 3 /* default priority for user events */, btle_handler, NULL);
|
||||
#else
|
||||
ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
|
||||
ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
|
||||
#endif
|
||||
|
||||
return btle_gap_init();
|
||||
}
|
||||
|
||||
#if NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
static void btle_handler(const ble_evt_t *p_ble_evt, void *p_context)
|
||||
#else
|
||||
static void btle_handler(ble_evt_t *p_ble_evt)
|
||||
#endif
|
||||
{
|
||||
#if NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
(void)p_context; // Keep compiler happy
|
||||
#endif
|
||||
using ble::pal::vendor::nordic::nRF5XGattClient;
|
||||
|
||||
// In SDK14+, all other modules from the SDK will be registered independently as softdevice events observers
|
||||
#if !NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
/* Library service handlers */
|
||||
#if SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
ble_conn_params_on_ble_evt(p_ble_evt);
|
||||
#endif
|
||||
|
||||
#if (IS_LEGACY_DEVICE_MANAGER_ENABLED)
|
||||
dm_ble_evt_handler(p_ble_evt);
|
||||
#else
|
||||
// Forward BLE events to the Connection State module.
|
||||
// This must be called before any event handler that uses this module.
|
||||
ble_conn_state_on_ble_evt(p_ble_evt);
|
||||
|
||||
// Forward BLE events to the Peer Manager
|
||||
pm_on_ble_evt(p_ble_evt);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
nRF5XGattClient::handle_events(p_ble_evt);
|
||||
#endif
|
||||
|
||||
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
nRF5xGap &gap = (nRF5xGap &) ble.getGap();
|
||||
nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer();
|
||||
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
|
||||
|
||||
/* Custom event handler */
|
||||
switch (p_ble_evt->header.evt_id) {
|
||||
case BLE_GAP_EVT_CONNECTED: {
|
||||
Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
#if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110)
|
||||
/* Only peripheral role is supported by S110 */
|
||||
Gap::Role_t role = Gap::PERIPHERAL;
|
||||
#else
|
||||
Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role);
|
||||
#endif
|
||||
gap.setConnectionHandle(handle);
|
||||
const Gap::ConnectionParams_t *params = reinterpret_cast<const Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
|
||||
const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
|
||||
|
||||
gap.processConnectionEvent(handle,
|
||||
role,
|
||||
static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
|
||||
static_cast<BLEProtocol::AddressType_t>(own->addr_type), own->addr,
|
||||
params);
|
||||
#else
|
||||
Gap::AddressType_t addr_type;
|
||||
Gap::Address_t own_address;
|
||||
gap.getAddress(&addr_type, own_address);
|
||||
|
||||
gap.processConnectionEvent(handle,
|
||||
role,
|
||||
static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
|
||||
addr_type, own_address,
|
||||
params);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case BLE_GAP_EVT_DISCONNECTED: {
|
||||
Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
// Since we are not in a connection and have not started advertising,
|
||||
// store bonds
|
||||
gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID);
|
||||
|
||||
Gap::DisconnectionReason_t reason;
|
||||
switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
|
||||
case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION:
|
||||
reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION;
|
||||
break;
|
||||
case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION:
|
||||
reason = Gap::REMOTE_USER_TERMINATED_CONNECTION;
|
||||
break;
|
||||
case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE:
|
||||
reason = Gap::CONN_INTERVAL_UNACCEPTABLE;
|
||||
break;
|
||||
default:
|
||||
/* Please refer to the underlying transport library for an
|
||||
* interpretion of this reason's value. */
|
||||
reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
// Close all pending discoveries for this connection
|
||||
nRF5XGattClient::handle_connection_termination(handle);
|
||||
#endif
|
||||
|
||||
gap.processDisconnectionEvent(handle, reason);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 5)
|
||||
#ifndef S140
|
||||
// Handle PHY upgrade request
|
||||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
|
||||
{
|
||||
ble_gap_phys_t const phys =
|
||||
{
|
||||
/* rx_phys */ BLE_GAP_PHY_AUTO,
|
||||
/* tx_phys */ BLE_GAP_PHY_AUTO,
|
||||
};
|
||||
ASSERT_STATUS_RET_VOID( sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys) );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle Data length negotiation request
|
||||
case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
|
||||
{
|
||||
ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
|
||||
uint8_t const data_length_peer =
|
||||
p_gap_evt->params.data_length_update_request.peer_params.max_tx_octets;
|
||||
|
||||
const uint8_t max_data_length = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + 4 /* L2CAP header size */;
|
||||
|
||||
uint8_t const data_length = MIN(max_data_length, data_length_peer);
|
||||
|
||||
ble_gap_data_length_params_t const dlp =
|
||||
{
|
||||
/* max_rx_octets */ data_length,
|
||||
/* max_tx_octets */ data_length
|
||||
};
|
||||
|
||||
ASSERT_STATUS_RET_VOID(sd_ble_gap_data_length_update(p_gap_evt->conn_handle, &dlp, NULL));
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle MTU exchange request
|
||||
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
|
||||
{
|
||||
// Respond with the server MTU
|
||||
uint16_t conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
|
||||
ASSERT_STATUS_RET_VOID(sd_ble_gatts_exchange_mtu_reply(conn_handle, NRF_SDH_BLE_GATT_MAX_MTU_SIZE));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BLE_GAP_EVT_PASSKEY_DISPLAY:
|
||||
securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_TIMEOUT:
|
||||
gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
|
||||
break;
|
||||
|
||||
case BLE_GATTC_EVT_TIMEOUT:
|
||||
case BLE_GATTS_EVT_TIMEOUT:
|
||||
// Disconnect on GATT Server and Client timeout events.
|
||||
// ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle,
|
||||
// BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_ADV_REPORT: {
|
||||
const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
|
||||
gap.processAdvertisementReport(advReport->peer_addr.addr,
|
||||
advReport->rssi,
|
||||
advReport->scan_rsp,
|
||||
static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
|
||||
advReport->dlen,
|
||||
advReport->data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gattServer.hwCallback(p_ble_evt);
|
||||
}
|
||||
|
||||
/*! @brief Callback when an error occurs inside the SoftDevice */
|
||||
void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name)
|
||||
{
|
||||
ASSERT_TRUE(false, (void) 0);
|
||||
}
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
/*!
|
||||
@brief Handler for general errors above the SoftDevice layer.
|
||||
Typically we can' recover from this so we do a reset.
|
||||
This implementation will override the default weak symbol generated by the Nordic SDK
|
||||
*/
|
||||
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
|
||||
{
|
||||
ASSERT_STATUS_RET_VOID( id );
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#else
|
||||
/*!
|
||||
@brief Handler for general errors above the SoftDevice layer.
|
||||
Typically we can' recover from this so we do a reset.
|
||||
*/
|
||||
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
|
||||
{
|
||||
ASSERT_STATUS_RET_VOID( error_code );
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NRF_SDK14PLUS_EVENT_HANDLERS
|
||||
/*!
|
||||
@brief Handler of Softdevice events.
|
||||
This signals that the softdevie has events that need to be processed.
|
||||
*/
|
||||
extern "C" void SD_EVT_IRQHandler(void)
|
||||
{
|
||||
ASSERT_STATUS_RET_VOID(signalEvent());
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,75 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef _BTLE_H_
|
||||
#define _BTLE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
#include "ble_srv_common.h"
|
||||
#include "headers/nrf_ble.h"
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
#include "sdk_config.h"
|
||||
#endif
|
||||
|
||||
#define NRF_CONNECTION_TAG 1 /**<Connection tag to use with softdevice */
|
||||
|
||||
#define CENTRAL_LINK_COUNT NRF_SDH_BLE_CENTRAL_LINK_COUNT /**<number of central links used by the application. When changing this number remember to adjust the RAM settings */
|
||||
/** If value for YOTTA_CFG_NORDIC_BLE_PERIPHERAL_LINKS was used, ram settings are adjusted by the yotta target module. */
|
||||
#define PERIPHERAL_LINK_COUNT NRF_SDH_BLE_PERIPHERAL_LINK_COUNT /**<number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
|
||||
/** If value for YOTTA_CFG_NORDIC_BLE_CENTRAL_LINKS was used, ram settings are adjusted by the yotta target module. */
|
||||
#define TOTAL_LINK_COUNT NRF_SDH_BLE_TOTAL_LINK_COUNT /**<number of total links used by the application. When changing this number remember to adjust the RAM settings */
|
||||
#define GATTS_ATTR_TAB_SIZE NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE /**< GATTS attribite table size. */
|
||||
/** If value for YOTTA_CFG_NORDIC_BLE_GATTS_ATTR_TAB_SIZE was used, ram settings are adjusted by the yotta target module. */
|
||||
|
||||
/**
|
||||
* Using this call, the application can select whether to include the
|
||||
* Service Changed characteristic in the GATT Server. The default in all
|
||||
* previous releases has been to include the Service Changed characteristic,
|
||||
* but this affects how GATT clients behave. Specifically, it requires
|
||||
* clients to subscribe to this attribute and not to cache attribute handles
|
||||
* between connections unless the devices are bonded. If the application
|
||||
* does not need to change the structure of the GATT server attributes at
|
||||
* runtime this adds unnecessary complexity to the interaction with peer
|
||||
* clients. If the SoftDevice is enabled with the Service Changed
|
||||
* Characteristics turned off, then clients are allowed to cache attribute
|
||||
* handles making applications simpler on both sides.
|
||||
*/
|
||||
#define IS_SRVC_CHANGED_CHARACT_PRESENT NRF_SDH_BLE_SERVICE_CHANGED
|
||||
|
||||
#define UUID_TABLE_MAX_ENTRIES NRF_SDH_BLE_VS_UUID_COUNT /* This is the maximum number of 128-bit UUIDs with distinct bases that
|
||||
* we expect to be in use; increase this limit if needed. */
|
||||
|
||||
#define NRF_SDK14PLUS_EVENT_HANDLERS (NRF_SD_BLE_API_VERSION >= 5) // Softdevice event dispatching has changed in SDK14
|
||||
|
||||
error_t btle_init(void);
|
||||
|
||||
// flag indicating if events have been signaled or not
|
||||
// It is used by processEvents and signalEventsToProcess
|
||||
// signalEventsToProcess raise the flag and processEvents
|
||||
// clears it.
|
||||
extern volatile bool isEventsSignaled;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ifndef _BTLE_H_
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 _BTLE_CLOCK_H_
|
||||
#define _BTLE_CLOCK_H_
|
||||
|
||||
#include "nrf5x_lf_clk_helper.h"
|
||||
|
||||
/**
|
||||
* @brief Module that generates settings for the low-frequency (LF) clock configuration.
|
||||
*
|
||||
* This module provides macros that are generated from the mbed config system macros.
|
||||
*
|
||||
*
|
||||
*
|
||||
* As a result, this module provides the following: @n
|
||||
* - literal value LFCLK_CONF_SOURCE @n
|
||||
* - literal value LFCLK_CONF_ACCURACY @n
|
||||
* - literal value LFCLK_CONF_RC_CTIV @n
|
||||
* - literal value LFCLK_CONF_RC_TEMP_CTIV
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "nrf_sdm.h"
|
||||
|
||||
#define DEFAULT_LFCLK_CONF_ACCURACY NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
|
||||
|
||||
#ifdef NRF52
|
||||
#define MAX_LFCLK_CONF_RC_CTIV 32
|
||||
#else
|
||||
#define MAX_LFCLK_CONF_RC_CTIV 64
|
||||
#endif
|
||||
|
||||
#define MAX_LFCLK_CONF_RC_TEMP_CTIV 33
|
||||
|
||||
#define DEFAULT_LFCLK_CONF_RC_CTIV 16 // Check temperature every 16 * 250ms.
|
||||
#define DEFAULT_LFCLK_CONF_RC_TEMP_CTIV 1 // Only calibrate if temperature has changed.
|
||||
|
||||
#define NRF_LF_SRC_XTAL 2
|
||||
#define NRF_LF_SRC_SYNTH 3
|
||||
#define NRF_LF_SRC_RC 4
|
||||
|
||||
#if MBED_CONF_NORDIC_NRF_LF_CLOCK_SRC == NRF_LF_SRC_RC
|
||||
#define LFCLK_CONF_SOURCE NRF_CLOCK_LF_SRC_RC
|
||||
|
||||
#ifdef MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL
|
||||
#define LFCLK_CONF_RC_CTIV MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL
|
||||
#else
|
||||
#define LFCLK_CONF_RC_CTIV DEFAULT_LFCLK_CONF_RC_CTIV
|
||||
#endif
|
||||
|
||||
#ifdef MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG
|
||||
#define LFCLK_CONF_RC_TEMP_CTIV MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG
|
||||
#else
|
||||
#define LFCLK_CONF_RC_TEMP_CTIV DEFAULT_LFCLK_CONF_RC_TEMP_CTIV
|
||||
#endif
|
||||
|
||||
#if (LFCLK_CONF_RC_CTIV < 1) || (LFCLK_CONF_RC_CTIV > MAX_LFCLK_CONF_RC_CTIV)
|
||||
#error Calibration timer interval out of range!
|
||||
#endif
|
||||
|
||||
#if (LFCLK_CONF_RC_TEMP_CTIV < 0 ) || (LFCLK_CONF_RC_TEMP_CTIV > 33)
|
||||
#error Number/mode of LF RC calibration intervals out of range!
|
||||
#endif
|
||||
|
||||
#elif MBED_CONF_NORDIC_NRF_LF_CLOCK_SRC == NRF_LF_SRC_SYNTH
|
||||
#define LFCLK_CONF_SOURCE NRF_CLOCK_LF_SRC_SYNTH
|
||||
#define LFCLK_CONF_RC_CTIV 0 // Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
|
||||
#define LFCLK_CONF_RC_TEMP_CTIV 0 // Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
|
||||
|
||||
#ifdef MBED_CONF_NORDIC_LF_CLOCK_HF_SYNTH_ACCURACY
|
||||
#define LFCLK_CONF_ACCURACY MBED_CONF_NORDIC_LF_CLOCK_HF_SYNTH_ACCURACY
|
||||
#endif
|
||||
|
||||
#else // default is NRF_LF_SRC_SYNTH
|
||||
#define LFCLK_CONF_SOURCE NRF_CLOCK_LF_SRC_XTAL
|
||||
#define LFCLK_CONF_RC_CTIV 0 // Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
|
||||
#define LFCLK_CONF_RC_TEMP_CTIV 0 // Must be 0 if source is not NRF_CLOCK_LF_SRC_RC.
|
||||
|
||||
#ifdef MBED_CONF_NORDIC_LF_CLOCK_XTAL_ACCURACY
|
||||
#define LFCLK_CONF_ACCURACY MBED_CONF_NORDIC_LF_CLOCK_XTAL_ACCURACY
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LFCLK_CONF_ACCURACY
|
||||
#define LFCLK_CONF_ACCURACY DEFAULT_LFCLK_CONF_ACCURACY
|
||||
#endif
|
||||
|
||||
#if (LFCLK_CONF_ACCURACY > NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM) || (LFCLK_CONF_ACCURACY < NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM)
|
||||
#error Low frequency clock accuracy out of range!
|
||||
#endif
|
||||
|
||||
|
||||
#endif //_BTLE_CLOCK_H_
|
||||
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#include "common/common.h"
|
||||
|
||||
#include "headers/ble_gap.h"
|
||||
#include "ble_conn_params.h"
|
||||
|
||||
static inline uint32_t msec_to_1_25msec(uint32_t interval_ms) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
#if SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
static void error_callback(uint32_t nrf_error);
|
||||
#endif // SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialise GAP in the underlying SoftDevice
|
||||
|
||||
@returns
|
||||
*/
|
||||
/**************************************************************************/
|
||||
error_t btle_gap_init(void)
|
||||
{
|
||||
ble_gap_conn_params_t gap_conn_params = {0};
|
||||
|
||||
gap_conn_params.min_conn_interval = msec_to_1_25msec(CFG_GAP_CONNECTION_MIN_INTERVAL_MS); // in 1.25ms units
|
||||
gap_conn_params.max_conn_interval = msec_to_1_25msec(CFG_GAP_CONNECTION_MAX_INTERVAL_MS); // in 1.25ms unit
|
||||
gap_conn_params.slave_latency = CFG_GAP_CONNECTION_SLAVE_LATENCY;
|
||||
gap_conn_params.conn_sup_timeout = CFG_GAP_CONNECTION_SUPERVISION_TIMEOUT_MS / 10; // in 10ms unit
|
||||
|
||||
ble_gap_conn_sec_mode_t sec_mode;
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
|
||||
|
||||
ASSERT_STATUS( sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) CFG_GAP_LOCAL_NAME, strlen(CFG_GAP_LOCAL_NAME)));
|
||||
ASSERT_STATUS( sd_ble_gap_appearance_set(CFG_GAP_APPEARANCE));
|
||||
ASSERT_STATUS( sd_ble_gap_ppcp_set(&gap_conn_params));
|
||||
ASSERT_STATUS( sd_ble_gap_tx_power_set(CFG_BLE_TX_POWER_LEVEL));
|
||||
|
||||
/**
|
||||
* Call to conn_params_init() is not necessary; and so is disabled by default.
|
||||
* This API should be exposed to the user to be invoked when necessary.
|
||||
*/
|
||||
#if SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
/* Connection Parameters */
|
||||
enum {
|
||||
FIRST_UPDATE_DELAY = APP_TIMER_TICKS(5000, CFG_TIMER_PRESCALER),
|
||||
NEXT_UPDATE_DELAY = APP_TIMER_TICKS(5000, CFG_TIMER_PRESCALER),
|
||||
MAX_UPDATE_COUNT = 3
|
||||
};
|
||||
|
||||
ble_conn_params_init_t cp_init = {0};
|
||||
|
||||
cp_init.p_conn_params = NULL;
|
||||
cp_init.first_conn_params_update_delay = FIRST_UPDATE_DELAY;
|
||||
cp_init.next_conn_params_update_delay = NEXT_UPDATE_DELAY;
|
||||
cp_init.max_conn_params_update_count = MAX_UPDATE_COUNT;
|
||||
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
|
||||
cp_init.disconnect_on_fail = true;
|
||||
cp_init.evt_handler = NULL;
|
||||
cp_init.error_handler = error_callback;
|
||||
|
||||
ASSERT_STATUS ( ble_conn_params_init(&cp_init));
|
||||
#endif // SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Converts msecs to an integer representing 1.25ms units
|
||||
|
||||
@param[in] ms
|
||||
The number of milliseconds to conver to 1.25ms units
|
||||
|
||||
@returns The number of 1.25ms units in the supplied number of ms
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static inline uint32_t msec_to_1_25msec(uint32_t interval_ms)
|
||||
{
|
||||
return (interval_ms * 4) / 5;
|
||||
}
|
||||
|
||||
#if SDK_CONN_PARAMS_MODULE_ENABLE
|
||||
static void error_callback(uint32_t nrf_error)
|
||||
{
|
||||
ASSERT_STATUS_RET_VOID( nrf_error );
|
||||
}
|
||||
#endif // SDK_CONN_PARAMS_MODULE_ENABLE
|
|
@ -0,0 +1,24 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef _BTLE_GAP_H_
|
||||
#define _BTLE_GAP_H_
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
error_t btle_gap_init(void);
|
||||
|
||||
#endif // ifndef _BTLE_GAP_H_
|
|
@ -0,0 +1,326 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#if defined(S110)
|
||||
#include "btle.h"
|
||||
|
||||
#include "nRF5xn.h"
|
||||
|
||||
extern "C" {
|
||||
#include "pstorage.h"
|
||||
#include "device_manager.h"
|
||||
#include "id_manager.h"
|
||||
}
|
||||
|
||||
#include "btle_security.h"
|
||||
|
||||
static dm_application_instance_t applicationInstance;
|
||||
static bool initialized = false;
|
||||
static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result);
|
||||
|
||||
// default security parameters. Avoid "holes" between member assigments in order to compile by gcc++11.
|
||||
static ble_gap_sec_params_t securityParameters = {
|
||||
.bond = true, /**< Perform bonding. */
|
||||
.mitm = true, /**< Man In The Middle protection required. */
|
||||
.lesc = false, /**< Enable LE Secure Connection pairing. */
|
||||
.keypress = false, /**< Enable generation of keypress notifications. */
|
||||
.io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
|
||||
.oob = 0, /**< Out Of Band data available. */
|
||||
.min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
|
||||
.max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
|
||||
.kdist_own = {
|
||||
.enc = 0, /**< Long Term Key and Master Identification. */
|
||||
.id = 0, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
}, /**< Key distribution bitmap: keys that the local device will distribute. */
|
||||
.kdist_peer = {
|
||||
.enc = 1, /**< Long Term Key and Master Identification. */
|
||||
.id = 1, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 1, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
} /**< Key distribution bitmap: keys that the peripheral device will distribute. */
|
||||
};
|
||||
|
||||
bool
|
||||
btle_hasInitializedSecurity(void)
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_initializeSecurity(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps,
|
||||
const SecurityManager::Passkey_t passkey)
|
||||
{
|
||||
/* guard against multiple initializations */
|
||||
if (initialized) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
if (pstorage_init() != NRF_SUCCESS) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
ret_code_t rc;
|
||||
if (passkey) {
|
||||
ble_opt_t opts;
|
||||
opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
|
||||
if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
default:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_BUSY:
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dm_init_param_t dm_init_param = {
|
||||
.clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
|
||||
};
|
||||
if (dm_init(&dm_init_param) != NRF_SUCCESS) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
// update default security parameters with function call parameters
|
||||
securityParameters.bond = enableBonding;
|
||||
securityParameters.mitm = requireMITM;
|
||||
securityParameters.io_caps = iocaps;
|
||||
|
||||
const dm_application_param_t dm_param = {
|
||||
.evt_handler = dm_handler,
|
||||
.service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
|
||||
.sec_param = securityParameters
|
||||
};
|
||||
|
||||
if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_purgeAllBondingState(void)
|
||||
{
|
||||
ret_code_t rc;
|
||||
if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
|
||||
{
|
||||
ret_code_t rc;
|
||||
dm_handle_t dmHandle = {
|
||||
.appl_id = applicationInstance,
|
||||
};
|
||||
if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
|
||||
if (rc == NRF_ERROR_NOT_FOUND) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
} else {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_NO_MEM:
|
||||
return BLE_ERROR_NO_MEM;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
|
||||
{
|
||||
// use default and updated parameters as starting point
|
||||
// and modify structure based on security mode.
|
||||
ble_gap_sec_params_t params = securityParameters;
|
||||
|
||||
switch (securityMode) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
|
||||
/**< Require no protection, open link. */
|
||||
securityParameters.bond = false;
|
||||
securityParameters.mitm = false;
|
||||
break;
|
||||
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
|
||||
/**< Require encryption, but no MITM protection. */
|
||||
securityParameters.bond = true;
|
||||
securityParameters.mitm = false;
|
||||
break;
|
||||
|
||||
// not yet implemented security modes
|
||||
case SecurityManager::SECURITY_MODE_NO_ACCESS:
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
|
||||
/**< Require encryption and MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
|
||||
/**< Require signing or encryption, but no MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
|
||||
/**< Require signing or encryption, and MITM protection. */
|
||||
default:
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// update security settings for given connection
|
||||
uint32_t result = sd_ble_gap_authenticate(connectionHandle, ¶ms);
|
||||
|
||||
if (result == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ret_code_t
|
||||
dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
|
||||
{
|
||||
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
|
||||
|
||||
switch (p_event->event_id) {
|
||||
case DM_EVT_SECURITY_SETUP: /* started */ {
|
||||
const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
|
||||
securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
|
||||
peerParams->bond,
|
||||
peerParams->mitm,
|
||||
(SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
|
||||
break;
|
||||
}
|
||||
case DM_EVT_SECURITY_SETUP_COMPLETE:
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
|
||||
(SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
|
||||
break;
|
||||
case DM_EVT_LINK_SECURED: {
|
||||
unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
|
||||
unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
|
||||
SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
|
||||
switch (securityMode) {
|
||||
case 1:
|
||||
switch (level) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
|
||||
break;
|
||||
case 3:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (level) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
|
||||
break;
|
||||
}
|
||||
case DM_EVT_DEVICE_CONTEXT_STORED:
|
||||
securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
|
||||
{
|
||||
if (!btle_hasInitializedSecurity()) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
ret_code_t err = dm_whitelist_create(&applicationInstance, p_whitelist);
|
||||
if (err == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else if (err == NRF_ERROR_NULL) {
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
} else {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
|
||||
{
|
||||
/*
|
||||
* Use a helper function from the Nordic SDK to test whether the BLE
|
||||
* address can be generated using the IRK.
|
||||
*/
|
||||
return im_address_resolve(p_addr, p_irk);
|
||||
}
|
||||
|
||||
void
|
||||
btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address)
|
||||
{
|
||||
/* Set type to resolvable */
|
||||
address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
||||
|
||||
/*
|
||||
* Assign a random number to the most significant 3 bytes
|
||||
* of the address.
|
||||
*/
|
||||
address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C;
|
||||
|
||||
/* Calculate the hash and store it in the top half of the address */
|
||||
ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,146 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef _BTLE_SECURITY_H_
|
||||
#define _BTLE_SECURITY_H_
|
||||
|
||||
#include "ble/Gap.h"
|
||||
#include "ble/SecurityManager.h"
|
||||
|
||||
/**
|
||||
* Function to test whether the SecurityManager has been initialized.
|
||||
* Possible by a call to @ref btle_initializeSecurity().
|
||||
*
|
||||
* @return True if the SecurityManager was previously initialized, false
|
||||
* otherwise.
|
||||
*/
|
||||
bool btle_hasInitializedSecurity(void);
|
||||
|
||||
/**
|
||||
* Enable Nordic's Device Manager, which brings in functionality from the
|
||||
* stack's Security Manager. The Security Manager implements the actual
|
||||
* cryptographic algorithms and protocol exchanges that allow two devices to
|
||||
* securely exchange data and privately detect each other.
|
||||
*
|
||||
* @param[in] enableBonding Allow for bonding.
|
||||
* @param[in] requireMITM Require protection for man-in-the-middle attacks.
|
||||
* @param[in] iocaps To specify IO capabilities of this peripheral,
|
||||
* such as availability of a display or keyboard to
|
||||
* support out-of-band exchanges of security data.
|
||||
* @param[in] passkey To specify a static passkey.
|
||||
*
|
||||
* @return BLE_ERROR_NONE on success.
|
||||
*/
|
||||
ble_error_t btle_initializeSecurity(bool enableBonding = true,
|
||||
bool requireMITM = true,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE,
|
||||
const SecurityManager::Passkey_t passkey = NULL);
|
||||
|
||||
/**
|
||||
* Get the security status of a link.
|
||||
*
|
||||
* @param[in] connectionHandle
|
||||
* Handle to identify the connection.
|
||||
* @param[out] securityStatusP
|
||||
* security status.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP);
|
||||
|
||||
/**
|
||||
* Set the security mode on a connection. Useful for elevating the security mode
|
||||
* once certain conditions are met, e.g., a particular service is found.
|
||||
*
|
||||
* @param[in] connectionHandle
|
||||
* Handle to identify the connection.
|
||||
* @param[in] securityMode
|
||||
* security mode.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode);
|
||||
|
||||
/**
|
||||
* Function for deleting all peer device context and all related bonding
|
||||
* information from the database.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure.
|
||||
* @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
||||
* application registration.
|
||||
*/
|
||||
ble_error_t btle_purgeAllBondingState(void);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/**
|
||||
* Query the SoftDevice bond table to extract a whitelist containing the BLE
|
||||
* addresses and IRKs of bonded devices.
|
||||
*
|
||||
* @param[in/out] p_whitelist
|
||||
* (on input) p_whitelist->addr_count and
|
||||
* p_whitelist->irk_count specify the maximum number of
|
||||
* addresses and IRKs added to the whitelist structure.
|
||||
* (on output) *p_whitelist is a whitelist containing the
|
||||
* addresses and IRKs of the bonded devices.
|
||||
*
|
||||
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
|
||||
*/
|
||||
ble_error_t btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function to test whether a BLE address is generated using an IRK.
|
||||
*
|
||||
* @param[in] p_addr
|
||||
* Pointer to a BLE address.
|
||||
* @param[in] p_irk
|
||||
* Pointer to an IRK.
|
||||
*
|
||||
* @return True if p_addr can be generated using p_irk, false otherwise.
|
||||
*/
|
||||
bool btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
|
||||
|
||||
/**
|
||||
* Function to generate a private resolvable BLE address.
|
||||
*
|
||||
* @param[out] p_addr
|
||||
* The output address.
|
||||
* @param[in] p_irk
|
||||
* A reference to a IRK.
|
||||
*
|
||||
* @note This function does not generate a secure address since the prand number in the
|
||||
* resolvable address is not truly random. Therefore, the output of this function
|
||||
* is only meant to be used by the application internally but never exported.
|
||||
*/
|
||||
void btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE if successful.
|
||||
* @retval BLE_ERROR_UNSPECIFIED Bond data could not be found in flash or is inconsistent.
|
||||
*/
|
||||
ble_error_t btle_getAddressesFromBondTable(Gap::Whitelist_t &addrList);
|
||||
#endif
|
||||
|
||||
#endif /* _BTLE_SECURITY_H_ */
|
|
@ -0,0 +1,488 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#if defined(S130) || defined(S132) || defined(S140)
|
||||
#include "btle.h"
|
||||
|
||||
#include "nRF5xn.h"
|
||||
|
||||
extern "C" {
|
||||
#include "peer_manager.h"
|
||||
#include "id_manager.h"
|
||||
#include "fds.h"
|
||||
}
|
||||
|
||||
#include "btle_security.h"
|
||||
|
||||
extern "C" void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash);
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
static void pm_handler(pm_evt_t const *p_event);
|
||||
static bool _enc_in_progress = false; // helper flag for distinguish between state of link connected and link connected in progres of encryption establishing.
|
||||
volatile static uint32_t async_ret_code; // busy loop support variable for asyncronous API.
|
||||
|
||||
// default security parameters. Avoid "holes" between member assigments in order to compile by gcc++11.
|
||||
static ble_gap_sec_params_t securityParameters = {
|
||||
.bond = true, /**< Perform bonding. */
|
||||
.mitm = true, /**< Man In The Middle protection required. */
|
||||
.lesc = false, /**< Enable LE Secure Connection pairing. */
|
||||
.keypress = false, /**< Enable generation of keypress notifications. */
|
||||
.io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
|
||||
.oob = 0, /**< Out Of Band data available. */
|
||||
.min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
|
||||
.max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
|
||||
.kdist_own = {
|
||||
.enc = 0, /**< Long Term Key and Master Identification. */
|
||||
.id = 0, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
}, /**< Key distribution bitmap: keys that the local device will distribute. */
|
||||
.kdist_peer = {
|
||||
.enc = 1, /**< Long Term Key and Master Identification. */
|
||||
.id = 1, /**< Identity Resolving Key and Identity Address Information. */
|
||||
.sign = 0, /**< Connection Signature Resolving Key. */
|
||||
.link = 0 /**< Derive the Link Key from the LTK. */
|
||||
} /**< Key distribution bitmap: keys that the peripheral device will distribute. */
|
||||
};
|
||||
|
||||
bool
|
||||
btle_hasInitializedSecurity(void)
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
ble_error_t
|
||||
btle_initializeSecurity(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityManager::SecurityIOCapabilities_t iocaps,
|
||||
const SecurityManager::Passkey_t passkey)
|
||||
{
|
||||
/* guard against multiple initializations */
|
||||
if (initialized) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ret_code_t rc;
|
||||
if (passkey) {
|
||||
ble_opt_t opts;
|
||||
opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
|
||||
if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
default:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
case NRF_ERROR_BUSY:
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update default security parameters with function call parameters
|
||||
securityParameters.bond = enableBonding;
|
||||
securityParameters.mitm = requireMITM;
|
||||
securityParameters.io_caps = iocaps;
|
||||
|
||||
if (enableBonding) {
|
||||
securityParameters.kdist_own.enc = 1;
|
||||
securityParameters.kdist_own.id = 1;
|
||||
} else {
|
||||
securityParameters.kdist_own.enc = 0;
|
||||
securityParameters.kdist_own.id = 0;
|
||||
}
|
||||
rc = pm_sec_params_set(&securityParameters);
|
||||
|
||||
if (rc == NRF_SUCCESS) {
|
||||
rc = pm_register(pm_handler);
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_purgeAllBondingState(void)
|
||||
{
|
||||
ret_code_t rc;
|
||||
|
||||
async_ret_code = NRF_ERROR_BUSY;
|
||||
|
||||
rc = pm_peers_delete(); // it is asynhronous API
|
||||
|
||||
if (rc == NRF_SUCCESS)
|
||||
{
|
||||
// waiting for respond from pm_handler
|
||||
while (async_ret_code == NRF_ERROR_BUSY) {
|
||||
// busy-loop
|
||||
}
|
||||
|
||||
rc = async_ret_code;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
|
||||
{
|
||||
ret_code_t rc;
|
||||
pm_conn_sec_status_t conn_sec_status;
|
||||
|
||||
rc = pm_conn_sec_status_get(connectionHandle, &conn_sec_status);
|
||||
|
||||
if (rc == NRF_SUCCESS)
|
||||
{
|
||||
if (conn_sec_status.encrypted) {
|
||||
*securityStatusP = SecurityManager::ENCRYPTED;
|
||||
}
|
||||
else if (conn_sec_status.connected) {
|
||||
if (_enc_in_progress) {
|
||||
*securityStatusP = SecurityManager::ENCRYPTION_IN_PROGRESS;
|
||||
}
|
||||
else {
|
||||
*securityStatusP = SecurityManager::NOT_ENCRYPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t
|
||||
btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
|
||||
{
|
||||
// use default and updated parameters as starting point
|
||||
// and modify structure based on security mode.
|
||||
ret_code_t rc;
|
||||
|
||||
switch (securityMode) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
|
||||
/**< Require no protection, open link. */
|
||||
securityParameters.bond = false;
|
||||
securityParameters.mitm = false;
|
||||
securityParameters.kdist_own.enc = 0;
|
||||
break;
|
||||
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
|
||||
/**< Require encryption, but no MITM protection. */
|
||||
securityParameters.bond = true;
|
||||
securityParameters.mitm = false;
|
||||
securityParameters.kdist_own.enc = 1;
|
||||
break;
|
||||
|
||||
// not yet implemented security modes
|
||||
case SecurityManager::SECURITY_MODE_NO_ACCESS:
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
|
||||
/**< Require encryption and MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
|
||||
/**< Require signing or encryption, but no MITM protection. */
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
|
||||
/**< Require signing or encryption, and MITM protection. */
|
||||
default:
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// update security settings for given connection
|
||||
|
||||
rc = pm_sec_params_set(&securityParameters);
|
||||
|
||||
if (rc == NRF_SUCCESS) {
|
||||
rc = pm_conn_secure(connectionHandle, false);
|
||||
}
|
||||
|
||||
switch (rc) {
|
||||
case NRF_SUCCESS:
|
||||
initialized = true;
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pm_handler(pm_evt_t const *p_event)
|
||||
{
|
||||
nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
|
||||
ret_code_t err_code;
|
||||
SecurityManager::SecurityMode_t resolvedSecurityMode;
|
||||
|
||||
switch (p_event->evt_id) {
|
||||
case PM_EVT_CONN_SEC_START: /* started */ {
|
||||
const ble_gap_sec_params_t *peerParams = &securityParameters;
|
||||
securityManager.processSecuritySetupInitiatedEvent(p_event->conn_handle,
|
||||
peerParams->bond,
|
||||
peerParams->mitm,
|
||||
(SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
|
||||
_enc_in_progress = true;
|
||||
break;
|
||||
}
|
||||
case PM_EVT_CONN_SEC_SUCCEEDED:
|
||||
// Update the rank of the peer.
|
||||
if (p_event->params.conn_sec_succeeded.procedure == PM_LINK_SECURED_PROCEDURE_BONDING)
|
||||
{
|
||||
err_code = pm_peer_rank_highest(p_event->peer_id);
|
||||
}
|
||||
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->conn_handle,
|
||||
SecurityManager::SEC_STATUS_SUCCESS);// SEC_STATUS_SUCCESS of SecurityCompletionStatus_t
|
||||
|
||||
ble_gap_conn_sec_t conn_sec;
|
||||
sd_ble_gap_conn_sec_get(p_event->conn_handle, &conn_sec);
|
||||
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
|
||||
|
||||
switch (conn_sec.sec_mode.sm) {
|
||||
case 1:
|
||||
switch (conn_sec.sec_mode.lv) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
|
||||
break;
|
||||
case 3:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (conn_sec.sec_mode.lv) {
|
||||
case 1:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
|
||||
break;
|
||||
case 2:
|
||||
resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
securityManager.processLinkSecuredEvent(p_event->conn_handle, resolvedSecurityMode);
|
||||
|
||||
_enc_in_progress = false;
|
||||
break;
|
||||
|
||||
case PM_EVT_CONN_SEC_FAILED:
|
||||
SecurityManager::SecurityCompletionStatus_t securityCompletionStatus;
|
||||
|
||||
if ((uint32_t)p_event->params.conn_sec_failed.error >= PM_CONN_SEC_ERROR_BASE ) {
|
||||
securityCompletionStatus = SecurityManager::SEC_STATUS_UNSPECIFIED;
|
||||
} else {
|
||||
securityCompletionStatus =
|
||||
(SecurityManager::SecurityCompletionStatus_t)p_event->params.conn_sec_failed.error;
|
||||
}
|
||||
|
||||
securityManager.
|
||||
processSecuritySetupCompletedEvent(p_event->conn_handle, securityCompletionStatus);
|
||||
|
||||
_enc_in_progress = false;
|
||||
break;
|
||||
|
||||
case PM_EVT_BONDED_PEER_CONNECTED:
|
||||
pm_peer_rank_highest(p_event->peer_id);
|
||||
break;
|
||||
|
||||
case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
|
||||
if (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
|
||||
{
|
||||
securityManager.processSecurityContextStoredEvent(p_event->conn_handle);
|
||||
}
|
||||
break;
|
||||
|
||||
case PM_EVT_PEER_DATA_UPDATE_FAILED:
|
||||
break;
|
||||
|
||||
case PM_EVT_PEERS_DELETE_SUCCEEDED:
|
||||
async_ret_code = NRF_SUCCESS; // respond SUCCESS to the busy-loop in f. btle_purgeAllBondingState
|
||||
break;
|
||||
|
||||
case PM_EVT_PEERS_DELETE_FAILED:
|
||||
async_ret_code = NRF_ERROR_INTERNAL; // respond FAILURE to the busy-loop in f. btle_purgeAllBondingState
|
||||
break;
|
||||
|
||||
case PM_EVT_STORAGE_FULL:
|
||||
// Run garbage collection on the flash.
|
||||
err_code = fds_gc();
|
||||
if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
|
||||
{
|
||||
// Retry.
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
break;//PM_EVT_STORAGE_FULL
|
||||
|
||||
case PM_EVT_CONN_SEC_CONFIG_REQ:{
|
||||
// A connected peer (central) is trying to pair, but the Peer Manager already has a bond
|
||||
// for that peer. Setting allow_repairing to false rejects the pairing request.
|
||||
// If this event is ignored (pm_conn_sec_config_reply is not called in the event
|
||||
// handler), the Peer Manager assumes allow_repairing to be false.
|
||||
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
|
||||
pm_conn_sec_config_reply(p_event->conn_handle, &conn_sec_config);
|
||||
}
|
||||
break;//PM_EVT_CONN_SEC_CONFIG_REQ
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
ble_error_t
|
||||
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
|
||||
{
|
||||
if (!btle_hasInitializedSecurity()) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
ret_code_t err = pm_whitelist_create( NULL, BLE_GAP_WHITELIST_ADDR_MAX_COUNT, p_whitelist);
|
||||
if (err == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
} else if (err == NRF_ERROR_NULL) {
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
} else {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
|
||||
{
|
||||
/*
|
||||
* Use a helper function from the Nordic SDK to test whether the BLE
|
||||
* address can be generated using the IRK.
|
||||
*/
|
||||
return im_address_resolve(p_addr, p_irk);
|
||||
}
|
||||
|
||||
void
|
||||
btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address)
|
||||
{
|
||||
/* Set type to resolvable */
|
||||
address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
|
||||
|
||||
/*
|
||||
* Assign a random number to the most significant 3 bytes
|
||||
* of the address.
|
||||
*/
|
||||
address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F;
|
||||
address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C;
|
||||
|
||||
/* Calculate the hash and store it in the top half of the address */
|
||||
ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr);
|
||||
}
|
||||
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
ble_error_t btle_getAddressesFromBondTable(Gap::Whitelist_t &addrList)
|
||||
{
|
||||
pm_peer_id_t peer_id;
|
||||
ret_code_t ret;
|
||||
pm_peer_data_bonding_t bond_data;
|
||||
|
||||
addrList.size = 0;
|
||||
peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
|
||||
|
||||
/**
|
||||
* Fill addresses list:
|
||||
* Copy addresses from bond table, or
|
||||
* for every private resolvable address in the bond table generate the resolvable address.
|
||||
*/
|
||||
while ((peer_id != PM_PEER_ID_INVALID) && (addrList.capacity > addrList.size)) {
|
||||
memset(&bond_data, 0x00, sizeof(bond_data));
|
||||
|
||||
// Read peer data from flash.
|
||||
ret = pm_peer_data_bonding_load(peer_id, &bond_data);
|
||||
|
||||
if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) {
|
||||
// Peer data could not be found in flash or peer ID is not valid.
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (bond_data.peer_ble_id.id_addr_info.addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) {
|
||||
btle_generateResolvableAddress(bond_data.peer_ble_id.id_info,
|
||||
(ble_gap_addr_t &) addrList.addresses[addrList.size].address);
|
||||
} else {
|
||||
memcpy(&addrList.addresses[addrList.size].address,
|
||||
&bond_data.peer_ble_id.id_addr_info.addr,
|
||||
sizeof(addrList.addresses[0].address));
|
||||
}
|
||||
|
||||
addrList.addresses[addrList.size].type = static_cast<BLEProtocol::AddressType_t> (bond_data.peer_ble_id.id_addr_info.addr_type);
|
||||
|
||||
addrList.size++;
|
||||
|
||||
// get next peer id
|
||||
peer_id = pm_next_peer_id_get(peer_id);
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(S130) || defined(S132) || defined(S140)
|
|
@ -0,0 +1,372 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#include "custom_helper.h"
|
||||
#include "../btle.h"
|
||||
|
||||
/*
|
||||
* The current version of the soft-device doesn't handle duplicate 128-bit UUIDs
|
||||
* very well. It is therefore necessary to filter away duplicates before
|
||||
* passing long UUIDs to sd_ble_uuid_vs_add(). The following types and data
|
||||
* structures involved in maintaining a local cache of 128-bit UUIDs.
|
||||
*/
|
||||
typedef struct {
|
||||
UUID::LongUUIDBytes_t uuid;
|
||||
uint8_t type;
|
||||
} converted_uuid_table_entry_t;
|
||||
|
||||
static unsigned uuidTableEntries = 0; /* current usage of the table */
|
||||
converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES];
|
||||
|
||||
void custom_reset_128bits_uuid_table() {
|
||||
uuidTableEntries = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup the cache of previously converted 128-bit UUIDs to find a type value.
|
||||
* @param uuid base 128-bit UUID
|
||||
* @param recoveredType the type field of the 3-byte nRF's uuid.
|
||||
* @return true if a match is found.
|
||||
*/
|
||||
static bool
|
||||
lookupConvertedUUIDTable(const UUID::LongUUIDBytes_t uuid, uint8_t *recoveredType)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < uuidTableEntries; i++) {
|
||||
unsigned byteIndex;
|
||||
for (byteIndex = 0; byteIndex < UUID::LENGTH_OF_LONG_UUID; byteIndex++) {
|
||||
/* Skip bytes 2 and 3, because they contain the shortUUID (16-bit) version of the
|
||||
* long UUID; and we're comparing against the remainder. */
|
||||
if ((byteIndex == 2) || (byteIndex == 3)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (convertedUUIDTable[i].uuid[byteIndex] != uuid[byteIndex]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (byteIndex == UUID::LENGTH_OF_LONG_UUID) {
|
||||
*recoveredType = convertedUUIDTable[i].type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
addToConvertedUUIDTable(const UUID::LongUUIDBytes_t uuid, uint8_t type)
|
||||
{
|
||||
if (uuidTableEntries == UUID_TABLE_MAX_ENTRIES) {
|
||||
return; /* recovery needed; or at least the user should be warned about this fact.*/
|
||||
}
|
||||
|
||||
memcpy(convertedUUIDTable[uuidTableEntries].uuid, uuid, UUID::LENGTH_OF_LONG_UUID);
|
||||
convertedUUIDTable[uuidTableEntries].uuid[2] = 0;
|
||||
convertedUUIDTable[uuidTableEntries].uuid[3] = 0;
|
||||
convertedUUIDTable[uuidTableEntries].type = type;
|
||||
uuidTableEntries++;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nRF transport has its own 3-byte representation of a UUID. If the user-
|
||||
* specified UUID is 128-bits wide, then the UUID base needs to be added to the
|
||||
* soft-device and converted to a 3-byte handle before being used further. This
|
||||
* function is responsible for this translation of user-specified UUIDs into
|
||||
* nRF's representation.
|
||||
*
|
||||
* @param[in] uuid
|
||||
* user-specified UUID
|
||||
* @return nRF
|
||||
* 3-byte UUID (containing a type and 16-bit UUID) representation
|
||||
* to be used with SVC calls.
|
||||
*/
|
||||
ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid)
|
||||
{
|
||||
ble_uuid_t nordicUUID;
|
||||
nordicUUID.uuid = uuid.getShortUUID();
|
||||
nordicUUID.type = BLE_UUID_TYPE_UNKNOWN; /* to be set below */
|
||||
|
||||
if (uuid.shortOrLong() == UUID::UUID_TYPE_SHORT) {
|
||||
nordicUUID.type = BLE_UUID_TYPE_BLE;
|
||||
} else {
|
||||
if (!lookupConvertedUUIDTable(uuid.getBaseUUID(), &nordicUUID.type)) {
|
||||
nordicUUID.type = custom_add_uuid_base(uuid.getBaseUUID());
|
||||
addToConvertedUUIDTable(uuid.getBaseUUID(), nordicUUID.type);
|
||||
}
|
||||
}
|
||||
|
||||
return nordicUUID;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Adds the base UUID to the custom service. All UUIDs used
|
||||
by this service are based on this 128-bit UUID.
|
||||
|
||||
@note This UUID needs to be added to the SoftDevice stack before
|
||||
adding the service's primary service via
|
||||
'sd_ble_gatts_service_add'
|
||||
|
||||
@param[in] p_uuid_base A pointer to the 128-bit UUID array (8*16)
|
||||
|
||||
@returns The UUID type.
|
||||
A return value of 0 should be considered an error.
|
||||
|
||||
@retval 0x00 BLE_UUID_TYPE_UNKNOWN
|
||||
@retval 0x01 BLE_UUID_TYPE_BLE
|
||||
@retval 0x02 BLE_UUID_TYPE_VENDOR_BEGIN
|
||||
|
||||
@section EXAMPLE
|
||||
@code
|
||||
|
||||
// Take note that bytes 2/3 are blank since these are used to identify
|
||||
// the primary service and individual characteristics
|
||||
#define CFG_CUSTOM_UUID_BASE "\x6E\x40\x00\x00\xB5\xA3\xF3\x93\xE0\xA9\xE5\x0E\x24\xDC\xCA\x9E"
|
||||
|
||||
uint8_t uuid_type = custom_add_uuid_base(CFG_CUSTOM_UUID_BASE);
|
||||
ASSERT(uuid_type > 0, ERROR_NOT_FOUND);
|
||||
|
||||
// We can now safely add the primary service and any characteristics
|
||||
// for our custom service ...
|
||||
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base)
|
||||
{
|
||||
ble_uuid128_t base_uuid;
|
||||
uint8_t uuid_type = 0;
|
||||
|
||||
for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
|
||||
base_uuid.uuid128[i] = p_uuid_base[i];
|
||||
}
|
||||
|
||||
ASSERT_INT( ERROR_NONE, sd_ble_uuid_vs_add( &base_uuid, &uuid_type ), 0);
|
||||
|
||||
return uuid_type;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
error_t custom_decode_uuid_base(uint8_t const *const p_uuid_base,
|
||||
ble_uuid_t *p_uuid)
|
||||
{
|
||||
UUID::LongUUIDBytes_t uuid_base_le;
|
||||
|
||||
for (uint8_t i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
|
||||
uuid_base_le[i] = p_uuid_base[i];
|
||||
}
|
||||
|
||||
ASSERT_STATUS( sd_ble_uuid_decode(UUID::LENGTH_OF_LONG_UUID, uuid_base_le, p_uuid));
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Adds a new characteristic to the custom service, assigning
|
||||
properties, a UUID add-on value, etc.
|
||||
|
||||
@param[in] service_handle
|
||||
@param[in] p_uuid The 16-bit value to add to the base UUID
|
||||
for this characteristic (normally >1
|
||||
since 1 is typically used by the primary
|
||||
service).
|
||||
@param[in] char_props The characteristic properties, as
|
||||
defined by ble_gatt_char_props_t
|
||||
@param[in] max_length The maximum length of this characeristic
|
||||
@param[in] has_variable_len Whether the characteristic data has
|
||||
variable length.
|
||||
@param[out] p_char_handle
|
||||
|
||||
@returns
|
||||
@retval ERROR_NONE Everything executed normally
|
||||
*/
|
||||
/**************************************************************************/
|
||||
error_t custom_add_in_characteristic(uint16_t service_handle,
|
||||
ble_uuid_t *p_uuid,
|
||||
uint8_t properties,
|
||||
SecurityManager::SecurityMode_t requiredSecurity,
|
||||
uint8_t *p_data,
|
||||
uint16_t length,
|
||||
uint16_t max_length,
|
||||
bool has_variable_len,
|
||||
const uint8_t *userDescriptionDescriptorValuePtr,
|
||||
uint16_t userDescriptionDescriptorValueLen,
|
||||
const uint8_t *presentationFormatDescriptorValuePtr,
|
||||
uint16_t presentationFormatDescriptorValueLen,
|
||||
bool readAuthorization,
|
||||
bool writeAuthorization,
|
||||
ble_gatts_char_handles_t *p_char_handle)
|
||||
{
|
||||
/* Characteristic metadata */
|
||||
ble_gatts_attr_md_t cccd_md;
|
||||
ble_gatt_char_props_t char_props;
|
||||
|
||||
memcpy(&char_props, &properties, 1);
|
||||
|
||||
if (char_props.notify || char_props.indicate) {
|
||||
/* Notification requires cccd */
|
||||
memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t));
|
||||
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
|
||||
}
|
||||
|
||||
ble_gatts_char_md_t char_md = {0};
|
||||
|
||||
char_md.char_props = char_props;
|
||||
char_md.p_cccd_md =
|
||||
(char_props.notify || char_props.indicate) ? &cccd_md : NULL;
|
||||
if ((userDescriptionDescriptorValueLen > 0) && (userDescriptionDescriptorValuePtr != NULL)) {
|
||||
char_md.p_char_user_desc = const_cast<uint8_t *>(userDescriptionDescriptorValuePtr);
|
||||
char_md.char_user_desc_max_size = userDescriptionDescriptorValueLen;
|
||||
char_md.char_user_desc_size = userDescriptionDescriptorValueLen;
|
||||
}
|
||||
if ((presentationFormatDescriptorValueLen > 0) && (presentationFormatDescriptorValuePtr != NULL)) {
|
||||
ASSERT_TRUE( sizeof(ble_gatts_char_pf_t) == sizeof(GattCharacteristic::PresentationFormat_t), ERROR_INVALID_PARAM );
|
||||
ASSERT_TRUE( presentationFormatDescriptorValueLen == sizeof(GattCharacteristic::PresentationFormat_t), ERROR_INVALID_PARAM );
|
||||
char_md.p_char_pf = const_cast<ble_gatts_char_pf_t *>(reinterpret_cast<const ble_gatts_char_pf_t *>(presentationFormatDescriptorValuePtr));
|
||||
}
|
||||
|
||||
/* Attribute declaration */
|
||||
ble_gatts_attr_md_t attr_md = {0};
|
||||
|
||||
attr_md.rd_auth = readAuthorization;
|
||||
attr_md.wr_auth = writeAuthorization;
|
||||
|
||||
attr_md.vloc = BLE_GATTS_VLOC_STACK;
|
||||
/* Always set variable size */
|
||||
attr_md.vlen = has_variable_len;
|
||||
|
||||
if (char_props.read || char_props.notify || char_props.indicate) {
|
||||
switch (requiredSecurity) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.read_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.read_perm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if (char_props.write || char_props.write_wo_resp) {
|
||||
switch (requiredSecurity) {
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.write_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.write_perm);
|
||||
break;
|
||||
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
|
||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.write_perm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
ble_gatts_attr_t attr_char_value = {0};
|
||||
|
||||
attr_char_value.p_uuid = p_uuid;
|
||||
attr_char_value.p_attr_md = &attr_md;
|
||||
attr_char_value.init_len = length;
|
||||
attr_char_value.max_len = max_length;
|
||||
attr_char_value.p_value = p_data;
|
||||
|
||||
ASSERT_STATUS ( sd_ble_gatts_characteristic_add(service_handle,
|
||||
&char_md,
|
||||
&attr_char_value,
|
||||
p_char_handle));
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Adds a new descriptor to the custom service, assigning
|
||||
value, a UUID add-on value, etc.
|
||||
|
||||
@param[in] char_handle
|
||||
@param[in] p_uuid The 16-bit value to add to the base UUID
|
||||
for this descriptor (normally >1
|
||||
since 1 is typically used by the primary
|
||||
service).
|
||||
@param[in] max_length The maximum length of this descriptor
|
||||
@param[in] has_variable_len Whether the characteristic data has
|
||||
variable length.
|
||||
|
||||
@returns
|
||||
@retval ERROR_NONE Everything executed normally
|
||||
*/
|
||||
/**************************************************************************/
|
||||
error_t custom_add_in_descriptor(uint16_t char_handle,
|
||||
ble_uuid_t *p_uuid,
|
||||
uint8_t *p_data,
|
||||
uint16_t length,
|
||||
uint16_t max_length,
|
||||
bool has_variable_len,
|
||||
uint16_t *p_desc_handle)
|
||||
{
|
||||
/* Descriptor metadata */
|
||||
ble_gatts_attr_md_t desc_md = {0};
|
||||
|
||||
desc_md.vloc = BLE_GATTS_VLOC_STACK;
|
||||
/* Always set variable size */
|
||||
desc_md.vlen = has_variable_len;
|
||||
|
||||
/* Make it readable and writable */
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.read_perm);
|
||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.write_perm);
|
||||
|
||||
ble_gatts_attr_t attr_desc = {0};
|
||||
|
||||
attr_desc.p_uuid = p_uuid;
|
||||
attr_desc.p_attr_md = &desc_md;
|
||||
attr_desc.init_len = length;
|
||||
attr_desc.max_len = max_length;
|
||||
attr_desc.p_value = p_data;
|
||||
|
||||
ASSERT_STATUS ( sd_ble_gatts_descriptor_add(char_handle,
|
||||
&attr_desc,
|
||||
p_desc_handle));
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef _CUSTOM_HELPER_H_
|
||||
#define _CUSTOM_HELPER_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "headers/nrf_ble.h"
|
||||
#include "ble/UUID.h"
|
||||
#include "ble/GattCharacteristic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Reset the table of 128bits uuids.
|
||||
* This table is used to keep track of vendors uuids added to the softdevice.
|
||||
* It is important to reset it before disabling the softdevice otherwise the
|
||||
* next time the softdevice will be enabled, this table will not be synchronmized
|
||||
* with the softdevice table.
|
||||
*/
|
||||
void custom_reset_128bits_uuid_table();
|
||||
uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base);
|
||||
error_t custom_decode_uuid(uint8_t const *const p_uuid_base,
|
||||
ble_uuid_t *p_uuid);
|
||||
ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid);
|
||||
|
||||
error_t custom_add_in_characteristic(uint16_t service_handle,
|
||||
ble_uuid_t *p_uuid,
|
||||
uint8_t properties,
|
||||
SecurityManager::SecurityMode_t requiredSecurity,
|
||||
uint8_t *p_data,
|
||||
uint16_t length,
|
||||
uint16_t max_length,
|
||||
bool has_variable_len,
|
||||
const uint8_t *userDescriptionDescriptorValuePtr,
|
||||
uint16_t userDescriptionDescriptorValueLen,
|
||||
const uint8_t *presentationFormatDescriptorValuePtr,
|
||||
uint16_t presentationFormatDescriptorValueLen,
|
||||
bool readAuthorization,
|
||||
bool writeAuthorization,
|
||||
ble_gatts_char_handles_t *p_char_handle);
|
||||
|
||||
error_t custom_add_in_descriptor(uint16_t char_handle,
|
||||
ble_uuid_t *p_uuid,
|
||||
uint8_t *p_data,
|
||||
uint16_t length,
|
||||
uint16_t max_length,
|
||||
bool has_variable_len,
|
||||
uint16_t *p_desc_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ifndef _CUSTOM_HELPER_H_
|
|
@ -0,0 +1,103 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file ansi_esc_code.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, hathach (tinyusb.org)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This file is part of the tinyusb stack.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \file
|
||||
* \brief TBD
|
||||
*
|
||||
* \note TBD
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ANSI_ESC_CODE_H_
|
||||
#define _ANSI_ESC_CODE_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CSI_CODE(seq) "\33[" seq
|
||||
#define CSI_SGR(x) CSI_CODE(#x) "m"
|
||||
|
||||
//------------- Cursor movement -------------//
|
||||
#define ANSI_CURSOR_UP(n) CSI_CODE(#n "A")
|
||||
#define ANSI_CURSOR_DOWN(n) CSI_CODE(#n "B")
|
||||
#define ANSI_CURSOR_FORWARD(n) CSI_CODE(#n "C")
|
||||
#define ANSI_CURSOR_BACKWARD(n) CSI_CODE(#n "D")
|
||||
#define ANSI_CURSOR_LINE_DOWN(n) CSI_CODE(#n "E")
|
||||
#define ANSI_CURSOR_LINE_UP(n) CSI_CODE(#n "F")
|
||||
#define ANSI_CURSOR_POSITION(n, m) CSI_CODE(#n ";" #m "H")
|
||||
|
||||
#define ANSI_ERASE_SCREEN(n) CSI_CODE(#n "J")
|
||||
#define ANSI_ERASE_LINE(n) CSI_CODE(#n "K")
|
||||
|
||||
/** text color */
|
||||
#define ANSI_TEXT_BLACK CSI_SGR(30)
|
||||
#define ANSI_TEXT_RED CSI_SGR(31)
|
||||
#define ANSI_TEXT_GREEN CSI_SGR(32)
|
||||
#define ANSI_TEXT_YELLOW CSI_SGR(33)
|
||||
#define ANSI_TEXT_BLUE CSI_SGR(34)
|
||||
#define ANSI_TEXT_MAGENTA CSI_SGR(35)
|
||||
#define ANSI_TEXT_CYAN CSI_SGR(36)
|
||||
#define ANSI_TEXT_WHITE CSI_SGR(37)
|
||||
#define ANSI_TEXT_DEFAULT CSI_SGR(39)
|
||||
|
||||
/** background color */
|
||||
#define ANSI_BG_BLACK CSI_SGR(40)
|
||||
#define ANSI_BG_RED CSI_SGR(41)
|
||||
#define ANSI_BG_GREEN CSI_SGR(42)
|
||||
#define ANSI_BG_YELLOW CSI_SGR(43)
|
||||
#define ANSI_BG_BLUE CSI_SGR(44)
|
||||
#define ANSI_BG_MAGENTA CSI_SGR(45)
|
||||
#define ANSI_BG_CYAN CSI_SGR(46)
|
||||
#define ANSI_BG_WHITE CSI_SGR(47)
|
||||
#define ANSI_BG_DEFAULT CSI_SGR(49)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_ANSI_ESC_CODE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,197 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file assertion.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \file
|
||||
* \brief TBD
|
||||
*
|
||||
* \note TBD
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ASSERTION_H_
|
||||
#define _ASSERTION_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
static inline void debugger_breakpoint(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void debugger_breakpoint(void)
|
||||
{
|
||||
#ifndef _TEST_
|
||||
__asm("BKPT #0\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Compile-time Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
|
||||
#define _ASSERT_COUNTER __COUNTER__
|
||||
#else
|
||||
#define _ASSERT_COUNTER __LINE__
|
||||
#endif
|
||||
|
||||
#define ASSERT_STATIC(const_expr, message) enum { XSTRING_CONCAT_(static_assert_, _ASSERT_COUNTER) = 1/(!!(const_expr)) }
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Assert Helper
|
||||
//--------------------------------------------------------------------+
|
||||
//#ifndef _TEST_
|
||||
// #define ASSERT_MESSAGE(format, ...) _PRINTF("Assert at %s: %s: %d: " format "\n", __BASE_FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
//#else
|
||||
// #define ASSERT_MESSAGE(format, ...) _PRINTF("%d:note: Assert " format "\n", __LINE__, __VA_ARGS__)
|
||||
//#endif
|
||||
|
||||
#if CFG_DEBUG == 3
|
||||
#define ASSERT_MESSAGE(format, ...) debugger_breakpoint()
|
||||
#elif CFG_DEBUG == 2
|
||||
#define ASSERT_MESSAGE(format, ...) printf("Assert at %s: %s: %d: " format "\n", __BASE_FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define ASSERT_MESSAGE(format, ...)
|
||||
#endif
|
||||
|
||||
#define ASSERT_ERROR_HANDLER(x, para) \
|
||||
return (x)
|
||||
|
||||
#define ASSERT_DEFINE_WITH_HANDLER(error_handler, handler_para, setup_statement, condition, error, format, ...) \
|
||||
do{\
|
||||
setup_statement;\
|
||||
if (!(condition)) {\
|
||||
ASSERT_MESSAGE(format, __VA_ARGS__);\
|
||||
error_handler(error, handler_para);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define ASSERT_DEFINE(...) ASSERT_DEFINE_WITH_HANDLER(ASSERT_ERROR_HANDLER, NULL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// error_t Status Assert TODO use ASSERT_DEFINE
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_STATUS_MESSAGE(sts, message) \
|
||||
ASSERT_DEFINE(error_t status = (error_t)(sts),\
|
||||
ERROR_NONE == status, status, "%s: %s", ErrorStr[status], message)
|
||||
|
||||
#define ASSERT_STATUS(sts) \
|
||||
ASSERT_DEFINE(error_t status = (error_t)(sts),\
|
||||
ERROR_NONE == status, status, "error = %d", status)
|
||||
|
||||
#define ASSERT_STATUS_RET_VOID(sts) \
|
||||
ASSERT_DEFINE(error_t status = (error_t)(sts),\
|
||||
ERROR_NONE == status, (void) 0, "error = %d", status)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Logical Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_TRUE(condition , error) ASSERT_DEFINE( , (condition), error, "%s", "evaluated to false")
|
||||
#define ASSERT_FALSE(condition , error) ASSERT_DEFINE( ,!(condition), error, "%s", "evaluated to true")
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Pointer Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_PTR(...) ASSERT_PTR_NOT_NULL(__VA_ARGS__)
|
||||
#define ASSERT_PTR_NOT_NULL(pointer, error) ASSERT_DEFINE( , NULL != (pointer), error, "%s", "pointer is NULL")
|
||||
#define ASSERT_PTR_NULL(pointer, error) ASSERT_DEFINE( , NULL == (pointer), error, "%s", "pointer is not NULL")
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Integral Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_XXX_EQUAL(type_format, expected, actual, error) \
|
||||
ASSERT_DEFINE(\
|
||||
uint32_t exp = (expected); uint32_t act = (actual),\
|
||||
exp==act,\
|
||||
error,\
|
||||
"expected " type_format ", actual " type_format, exp, act)
|
||||
|
||||
#define ASSERT_XXX_WITHIN(type_format, lower, upper, actual, error) \
|
||||
ASSERT_DEFINE(\
|
||||
uint32_t low = (lower); uint32_t up = (upper); uint32_t act = (actual),\
|
||||
(low <= act) && (act <= up),\
|
||||
error,\
|
||||
"expected within " type_format " - " type_format ", actual " type_format, low, up, act)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Integer Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_INT(...) ASSERT_INT_EQUAL(__VA_ARGS__)
|
||||
#define ASSERT_INT_EQUAL(...) ASSERT_XXX_EQUAL("%d", __VA_ARGS__)
|
||||
#define ASSERT_INT_WITHIN(...) ASSERT_XXX_WITHIN("%d", __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Hex Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define ASSERT_HEX(...) ASSERT_HEX_EQUAL(__VA_ARGS__)
|
||||
#define ASSERT_HEX_EQUAL(...) ASSERT_XXX_EQUAL("0x%x", __VA_ARGS__)
|
||||
#define ASSERT_HEX_WITHIN(...) ASSERT_XXX_WITHIN("0x%x", __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Bin Assert
|
||||
//--------------------------------------------------------------------+
|
||||
#define BIN8_PRINTF_PATTERN "%d%d%d%d%d%d%d%d"
|
||||
#define BIN8_PRINTF_CONVERT(byte) \
|
||||
((byte) & 0x80 ? 1 : 0), \
|
||||
((byte) & 0x40 ? 1 : 0), \
|
||||
((byte) & 0x20 ? 1 : 0), \
|
||||
((byte) & 0x10 ? 1 : 0), \
|
||||
((byte) & 0x08 ? 1 : 0), \
|
||||
((byte) & 0x04 ? 1 : 0), \
|
||||
((byte) & 0x02 ? 1 : 0), \
|
||||
((byte) & 0x01 ? 1 : 0)
|
||||
|
||||
#define ASSERT_BIN8(...) ASSERT_BIN8_EQUAL(__VA_ARGS__)
|
||||
#define ASSERT_BIN8_EQUAL(expected, actual, error)\
|
||||
ASSERT_DEFINE(\
|
||||
uint8_t exp = (expected); uint8_t act = (actual),\
|
||||
exp==act,\
|
||||
error,\
|
||||
"expected " BIN8_PRINTF_PATTERN ", actual " BIN8_PRINTF_PATTERN, BIN8_PRINTF_CONVERT(exp), BIN8_PRINTF_CONVERT(act) )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASSERTION_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,96 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file binary.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _BINARY_H_
|
||||
#define _BINARY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// n-th Bit
|
||||
#define BIT(n) (1 << (n))
|
||||
|
||||
/// set n-th bit of x to 1
|
||||
#define BIT_SET(x, n) ( (x) | BIT(n) )
|
||||
|
||||
/// clear n-th bit of x
|
||||
#define BIT_CLR(x, n) ( (x) & (~BIT(n)) )
|
||||
|
||||
/// test n-th bit of x
|
||||
#define BIT_TEST(x, n) ( (x) & BIT(n) )
|
||||
|
||||
#if defined(__GNUC__) && !defined(__CC_ARM) // keil does not support binary format
|
||||
|
||||
#define BIN8(x) ((uint8_t) (0b##x))
|
||||
#define BIN16(b1, b2) ((uint16_t) (0b##b1##b2))
|
||||
#define BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4))
|
||||
|
||||
#else
|
||||
|
||||
// internal macro of B8, B16, B32
|
||||
#define _B8__(x) (((x&0x0000000FUL)?1:0) \
|
||||
+((x&0x000000F0UL)?2:0) \
|
||||
+((x&0x00000F00UL)?4:0) \
|
||||
+((x&0x0000F000UL)?8:0) \
|
||||
+((x&0x000F0000UL)?16:0) \
|
||||
+((x&0x00F00000UL)?32:0) \
|
||||
+((x&0x0F000000UL)?64:0) \
|
||||
+((x&0xF0000000UL)?128:0))
|
||||
|
||||
#define BIN8(d) ((uint8_t) _B8__(0x##d##UL))
|
||||
#define BIN16(dmsb,dlsb) (((uint16_t)BIN8(dmsb)<<8) + BIN8(dlsb))
|
||||
#define BIN32(dmsb,db2,db3,dlsb) \
|
||||
(((uint32_t)BIN8(dmsb)<<24) \
|
||||
+ ((uint32_t)BIN8(db2)<<16) \
|
||||
+ ((uint32_t)BIN8(db3)<<8) \
|
||||
+ BIN8(dlsb))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BINARY_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,151 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file ble_error.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \file
|
||||
* \brief Error Header
|
||||
*
|
||||
* \note TBD
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common
|
||||
* \defgroup Group_Error Error Codes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _BLE_ERROR_H_
|
||||
#define _BLE_ERROR_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/*=======================================================================
|
||||
NORDIC GLOBAL ERRORS 0x0000 .. 0x00FF
|
||||
-----------------------------------------------------------------------
|
||||
Errors mapped from nrf_error.h
|
||||
-----------------------------------------------------------------------*/
|
||||
ERROR_NONE = 0x0000 , ///< Successful command
|
||||
ERROR_SVC_HANDLER_MISSING = 0x0001 , ///< SVC handler is missing
|
||||
ERROR_SOFTDEVICE_NOT_ENABLED = 0x0002 , ///< SoftDevice has not been enabled
|
||||
ERROR_INTERNAL = 0x0003 , ///< Internal Error
|
||||
ERROR_NO_MEM = 0x0004 , ///< No Memory for operation
|
||||
ERROR_NOT_FOUND = 0x0005 , ///< Not found
|
||||
ERROR_NOT_SUPPORTED = 0x0006 , ///< Not supported
|
||||
ERROR_INVALID_PARAM = 0x0007 , ///< Invalid Parameter
|
||||
ERROR_INVALID_STATE = 0x0008 , ///< Invalid state, operation disallowed in this state
|
||||
ERROR_INVALID_LENGTH = 0x0009 , ///< Invalid Length
|
||||
ERROR_INVALID_FLAGS = 0x000A , ///< Invalid Flags
|
||||
ERROR_INVALID_DATA = 0x000B , ///< Invalid Data
|
||||
ERROR_DATA_SIZE = 0x000C , ///< Data size exceeds limit
|
||||
ERROR_TIMEOUT = 0x000D , ///< Operation timed out
|
||||
ERROR_NULL = 0x000E , ///< Null Pointer
|
||||
ERROR_FORBIDDEN = 0x000F , ///< Forbidden Operation
|
||||
ERROR_INVALID_ADDR = 0x0010 , ///< Bad Memory Address
|
||||
ERROR_BUSY = 0x0011 , ///< Busy
|
||||
/*=======================================================================*/
|
||||
|
||||
ERROR_INVALIDPARAMETER = 0x0100 , /**< An invalid parameter value was provided */
|
||||
ERROR_I2C_XFER_FAILED = 0x0101 , /**< an failed attempt to make I2C transfer */
|
||||
|
||||
/*=======================================================================
|
||||
SIMPLE BINARY PROTOCOL ERRORS 0x0120 .. 0x013F
|
||||
-----------------------------------------------------------------------
|
||||
Errors relating to the simple binary protocol (/src//protocol)
|
||||
-----------------------------------------------------------------------*/
|
||||
ERROR_PROT_INVALIDMSGTYPE = 0x121, /**< Unexpected msg type encountered */
|
||||
ERROR_PROT_INVALIDCOMMANDID = 0x122, /**< Unknown or out of range command ID */
|
||||
ERROR_PROT_INVALIDPAYLOAD = 0x123, /**< Message payload has a problem (invalid len, etc.) */
|
||||
/*=======================================================================*/
|
||||
|
||||
//------------- based on Nordic SDM nrf_error_sdm.h -------------//
|
||||
ERROR_SDM_LFCLK_SOURCE_UNKNOWN = 0x1000 , ///< Unknown lfclk source
|
||||
ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION = 0x1001 , ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts)
|
||||
ERROR_SDM_INCORRECT_CLENR0 = 0x1002 , ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing)
|
||||
|
||||
//------------- based on Nordic SOC nrf_error_soc.h -------------//
|
||||
/* Mutex Errors */
|
||||
ERROR_SOC_MUTEX_ALREADY_TAKEN = 0x2000 , ///< Mutex already taken
|
||||
|
||||
/* NVIC errors */
|
||||
ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE = 0x2001 , ///< NVIC interrupt not available
|
||||
ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED = 0x2002 , ///< NVIC interrupt priority not allowed
|
||||
ERROR_SOC_NVIC_SHOULD_NOT_RETURN = 0x2003 , ///< NVIC should not return
|
||||
|
||||
/* Power errors */
|
||||
ERROR_SOC_POWER_MODE_UNKNOWN = 0x2004 , ///< Power mode unknown
|
||||
ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN = 0x2005 , ///< Power POF threshold unknown
|
||||
ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN = 0x2006 , ///< Power off should not return
|
||||
|
||||
/* Rand errors */
|
||||
ERROR_SOC_RAND_NOT_ENOUGH_VALUES = 0x2007 , ///< RAND not enough values
|
||||
|
||||
/* PPI errors */
|
||||
ERROR_SOC_PPI_INVALID_CHANNEL = 0x2008 , ///< Invalid PPI Channel
|
||||
ERROR_SOC_PPI_INVALID_GROUP = 0x2009 , ///< Invalid PPI Group
|
||||
|
||||
//------------- based on Nordic STK (ble) ble_err.h -------------//
|
||||
ERROR_BLE_INVALID_CONN_HANDLE = 0x3001 , /**< Invalid connection handle. */
|
||||
ERROR_BLE_INVALID_ATTR_HANDLE = 0x3002 , /**< Invalid attribute handle. */
|
||||
ERROR_BLE_NO_TX_BUFFERS = 0x3003 , /**< Buffer capacity exceeded. */
|
||||
|
||||
// L2CAP
|
||||
ERROR_BLE_L2CAP_CID_IN_USE = 0x3100 , /**< CID already in use. */
|
||||
|
||||
// GAP
|
||||
ERROR_BLE_GAP_UUID_LIST_MISMATCH = 0x3200 , /**< UUID list does not contain an integral number of UUIDs. */
|
||||
ERROR_BLE_GAP_DISCOVERABLE_WITH_WHITELIST = 0x3201 , /**< Use of Whitelist not permitted with discoverable advertising. */
|
||||
ERROR_BLE_GAP_INVALID_BLE_ADDR = 0x3202 , /**< The upper two bits of the address do not correspond to the specified address type. */
|
||||
|
||||
// GATTC
|
||||
ERROR_BLE_GATTC_PROC_NOT_PERMITTED = 0x3300 ,
|
||||
|
||||
// GATTS
|
||||
ERROR_BLEGATTS_INVALID_ATTR_TYPE = 0x3400 , /**< Invalid attribute type. */
|
||||
ERROR_BLEGATTS_SYS_ATTR_MISSING = 0x3401 , /**< System Attributes missing. */
|
||||
|
||||
}error_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLE_ERROR_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,236 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file common.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \defgroup Group_Common Common Files
|
||||
* @{
|
||||
*
|
||||
* \defgroup Group_CommonH common.h
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDES
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
//------------- Standard Header -------------//
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//------------- General Header -------------//
|
||||
#include "projectconfig.h"
|
||||
#include "compiler.h"
|
||||
#include "assertion.h"
|
||||
#include "binary.h"
|
||||
#include "ble_error.h"
|
||||
|
||||
//------------- MCU header -------------//
|
||||
//#include "nrf.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TYPEDEFS
|
||||
//--------------------------------------------------------------------+
|
||||
typedef unsigned char byte_t;
|
||||
typedef float float32_t;
|
||||
typedef double float64_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACROS
|
||||
//--------------------------------------------------------------------+
|
||||
#define STRING_(x) #x // stringify without expand
|
||||
#define XSTRING_(x) STRING_(x) // expand then stringify
|
||||
#define STRING_CONCAT_(a, b) a##b // concat without expand
|
||||
#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) // expand then concat
|
||||
|
||||
#define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
|
||||
#define U16_LOW_U8(u16) ((uint8_t) ((u16) & 0x00ff))
|
||||
#define U16_TO_U8S_BE(u16) U16_HIGH_U8(u16), U16_LOW_U8(u16)
|
||||
#define U16_TO_U8S_LE(u16) U16_LOW_U8(u16), U16_HIGH_U8(u16)
|
||||
|
||||
#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
|
||||
#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
|
||||
#define U32_B3_U8(u32) ((uint8_t) (((u32) >> 8) & 0x000000ff))
|
||||
#define U32_B4_U8(u32) ((uint8_t) ((u32) & 0x000000ff)) // LSB
|
||||
|
||||
#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
|
||||
#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INLINE FUNCTION
|
||||
//--------------------------------------------------------------------+
|
||||
#define memclr_(buffer, size) memset(buffer, 0, size)
|
||||
|
||||
//------------- Conversion -------------//
|
||||
/// form an uint32_t from 4 x uint8_t
|
||||
static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
|
||||
{
|
||||
return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
|
||||
}
|
||||
|
||||
static inline uint8_t u16_high_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t u16_high_u8(uint16_t u16)
|
||||
{
|
||||
return (uint8_t) ((u16 >> 8) & 0x00ff);
|
||||
}
|
||||
|
||||
static inline uint8_t u16_low_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t u16_low_u8(uint16_t u16)
|
||||
{
|
||||
return (uint8_t) (u16 & 0x00ff);
|
||||
}
|
||||
|
||||
//------------- Min -------------//
|
||||
static inline uint8_t min8_of(uint8_t x, uint8_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint8_t min8_of(uint8_t x, uint8_t y)
|
||||
{
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
static inline uint16_t min16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint16_t min16_of(uint16_t x, uint16_t y)
|
||||
{
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
static inline uint32_t min32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t min32_of(uint32_t x, uint32_t y)
|
||||
{
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
//------------- Max -------------//
|
||||
static inline uint32_t max32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t max32_of(uint32_t x, uint32_t y)
|
||||
{
|
||||
return (x > y) ? x : y;
|
||||
}
|
||||
|
||||
//------------- Align -------------//
|
||||
static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t align32 (uint32_t value)
|
||||
{
|
||||
return (value & 0xFFFFFFE0UL);
|
||||
}
|
||||
|
||||
static inline uint32_t align16 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t align16 (uint32_t value)
|
||||
{
|
||||
return (value & 0xFFFFFFF0UL);
|
||||
}
|
||||
|
||||
static inline uint32_t align_n (uint32_t alignment, uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t align_n (uint32_t alignment, uint32_t value)
|
||||
{
|
||||
return value & (~(alignment-1));
|
||||
}
|
||||
|
||||
static inline uint32_t align4k (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t align4k (uint32_t value)
|
||||
{
|
||||
return (value & 0xFFFFF000UL);
|
||||
}
|
||||
|
||||
static inline uint32_t offset4k(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint32_t offset4k(uint32_t value)
|
||||
{
|
||||
return (value & 0xFFFUL);
|
||||
}
|
||||
|
||||
//------------- Mathematics -------------//
|
||||
/// inclusive range checking
|
||||
static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper)
|
||||
{
|
||||
return (lower <= value) && (value <= upper);
|
||||
}
|
||||
|
||||
/// exclusive range checking
|
||||
static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper)
|
||||
{
|
||||
return (lower < value) && (value < upper);
|
||||
}
|
||||
|
||||
static inline uint8_t log2_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint8_t log2_of(uint32_t value)
|
||||
{
|
||||
uint8_t result = 0; // log2 of a value is its MSB's position
|
||||
|
||||
while (value >>= 1)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// return the number of set bits in value
|
||||
static inline uint8_t cardinality_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||
static inline uint8_t cardinality_of(uint32_t value)
|
||||
{
|
||||
// Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only
|
||||
// the high bit set, then it will only go once through the loop
|
||||
// Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie)
|
||||
// mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method
|
||||
// "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and
|
||||
// published in 1964 in a book edited by Beckenbach.)"
|
||||
uint8_t count;
|
||||
for (count = 0; value; count++)
|
||||
{
|
||||
value &= value - 1; // clear the least significant bit set
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMMON_H_ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,160 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file compiler.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2013, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
/** \file
|
||||
* \brief GCC Header
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Compiler
|
||||
* \defgroup Group_GCC GNU GCC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _COMPILER_GCC_H_
|
||||
#define _COMPILER_GCC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
//#ifndef __GNUC__
|
||||
// #define ATTR_ALWAYS_INLINE
|
||||
// #define ATTR_CONST
|
||||
//#else
|
||||
|
||||
#ifdef _TEST_
|
||||
#define ATTR_ALWAYS_INLINE
|
||||
#define STATIC_
|
||||
#define INLINE_
|
||||
#else
|
||||
#define STATIC_ static
|
||||
#define INLINE_ inline
|
||||
|
||||
#if CFG_DEBUG == 3
|
||||
#define ATTR_ALWAYS_INLINE // no inline for debug = 3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#define ALIGN_OF(x) __alignof__(x)
|
||||
|
||||
/// Normally, the compiler places the objects it generates in sections like data or bss & function in text. Sometimes, however, you need additional sections, or you need certain particular variables to appear in special sections, for example to map to special hardware. The section attribute specifies that a variable (or function) lives in a particular section
|
||||
#define ATTR_SECTION(section) __attribute__ ((#section))
|
||||
|
||||
/// If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, an error that includes message is diagnosed. This is useful for compile-time checking
|
||||
#define ATTR_ERROR(Message) __attribute__ ((error(Message)))
|
||||
|
||||
/// If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, a warning that includes message is diagnosed. This is useful for compile-time checking
|
||||
#define ATTR_WARNING(Message) __attribute__ ((warning(Message)))
|
||||
|
||||
/**
|
||||
* \defgroup Group_VariableAttr Variable Attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// This attribute specifies a minimum alignment for the variable or structure field, measured in bytes
|
||||
#define ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
|
||||
|
||||
/// The packed attribute specifies that a variable or structure field should have the smallest possible alignment—one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute
|
||||
#define ATTR_PACKED __attribute__ ((packed))
|
||||
|
||||
#define ATTR_PREPACKED
|
||||
|
||||
#define ATTR_PACKED_STRUCT(x) x __attribute__ ((packed))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \defgroup Group_FuncAttr Function Attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef ATTR_ALWAYS_INLINE
|
||||
/// Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level is specified
|
||||
#define ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
|
||||
#endif
|
||||
|
||||
/// The nonnull attribute specifies that some function parameters should be non-null pointers. f the compiler determines that a null pointer is passed in an argument slot marked as non-null, and the -Wnonnull option is enabled, a warning is issued. All pointer arguments are marked as non-null
|
||||
#define ATTR_NON_NULL __attribute__ ((nonull))
|
||||
|
||||
/// Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute pure
|
||||
#define ATTR_PURE __attribute__ ((pure))
|
||||
|
||||
/// Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the pure attribute below, since function is not allowed to read global memory.
|
||||
/// Note that a function that has pointer arguments and examines the data pointed to must not be declared const. Likewise, a function that calls a non-const function usually must not be const. It does not make sense for a const function to return void
|
||||
#define ATTR_CONST __attribute__ ((const))
|
||||
|
||||
/// The deprecated attribute results in a warning if the function is used anywhere in the source file. This is useful when identifying functions that are expected to be removed in a future version of a program. The warning also includes the location of the declaration of the deprecated function, to enable users to easily find further information about why the function is deprecated, or what they should do instead. Note that the warnings only occurs for uses
|
||||
#define ATTR_DEPRECATED __attribute__ ((deprecated))
|
||||
|
||||
/// Same as the deprecated attribute with optional message in the warning
|
||||
#define ATTR_DEPRECATED_MESS(mess) __attribute__ ((deprecated(mess)))
|
||||
|
||||
/// The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code
|
||||
#define ATTR_WEAK __attribute__ ((weak))
|
||||
|
||||
/// The alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified
|
||||
#define ATTR_ALIAS(func) __attribute__ ((alias(#func)))
|
||||
|
||||
/// The weakref attribute marks a declaration as a weak reference. It is equivalent with weak + alias attribute, but require function is static
|
||||
#define ATTR_WEAKREF(func) __attribute__ ((weakref(#func)))
|
||||
|
||||
/// The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug
|
||||
#define ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
|
||||
|
||||
/// This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly.
|
||||
#define ATTR_USED __attribute__ ((used))
|
||||
|
||||
/// This attribute, attached to a function, means that the function is meant to be possibly unused. GCC does not produce a warning for this function.
|
||||
#define ATTR_UNUSED __attribute__ ((unused))
|
||||
|
||||
#elif defined (__ICCARM__) //IAR
|
||||
#define ATTR_ALWAYS_INLINE // IAR dosn't provide such a syntax extension in function's prototypes.
|
||||
#define ATTR_CONST // IAR dosn't provide such a syntax extension in function's prototypes.
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMPILER_GCC_H_ */
|
||||
|
||||
/// @}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,257 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 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 BLE_NORDIC_PAL_GATT_CLIENT_H_
|
||||
#define BLE_NORDIC_PAL_GATT_CLIENT_H_
|
||||
|
||||
#include "ble/pal/PalGattClient.h"
|
||||
#include "ble/blecommon.h"
|
||||
#include "ble/UUID.h"
|
||||
|
||||
#include "headers/nrf_ble.h"
|
||||
#include "headers/ble_gatt.h"
|
||||
#include "headers/ble_types.h"
|
||||
#include "btle.h"
|
||||
|
||||
namespace ble {
|
||||
namespace pal {
|
||||
namespace vendor {
|
||||
namespace nordic {
|
||||
|
||||
/**
|
||||
* Implementation of pal::GattClient for the Nordic stack.
|
||||
*/
|
||||
class nRF5XGattClient : public ble::pal::GattClient {
|
||||
|
||||
public:
|
||||
nRF5XGattClient();
|
||||
|
||||
virtual ~nRF5XGattClient();
|
||||
|
||||
/**
|
||||
* see pal::GattClient::initialize .
|
||||
*/
|
||||
virtual ble_error_t initialize();
|
||||
|
||||
/**
|
||||
* see pal::GattClient::terminate .
|
||||
*/
|
||||
virtual ble_error_t terminate();
|
||||
|
||||
/**
|
||||
* see pal::GattClient::exchange_mtu .
|
||||
*/
|
||||
virtual ble_error_t exchange_mtu(connection_handle_t connection);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::get_mtu_size .
|
||||
*/
|
||||
virtual ble_error_t get_mtu_size(
|
||||
connection_handle_t connection_handle, uint16_t& mtu_size
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::discover_primary_service .
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service(
|
||||
connection_handle_t connection,
|
||||
attribute_handle_t discovery_range_begining
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::discover_primary_service_by_service_uuid .
|
||||
*/
|
||||
virtual ble_error_t discover_primary_service_by_service_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t discovery_range_beginning,
|
||||
const UUID& uuid
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::find_included_service .
|
||||
*/
|
||||
virtual ble_error_t find_included_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t service_range
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::discover_characteristics_of_a_service .
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_of_a_service(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t discovery_range
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::discover_characteristics_descriptors .
|
||||
*/
|
||||
virtual ble_error_t discover_characteristics_descriptors(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t descriptors_discovery_range
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::read_attribute_value .
|
||||
*/
|
||||
virtual ble_error_t read_attribute_value(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::read_using_characteristic_uuid .
|
||||
*/
|
||||
virtual ble_error_t read_using_characteristic_uuid(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_range_t read_range,
|
||||
const UUID& uuid
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::read_attribute_blob .
|
||||
*/
|
||||
virtual ble_error_t read_attribute_blob(
|
||||
connection_handle_t connection,
|
||||
attribute_handle_t attribute_handle,
|
||||
uint16_t offset
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::read_multiple_characteristic_values .
|
||||
*/
|
||||
virtual ble_error_t read_multiple_characteristic_values(
|
||||
connection_handle_t connection,
|
||||
const ArrayView<const attribute_handle_t>& characteristic_handles
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::write_without_response .
|
||||
*/
|
||||
virtual ble_error_t write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::signed_write_without_response .
|
||||
*/
|
||||
virtual ble_error_t signed_write_without_response(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::write_attribute .
|
||||
*/
|
||||
virtual ble_error_t write_attribute(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t attribute_handle,
|
||||
const ArrayView<const uint8_t>& value
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::queue_prepare_write .
|
||||
*/
|
||||
virtual ble_error_t queue_prepare_write(
|
||||
connection_handle_t connection_handle,
|
||||
attribute_handle_t characteristic_value_handle,
|
||||
const ArrayView<const uint8_t>& value,
|
||||
uint16_t offset
|
||||
);
|
||||
|
||||
/**
|
||||
* see pal::GattClient::execute_write_queue .
|
||||
*/
|
||||
virtual ble_error_t execute_write_queue(
|
||||
connection_handle_t connection_handle,
|
||||
bool execute
|
||||
);
|
||||
|
||||
// singleton of the ARM Cordio client
|
||||
static nRF5XGattClient& get_client();
|
||||
|
||||
/**
|
||||
* Function call from btle.cpp
|
||||
*
|
||||
* Do not call directly.
|
||||
*/
|
||||
static void handle_events(const ble_evt_t *p_ble_evt);
|
||||
|
||||
/**
|
||||
* Called by btle.cpp when a disconnection happens.
|
||||
*/
|
||||
static void handle_connection_termination(connection_handle_t connection);
|
||||
|
||||
private:
|
||||
struct GattProcedure;
|
||||
struct RegularGattProcedure;
|
||||
struct DiscoverPrimaryServiceProcedure;
|
||||
struct DiscoverPrimaryServiceByUUIDProcedure;
|
||||
struct FindIncludedServicesProcedure;
|
||||
struct DiscoverCharacteristicsProcedure;
|
||||
struct DiscoverDescriptorsProcedure;
|
||||
struct ReadAttributeProcedure;
|
||||
struct ReadUsingCharacteristicUUIDProcedure;
|
||||
struct ReadAttributeBlobProcedure;
|
||||
struct ReadMultipleCharacteristicsProcedure;
|
||||
struct WriteAttributeProcedure;
|
||||
struct QueuePrepareWriteProcedure;
|
||||
struct ExecuteWriteQueueProcedure;
|
||||
|
||||
template<typename ProcType, typename A0>
|
||||
ble_error_t launch_procedure(connection_handle_t connection, const A0& a0);
|
||||
|
||||
template<typename ProcType, typename A0, typename A1>
|
||||
ble_error_t launch_procedure(
|
||||
connection_handle_t connection, const A0& a0, const A1& a1
|
||||
);
|
||||
|
||||
template<typename ProcType, typename A0, typename A1, typename A2>
|
||||
ble_error_t launch_procedure(
|
||||
connection_handle_t connection,
|
||||
const A0& a0, const A1& a1, const A2& a2
|
||||
);
|
||||
|
||||
template<typename ProcType, typename A0, typename A1, typename A2, typename A3>
|
||||
ble_error_t launch_procedure(
|
||||
connection_handle_t connection,
|
||||
const A0& a0, const A1& a1, const A2& a2, const A3& a3
|
||||
);
|
||||
|
||||
GattProcedure* get_procedure(connection_handle_t) const;
|
||||
bool register_procedure(GattProcedure*);
|
||||
bool remove_procedure(GattProcedure*);
|
||||
|
||||
void handle_procedure_event(const ble_evt_t &evt);
|
||||
void handle_hvx_event(const ble_evt_t &evt);
|
||||
void handle_timeout_event(const ble_evt_t &evt);
|
||||
|
||||
static const size_t max_procedures_count =
|
||||
CENTRAL_LINK_COUNT + PERIPHERAL_LINK_COUNT;
|
||||
|
||||
// Note: Ideally we would have used an array of variant here
|
||||
GattProcedure* _procedures[max_procedures_count];
|
||||
};
|
||||
|
||||
} // nordic
|
||||
} // vendor
|
||||
} // pal
|
||||
} // ble
|
||||
|
||||
#endif /* BLE_NORDIC_PAL_GATT_CLIENT_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,285 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef __NRF5x_GAP_H__
|
||||
#define __NRF5x_GAP_H__
|
||||
|
||||
#ifdef YOTTA_CFG_MBED_OS
|
||||
#include "mbed-drivers/mbed.h"
|
||||
#else
|
||||
#include "mbed.h"
|
||||
#endif
|
||||
#ifndef YOTTA_CFG_WHITELIST_MAX_SIZE
|
||||
#define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
|
||||
#elif YOTTA_CFG_WHITELIST_MAX_SIZE > BLE_GAP_WHITELIST_ADDR_MAX_COUNT
|
||||
#undef YOTTA_CFG_WHITELIST_MAX_SIZE
|
||||
#define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
|
||||
#endif
|
||||
#ifndef YOTTA_CFG_IRK_TABLE_MAX_SIZE
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT
|
||||
#else
|
||||
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
|
||||
#endif
|
||||
#elif YOTTA_CFG_IRK_TABLE_MAX_SIZE > BLE_GAP_WHITELIST_IRK_MAX_COUNT
|
||||
#undef YOTTA_CFG_IRK_TABLE_MAX_SIZE
|
||||
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
|
||||
#endif
|
||||
#include "ble/blecommon.h"
|
||||
#include "headers/nrf_ble.h"
|
||||
#include "ble/GapAdvertisingParams.h"
|
||||
#include "ble/GapAdvertisingData.h"
|
||||
#include "ble/Gap.h"
|
||||
#include "ble/GapScanningParams.h"
|
||||
|
||||
#include "nrf_soc.h"
|
||||
|
||||
extern "C" {
|
||||
#include "ble_radio_notification.h"
|
||||
#include "app_util_platform.h"
|
||||
}
|
||||
|
||||
#include "btle_security.h"
|
||||
|
||||
void radioNotificationStaticCallback(bool param);
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
class nRF5xGap : public Gap
|
||||
{
|
||||
public:
|
||||
/* Functions that must be implemented from Gap */
|
||||
virtual ble_error_t setAddress(AddressType_t type, const Address_t address);
|
||||
virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address);
|
||||
virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
|
||||
|
||||
virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);}
|
||||
virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {
|
||||
#if (NRF_SD_BLE_API_VERSION >= 5) // In SD v5+, non connectable advertising interval is the same as connectable advertising interval
|
||||
// The Mbed infrastructure expects 100ms+ - so for now return that
|
||||
// return getMinAdvertisingInterval();
|
||||
// FIXME infrastructure
|
||||
return GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON;
|
||||
#else
|
||||
return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);
|
||||
#endif
|
||||
}
|
||||
virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MAX);}
|
||||
|
||||
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
|
||||
virtual ble_error_t stopAdvertising(void);
|
||||
virtual ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
|
||||
virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
|
||||
virtual ble_error_t disconnect(DisconnectionReason_t reason);
|
||||
|
||||
virtual ble_error_t setDeviceName(const uint8_t *deviceName);
|
||||
virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
|
||||
virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
|
||||
virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
|
||||
|
||||
virtual ble_error_t setTxPower(int8_t txPower);
|
||||
virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP);
|
||||
|
||||
void setConnectionHandle(uint16_t con_handle);
|
||||
uint16_t getConnectionHandle(void);
|
||||
|
||||
virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
|
||||
virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
|
||||
virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
|
||||
|
||||
virtual ble_error_t reset(void);
|
||||
|
||||
/*
|
||||
* The following functions are part of the whitelisting experimental API.
|
||||
* Therefore, this functionality can change in the near future.
|
||||
*/
|
||||
virtual uint8_t getMaxWhitelistSize(void) const;
|
||||
virtual ble_error_t getWhitelist(Gap::Whitelist_t &whitelistOut) const;
|
||||
virtual ble_error_t setWhitelist(const Gap::Whitelist_t &whitelistIn);
|
||||
|
||||
virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
|
||||
virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
|
||||
virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode);
|
||||
virtual Gap::AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
|
||||
virtual Gap::ScanningPolicyMode_t getScanningPolicyMode(void) const;
|
||||
virtual Gap::InitiatorPolicyMode_t getInitiatorPolicyMode(void) const;
|
||||
|
||||
virtual ble_error_t initRadioNotification(void) {
|
||||
if (ble_radio_notification_init(APP_IRQ_PRIORITY_HIGH /*MID*/, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
/* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */
|
||||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
|
||||
virtual ble_error_t stopScan(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*
|
||||
* Whitelisting API related structures and helper functions.
|
||||
*/
|
||||
|
||||
/* Policy modes set by the user. By default these are set to ignore the whitelist */
|
||||
Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
|
||||
Gap::ScanningPolicyMode_t scanningPolicyMode;
|
||||
|
||||
/* Internal representation of a whitelist */
|
||||
uint8_t whitelistAddressesSize;
|
||||
ble_gap_addr_t whitelistAddresses[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/*
|
||||
* An internal function used to populate the ble_gap_whitelist_t that will be used by
|
||||
* the SoftDevice for filtering requests. This function is needed because for the BLE
|
||||
* API the whitelist is just a collection of keys, but for the stack it also includes
|
||||
* the IRK table.
|
||||
*/
|
||||
ble_error_t generateStackWhitelist(ble_gap_whitelist_t &whitelist);
|
||||
#endif
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
/* internal type for passing a whitelist and a identities list. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gap_addr_t addrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
uint32_t addrs_cnt;
|
||||
|
||||
ble_gap_id_key_t identities[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
uint32_t identities_cnt;
|
||||
} GapWhiteAndIdentityList_t;
|
||||
|
||||
/* Function for preparing setting of the whitelist feature and the identity-resolving feature (privacy).*/
|
||||
ble_error_t getStackWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
|
||||
|
||||
/* Function for applying setting of the whitelist feature and identity-resolving feature (privacy).*/
|
||||
ble_error_t applyWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
|
||||
|
||||
/* Function for introducing whitelist feature and the identity-resolving feature setting into SoftDevice.
|
||||
*
|
||||
* This function incorporates getStackWhiteIdentityList and applyWhiteIdentityList together. */
|
||||
ble_error_t updateWhiteAndIdentityListInStack(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
|
||||
Timeout radioNotificationTimeout;
|
||||
|
||||
/*
|
||||
* A helper function to post radio notification callbacks with low interrupt priority.
|
||||
*/
|
||||
void postRadioNotificationCallback(void) {
|
||||
#ifdef YOTTA_CFG_MBED_OS
|
||||
/*
|
||||
* In mbed OS, all user-facing BLE events (interrupts) are posted to the
|
||||
* MINAR scheduler to be executed as callbacks in thread mode. MINAR guards
|
||||
* its critical sections from interrupts by acquiring CriticalSectionLock,
|
||||
* which results in a call to sd_nvic_critical_region_enter(). Thus, it is
|
||||
* safe to invoke MINAR APIs from interrupt context as long as those
|
||||
* interrupts are blocked by sd_nvic_critical_region_enter().
|
||||
*
|
||||
* Radio notifications are a special case for the above. The Radio
|
||||
* Notification IRQ is handled at a very high priority--higher than the
|
||||
* level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification
|
||||
* events can preempt MINAR's critical sections. Using MINAR APIs (such as
|
||||
* posting an event) directly in processRadioNotification() may result in a
|
||||
* race condition ending in a hard-fault.
|
||||
*
|
||||
* The solution is to *not* call MINAR APIs directly from the Radio
|
||||
* Notification handling; i.e. to do the bulk of RadioNotification
|
||||
* processing at a reduced priority which respects MINAR's critical
|
||||
* sections. Unfortunately, on a cortex-M0, there is no clean way to demote
|
||||
* priority for the currently executing interrupt--we wouldn't want to
|
||||
* demote the radio notification handling anyway because it is sensitive to
|
||||
* timing, and the system expects to finish this handling very quickly. The
|
||||
* workaround is to employ a Timeout to trigger
|
||||
* postRadioNotificationCallback() after a very short delay (~0 us) and post
|
||||
* the MINAR callback that context.
|
||||
*
|
||||
* !!!WARNING!!! Radio notifications are very time critical events. The
|
||||
* current solution is expected to work under the assumption that
|
||||
* postRadioNotificationCalback() will be executed BEFORE the next radio
|
||||
* notification event is generated.
|
||||
*/
|
||||
minar::Scheduler::postCallback(
|
||||
mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam)
|
||||
);
|
||||
#else
|
||||
/*
|
||||
* In mbed classic, all user-facing BLE events execute callbacks in interrupt
|
||||
* mode. Radio Notifications are a special case because its IRQ is handled at
|
||||
* a very high priority. Thus Radio Notification events can preempt other
|
||||
* operations that require interaction with the SoftDevice such as advertising
|
||||
* payload updates and changing the Gap state. Therefore, executing a Radio
|
||||
* Notification callback directly from processRadioNotification() may result
|
||||
* in a race condition ending in a hard-fault.
|
||||
*
|
||||
* The solution is to *not* execute the Radio Notification callback directly
|
||||
* from the Radio Notification handling; i.e. to do the bulk of the
|
||||
* Radio Notification processing at a reduced priority. Unfortunately, on a
|
||||
* cortex-M0, there is no clean way to demote priority for the currently
|
||||
* executing interrupt--we wouldn't want to demote the radio notification
|
||||
* handling anyway because it is sensitive to timing, and the system expects
|
||||
* to finish this handling very quickly. The workaround is to employ a Timeout
|
||||
* to trigger postRadioNotificationCallback() after a very short delay (~0 us)
|
||||
* and execute the callback in that context.
|
||||
*
|
||||
* !!!WARNING!!! Radio notifications are very time critical events. The
|
||||
* current solution is expected to work under the assumption that
|
||||
* postRadioNotificationCalback() will be executed BEFORE the next radio
|
||||
* notification event is generated.
|
||||
*/
|
||||
radioNotificationCallback.call(radioNotificationCallbackParam);
|
||||
#endif /* #ifdef YOTTA_CFG_MBED_OS */
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to process radio-notification events; to be called internally.
|
||||
* @param param [description]
|
||||
*/
|
||||
void processRadioNotificationEvent(bool param) {
|
||||
radioNotificationCallbackParam = param;
|
||||
radioNotificationTimeout.attach_us(mbed::callback(this, &nRF5xGap::postRadioNotificationCallback), 0);
|
||||
}
|
||||
friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
|
||||
|
||||
private:
|
||||
uint16_t m_connectionHandle;
|
||||
|
||||
/*
|
||||
* Allow instantiation from nRF5xn when required.
|
||||
*/
|
||||
friend class nRF5xn;
|
||||
|
||||
nRF5xGap() :
|
||||
advertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST),
|
||||
scanningPolicyMode(Gap::SCAN_POLICY_IGNORE_WHITELIST),
|
||||
whitelistAddressesSize(0) {
|
||||
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
nRF5xGap(nRF5xGap const &);
|
||||
void operator=(nRF5xGap const &);
|
||||
};
|
||||
|
||||
#endif // ifndef __NRF5x_GAP_H__
|
|
@ -0,0 +1,847 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#include "nRF5xGattServer.h"
|
||||
#ifdef YOTTA_CFG_MBED_OS
|
||||
#include "mbed-drivers/mbed.h"
|
||||
#else
|
||||
#include "mbed.h"
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
#include "btle/custom/custom_helper.h"
|
||||
|
||||
#include "nRF5xn.h"
|
||||
|
||||
namespace {
|
||||
|
||||
static const ble_gatts_rw_authorize_reply_params_t write_auth_queue_full_reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const ble_gatts_rw_authorize_reply_params_t write_auth_invalid_offset_reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_OFFSET
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const ble_gatts_rw_authorize_reply_params_t write_auth_succes_reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = BLE_GATT_STATUS_SUCCESS,
|
||||
.update = 0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const ble_gatts_rw_authorize_reply_params_t write_auth_invalid_reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ble_error_t set_attribute_value(
|
||||
Gap::Handle_t connectionHandle,
|
||||
GattAttribute::Handle_t attributeHandle,
|
||||
ble_gatts_value_t *value
|
||||
) {
|
||||
uint32_t err = sd_ble_gatts_value_set(connectionHandle, attributeHandle, value);
|
||||
switch(err) {
|
||||
case NRF_SUCCESS:
|
||||
return BLE_ERROR_NONE;
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case NRF_ERROR_INVALID_PARAM:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case NRF_ERROR_NOT_FOUND:
|
||||
case NRF_ERROR_DATA_SIZE:
|
||||
case BLE_ERROR_INVALID_CONN_HANDLE:
|
||||
case BLE_ERROR_GATTS_INVALID_ATTR_TYPE:
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
case NRF_ERROR_FORBIDDEN:
|
||||
return BLE_ERROR_OPERATION_NOT_PERMITTED;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Adds a new service to the GATT table on the peripheral
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
|
||||
@section EXAMPLE
|
||||
|
||||
@code
|
||||
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGattServer::addService(GattService &service)
|
||||
{
|
||||
/* ToDo: Make sure this service UUID doesn't already exist (?) */
|
||||
/* ToDo: Basic validation */
|
||||
|
||||
/* Add the service to the nRF51 */
|
||||
ble_uuid_t nordicUUID;
|
||||
nordicUUID = custom_convert_to_nordic_uuid(service.getUUID());
|
||||
|
||||
uint16_t serviceHandle;
|
||||
ASSERT_TRUE( ERROR_NONE ==
|
||||
sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
|
||||
&nordicUUID,
|
||||
&serviceHandle),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE );
|
||||
service.setHandle(serviceHandle);
|
||||
|
||||
/* Add characteristics to the service */
|
||||
for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
|
||||
if (characteristicCount >= BLE_TOTAL_CHARACTERISTICS) {
|
||||
return BLE_ERROR_NO_MEM;
|
||||
}
|
||||
GattCharacteristic *p_char = service.getCharacteristic(i);
|
||||
GattAttribute *p_description_descriptor = NULL;
|
||||
GattAttribute *p_presentation_format_descriptor = NULL;
|
||||
|
||||
/* Skip any incompletely defined, read-only characteristics. */
|
||||
if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
|
||||
(p_char->getValueAttribute().getLength() == 0) &&
|
||||
(p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
|
||||
|
||||
/* The user-description and presentation-format descriptors are special cases
|
||||
* that need to be handled at the time of adding each characteristic. The
|
||||
* following block is meant to discover their presence. */
|
||||
const uint8_t *userDescriptionDescriptorValuePtr = NULL;
|
||||
uint16_t userDescriptionDescriptorValueLen = 0;
|
||||
const uint8_t *presentationFormatDescriptorValuePtr = NULL;
|
||||
uint16_t presentationFormatDescriptorValueLen = 0;
|
||||
for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
|
||||
GattAttribute *p_desc = p_char->getDescriptor(j);
|
||||
if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
|
||||
p_description_descriptor = p_desc;
|
||||
userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
|
||||
userDescriptionDescriptorValueLen = p_desc->getLength();
|
||||
}
|
||||
if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT) {
|
||||
p_presentation_format_descriptor = p_desc;
|
||||
presentationFormatDescriptorValuePtr = p_desc->getValuePtr();
|
||||
presentationFormatDescriptorValueLen = p_desc->getLength();
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_TRUE ( ERROR_NONE ==
|
||||
custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
|
||||
&nordicUUID,
|
||||
p_char->getProperties(),
|
||||
p_char->getRequiredSecurity(),
|
||||
p_char->getValueAttribute().getValuePtr(),
|
||||
p_char->getValueAttribute().getLength(),
|
||||
p_char->getValueAttribute().getMaxLength(),
|
||||
p_char->getValueAttribute().hasVariableLength(),
|
||||
userDescriptionDescriptorValuePtr,
|
||||
userDescriptionDescriptorValueLen,
|
||||
presentationFormatDescriptorValuePtr,
|
||||
presentationFormatDescriptorValueLen,
|
||||
p_char->isReadAuthorizationEnabled(),
|
||||
p_char->isWriteAuthorizationEnabled(),
|
||||
&nrfCharacteristicHandles[characteristicCount]),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE );
|
||||
|
||||
/* Update the characteristic handle */
|
||||
p_characteristics[characteristicCount] = p_char;
|
||||
p_char->getValueAttribute().setHandle(nrfCharacteristicHandles[characteristicCount].value_handle);
|
||||
if (p_description_descriptor) {
|
||||
p_description_descriptor->setHandle(
|
||||
nrfCharacteristicHandles[characteristicCount].user_desc_handle
|
||||
);
|
||||
}
|
||||
if (p_presentation_format_descriptor) {
|
||||
// The handle is not available from the SoftDevice
|
||||
p_presentation_format_descriptor->setHandle(GattAttribute::INVALID_HANDLE);
|
||||
}
|
||||
characteristicCount++;
|
||||
|
||||
/* Add optional descriptors if any */
|
||||
for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
|
||||
if (descriptorCount >= BLE_TOTAL_DESCRIPTORS) {
|
||||
return BLE_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
GattAttribute *p_desc = p_char->getDescriptor(j);
|
||||
/* skip the user-description or presentation-format descriptor here;
|
||||
* they have already been handled when adding the characteristic (above). */
|
||||
if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC
|
||||
|| p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
|
||||
|
||||
ASSERT_TRUE(ERROR_NONE ==
|
||||
custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
|
||||
&nordicUUID,
|
||||
p_desc->getValuePtr(),
|
||||
p_desc->getLength(),
|
||||
p_desc->getMaxLength(),
|
||||
p_desc->hasVariableLength(),
|
||||
&nrfDescriptorHandles[descriptorCount]),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE);
|
||||
|
||||
p_descriptors[descriptorCount] = p_desc;
|
||||
p_desc->setHandle(nrfDescriptorHandles[descriptorCount]);
|
||||
descriptorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
serviceCount++;
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads the value of a characteristic, based on the service
|
||||
and characteristic index fields
|
||||
|
||||
@param[in] attributeHandle
|
||||
The handle of the GattCharacteristic to read from
|
||||
@param[in] buffer
|
||||
Buffer to hold the the characteristic's value
|
||||
(raw byte array in LSB format)
|
||||
@param[in/out] len
|
||||
input: Length in bytes to be read.
|
||||
output: Total length of attribute value upon successful return.
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
|
||||
{
|
||||
return read(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, lengthP);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
|
||||
{
|
||||
ble_gatts_value_t value = {
|
||||
.len = *lengthP,
|
||||
.offset = 0,
|
||||
.p_value = buffer,
|
||||
};
|
||||
|
||||
ASSERT_TRUE( ERROR_NONE ==
|
||||
sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE);
|
||||
*lengthP = value.len;
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Updates the value of a characteristic, based on the service
|
||||
and characteristic index fields
|
||||
|
||||
@param[in] charHandle
|
||||
The handle of the GattCharacteristic to write to
|
||||
@param[in] buffer
|
||||
Data to use when updating the characteristic's value
|
||||
(raw byte array in LSB format)
|
||||
@param[in] len
|
||||
The number of bytes in buffer
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
|
||||
{
|
||||
return write(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, len, localOnly);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
|
||||
{
|
||||
ble_error_t returnValue = BLE_ERROR_NONE;
|
||||
|
||||
ble_gatts_value_t value = {
|
||||
.len = len,
|
||||
.offset = 0,
|
||||
.p_value = const_cast<uint8_t *>(buffer),
|
||||
};
|
||||
|
||||
if (localOnly) {
|
||||
/* Only update locally regardless of notify/indicate */
|
||||
ASSERT_INT( ERROR_NONE,
|
||||
sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE );
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
int characteristicIndex = resolveValueHandleToCharIndex(attributeHandle);
|
||||
if ((characteristicIndex != -1) &&
|
||||
(p_characteristics[characteristicIndex]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
|
||||
/* HVX update for the characteristic value */
|
||||
ble_gatts_hvx_params_t hvx_params;
|
||||
|
||||
hvx_params.handle = attributeHandle;
|
||||
hvx_params.type =
|
||||
(p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
|
||||
hvx_params.offset = 0;
|
||||
hvx_params.p_data = const_cast<uint8_t *>(buffer);
|
||||
hvx_params.p_len = &len;
|
||||
|
||||
if (connectionHandle == BLE_CONN_HANDLE_INVALID) { /* use the default connection handle if the caller hasn't specified a valid connectionHandle. */
|
||||
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
|
||||
connectionHandle = gap.getConnectionHandle();
|
||||
}
|
||||
|
||||
bool updatesEnabled = false;
|
||||
if (connectionHandle != BLE_CONN_HANDLE_INVALID) {
|
||||
ble_error_t err = areUpdatesEnabled(connectionHandle, attributeHandle, &updatesEnabled);
|
||||
|
||||
// FIXME: The softdevice allocates and populates CCCD when the client
|
||||
// interract with them. Checking for updates may return an out of
|
||||
// range error in such case.
|
||||
if(err && err != BLE_ERROR_PARAM_OUT_OF_RANGE) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (updatesEnabled) {
|
||||
error_t error = (error_t) sd_ble_gatts_hvx(connectionHandle, &hvx_params);
|
||||
if (error != ERROR_NONE) {
|
||||
switch (error) {
|
||||
case ERROR_BLE_NO_TX_BUFFERS: /* Notifications consume application buffers. The return value can be used for resending notifications. */
|
||||
case ERROR_BUSY:
|
||||
returnValue = BLE_STACK_BUSY;
|
||||
break;
|
||||
|
||||
case ERROR_INVALID_STATE:
|
||||
case ERROR_BLEGATTS_SYS_ATTR_MISSING:
|
||||
returnValue = BLE_ERROR_INVALID_STATE;
|
||||
break;
|
||||
|
||||
default :
|
||||
ASSERT_INT( ERROR_NONE,
|
||||
sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
|
||||
BLE_ERROR_PARAM_OUT_OF_RANGE );
|
||||
|
||||
/* Notifications consume application buffers. The return value can
|
||||
* be used for resending notifications. */
|
||||
returnValue = BLE_STACK_BUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
returnValue = set_attribute_value(connectionHandle, attributeHandle, &value);
|
||||
}
|
||||
} else {
|
||||
returnValue = set_attribute_value(connectionHandle, attributeHandle, &value);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP)
|
||||
{
|
||||
/* Forward the call with the default connection handle. */
|
||||
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
|
||||
return areUpdatesEnabled(gap.getConnectionHandle(), characteristic, enabledP);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
|
||||
{
|
||||
return areUpdatesEnabled(connectionHandle, characteristic.getValueHandle(), enabledP);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, bool *enabledP)
|
||||
{
|
||||
int characteristicIndex = resolveValueHandleToCharIndex(attributeHandle);
|
||||
if (characteristicIndex == -1) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Read the cccd value from the GATT server. */
|
||||
GattAttribute::Handle_t cccdHandle = nrfCharacteristicHandles[characteristicIndex].cccd_handle;
|
||||
uint16_t cccdValue;
|
||||
uint16_t length = sizeof(cccdValue);
|
||||
ble_error_t rc = read(connectionHandle, cccdHandle, reinterpret_cast<uint8_t *>(&cccdValue), &length);
|
||||
if (rc != BLE_ERROR_NONE) {
|
||||
return rc;
|
||||
}
|
||||
if (length != sizeof(cccdValue)) {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Check for NOTFICATION or INDICATION in CCCD. */
|
||||
if ((cccdValue & BLE_GATT_HVX_NOTIFICATION) || (cccdValue & BLE_GATT_HVX_INDICATION)) {
|
||||
*enabledP = true;
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Clear nRF5xGattServer's state.
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGattServer::reset(void)
|
||||
{
|
||||
/* Clear all state that is from the parent, including private members */
|
||||
if (GattServer::reset() != BLE_ERROR_NONE) {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Clear derived class members */
|
||||
memset(p_characteristics, 0, sizeof(p_characteristics));
|
||||
memset(p_descriptors, 0, sizeof(p_descriptors));
|
||||
memset(nrfCharacteristicHandles, 0, sizeof(ble_gatts_char_handles_t));
|
||||
memset(nrfDescriptorHandles, 0, sizeof(nrfDescriptorHandles));
|
||||
descriptorCount = 0;
|
||||
|
||||
releaseAllWriteRequests();
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Callback handler for events getting pushed up from the SD
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void nRF5xGattServer::hwCallback(const ble_evt_t *p_ble_evt)
|
||||
{
|
||||
GattAttribute::Handle_t handle_value;
|
||||
GattServerEvents::gattEvent_t eventType;
|
||||
const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt;
|
||||
|
||||
switch (p_ble_evt->header.evt_id) {
|
||||
case BLE_GATTS_EVT_WRITE: {
|
||||
/* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
|
||||
|
||||
/* 1.) Handle CCCD changes */
|
||||
handle_value = gattsEventP->params.write.handle;
|
||||
int characteristicIndex = resolveCCCDHandleToCharIndex(handle_value);
|
||||
if ((characteristicIndex != -1) &&
|
||||
(p_characteristics[characteristicIndex]->getProperties() &
|
||||
(GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
|
||||
|
||||
uint16_t cccd_value = (gattsEventP->params.write.data[1] << 8) | gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
|
||||
|
||||
if (((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) ||
|
||||
((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
|
||||
eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
|
||||
} else {
|
||||
eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
|
||||
}
|
||||
|
||||
handleEvent(eventType, p_characteristics[characteristicIndex]->getValueHandle());
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2.) Changes to the characteristic value will be handled with other events below */
|
||||
eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GATTS_EVT_HVC:
|
||||
/* Indication confirmation received */
|
||||
eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
|
||||
handle_value = gattsEventP->params.hvc.handle;
|
||||
break;
|
||||
|
||||
#if NRF_SD_BLE_API_VERSION >= 4 // This event has been renamed in API V4+
|
||||
case BLE_GATTS_EVT_HVN_TX_COMPLETE: {
|
||||
handleDataSentEvent(p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
case BLE_EVT_TX_COMPLETE: {
|
||||
handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
||||
sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0, 0);
|
||||
return;
|
||||
|
||||
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
|
||||
switch (gattsEventP->params.authorize_request.type) {
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_READ:
|
||||
eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ;
|
||||
handle_value = gattsEventP->params.authorize_request.request.read.handle;
|
||||
break;
|
||||
case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
|
||||
eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ;
|
||||
handle_value = gattsEventP->params.authorize_request.request.write.handle;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_EVT_USER_MEM_REQUEST: {
|
||||
uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle;
|
||||
|
||||
// allocate a new long request for this connection
|
||||
// NOTE: we don't care about the result at this stage,
|
||||
// it is not possible to cancel the operation anyway.
|
||||
// If the request was not allocated then it will gracefully failled
|
||||
// at subsequent stages.
|
||||
allocateLongWriteRequest(conn_handle);
|
||||
sd_ble_user_mem_reply(conn_handle, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
int characteristicIndex = resolveValueHandleToCharIndex(handle_value);
|
||||
if (characteristicIndex == -1) {
|
||||
// filter out the case were the request is a long one,
|
||||
// and there is no attribute handle provided
|
||||
uint8_t write_op = gattsEventP->params.authorize_request.request.write.op;
|
||||
if (eventType != GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ ||
|
||||
(write_op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW &&
|
||||
write_op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find index (charHandle) in the pool */
|
||||
switch (eventType) {
|
||||
case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
|
||||
GattWriteCallbackParams cbParams = {
|
||||
/* .connHandle = */ gattsEventP->conn_handle,
|
||||
/* .handle = */ handle_value,
|
||||
/* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.write.op),
|
||||
/* .offset = */ gattsEventP->params.write.offset,
|
||||
/* .len = */ gattsEventP->params.write.len,
|
||||
/* .data = */ gattsEventP->params.write.data
|
||||
};
|
||||
handleDataWrittenEvent(&cbParams);
|
||||
break;
|
||||
}
|
||||
case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: {
|
||||
uint16_t conn_handle = gattsEventP->conn_handle;
|
||||
const ble_gatts_evt_write_t& input_req = gattsEventP->params.authorize_request.request.write;
|
||||
const uint16_t max_size = getBiggestCharacteristicSize();
|
||||
|
||||
// this is a long write request, handle it here.
|
||||
switch (input_req.op) {
|
||||
case BLE_GATTS_OP_PREP_WRITE_REQ: {
|
||||
// verify that the request is not outside of the possible range
|
||||
if ((input_req.offset + input_req.len) > max_size) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_offset_reply);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// find the write request
|
||||
long_write_request_t* req = findLongWriteRequest(conn_handle);
|
||||
if (!req) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply);
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize the first request by setting the offset
|
||||
if (req->length == 0) {
|
||||
req->attr_handle = input_req.handle;
|
||||
req->offset = input_req.offset;
|
||||
} else {
|
||||
// it should be the subsequent write
|
||||
if ((req->offset + req->length) != input_req.offset) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_offset_reply);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// it is not allowed to write multiple characteristic with the same request
|
||||
if (input_req.handle != req->attr_handle) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// start the copy of what is in input
|
||||
memcpy(req->data + req->length, input_req.data, input_req.len);
|
||||
|
||||
// update the lenght of the data written
|
||||
req->length = req->length + input_req.len;
|
||||
|
||||
// success, signal it to the softdevice
|
||||
ble_gatts_rw_authorize_reply_params_t reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = BLE_GATT_STATUS_SUCCESS,
|
||||
.update = 1,
|
||||
.offset = input_req.offset,
|
||||
.len = input_req.len,
|
||||
.p_data = input_req.data
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &reply);
|
||||
} return;
|
||||
|
||||
case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL: {
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_succes_reply);
|
||||
} return;
|
||||
|
||||
case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: {
|
||||
long_write_request_t* req = findLongWriteRequest(conn_handle);
|
||||
if (!req) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply);
|
||||
return;
|
||||
}
|
||||
|
||||
GattWriteAuthCallbackParams cbParams = {
|
||||
.connHandle = conn_handle,
|
||||
.handle = req->attr_handle,
|
||||
.offset = req->offset,
|
||||
.len = req->length,
|
||||
.data = req->data,
|
||||
.authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member
|
||||
* set to AUTH_CALLBACK_REPLY_SUCCESS if the client
|
||||
* request is to proceed. */
|
||||
};
|
||||
uint16_t write_authorization = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams);
|
||||
|
||||
// the user code didn't provide the write authorization,
|
||||
// just leave here.
|
||||
if (write_authorization != AUTH_CALLBACK_REPLY_SUCCESS) {
|
||||
// report the status of the operation in any cases
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME can't use ::write here, this function doesn't take the offset into account ...
|
||||
ble_gatts_value_t value = {
|
||||
.len = req->length,
|
||||
.offset = req->offset,
|
||||
.p_value = req->data
|
||||
};
|
||||
uint32_t update_err = sd_ble_gatts_value_set(conn_handle, req->attr_handle, &value);
|
||||
if (update_err) {
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_succes_reply);
|
||||
|
||||
GattWriteCallbackParams writeParams = {
|
||||
/* .connHandle = */ conn_handle,
|
||||
/* .handle = */ req->attr_handle,
|
||||
/* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(input_req.op),
|
||||
/* .offset = */ req->offset,
|
||||
/* .len = */ req->length,
|
||||
/* .data = */ req->data,
|
||||
};
|
||||
handleDataWrittenEvent(&writeParams);
|
||||
releaseLongWriteRequest(conn_handle);
|
||||
} return;
|
||||
}
|
||||
|
||||
GattWriteAuthCallbackParams cbParams = {
|
||||
.connHandle = gattsEventP->conn_handle,
|
||||
.handle = handle_value,
|
||||
.offset = gattsEventP->params.authorize_request.request.write.offset,
|
||||
.len = gattsEventP->params.authorize_request.request.write.len,
|
||||
.data = gattsEventP->params.authorize_request.request.write.data,
|
||||
.authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member
|
||||
* set to AUTH_CALLBACK_REPLY_SUCCESS if the client
|
||||
* request is to proceed. */
|
||||
};
|
||||
|
||||
ble_gatts_rw_authorize_reply_params_t reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
|
||||
.params = {
|
||||
.write = {
|
||||
.gatt_status = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams),
|
||||
.update = 1,
|
||||
.offset = cbParams.offset,
|
||||
.len = cbParams.len,
|
||||
.p_data = cbParams.data
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
|
||||
{
|
||||
reply.params.write.update = 0;
|
||||
}
|
||||
|
||||
sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
|
||||
|
||||
/*
|
||||
* If write-authorization is enabled for a characteristic,
|
||||
* AUTHORIZATION_REQ event (if replied with true) is *not*
|
||||
* followed by another DATA_WRITTEN event; so we still need
|
||||
* to invoke handleDataWritten(), much the same as we would
|
||||
* have done if write-authorization had not been enabled.
|
||||
*/
|
||||
if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
|
||||
GattWriteCallbackParams cbParams = {
|
||||
/* .connHandle = */ gattsEventP->conn_handle,
|
||||
/* .handle = */ handle_value,
|
||||
/* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.authorize_request.request.write.op),
|
||||
/* .offset = */ gattsEventP->params.authorize_request.request.write.offset,
|
||||
/* .len = */ gattsEventP->params.authorize_request.request.write.len,
|
||||
/* .data = */ gattsEventP->params.authorize_request.request.write.data,
|
||||
};
|
||||
handleDataWrittenEvent(&cbParams);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: {
|
||||
GattReadAuthCallbackParams cbParams = {
|
||||
.connHandle = gattsEventP->conn_handle,
|
||||
.handle = handle_value,
|
||||
.offset = gattsEventP->params.authorize_request.request.read.offset,
|
||||
.len = 0,
|
||||
.data = NULL,
|
||||
.authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member
|
||||
* set to AUTH_CALLBACK_REPLY_SUCCESS if the client
|
||||
* request is to proceed. */
|
||||
};
|
||||
|
||||
ble_gatts_rw_authorize_reply_params_t reply = {
|
||||
.type = BLE_GATTS_AUTHORIZE_TYPE_READ,
|
||||
.params = {
|
||||
.read = {
|
||||
.gatt_status = p_characteristics[characteristicIndex]->authorizeRead(&cbParams)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) {
|
||||
if (cbParams.data != NULL) {
|
||||
reply.params.read.update = 1;
|
||||
reply.params.read.offset = cbParams.offset;
|
||||
reply.params.read.len = cbParams.len;
|
||||
reply.params.read.p_data = cbParams.data;
|
||||
}
|
||||
}
|
||||
|
||||
sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
handleEvent(eventType, handle_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nRF5xGattServer::getBiggestCharacteristicSize() const {
|
||||
uint16_t result = 0;
|
||||
for (size_t i = 0; i < characteristicCount; ++i) {
|
||||
uint16_t current_size = p_characteristics[i]->getValueAttribute().getMaxLength();
|
||||
if (current_size > result) {
|
||||
result = current_size;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nRF5xGattServer::long_write_request_t* nRF5xGattServer::allocateLongWriteRequest(uint16_t connection_handle) {
|
||||
for (size_t i = 0; i < TOTAL_CONCURRENT_LONG_WRITE_REQUESTS; ++i) {
|
||||
long_write_request_t& req = long_write_requests[i];
|
||||
if (req.data == NULL) {
|
||||
uint16_t block_size = getBiggestCharacteristicSize();
|
||||
req.data = static_cast<uint8_t*>(malloc(block_size));
|
||||
req.offset = 0;
|
||||
req.length = 0;
|
||||
req.conn_handle = connection_handle;
|
||||
return &req;
|
||||
}
|
||||
}
|
||||
// if nothing has been found then return null
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool nRF5xGattServer::releaseLongWriteRequest(uint16_t connection_handle) {
|
||||
long_write_request_t* req = findLongWriteRequest(connection_handle);
|
||||
if (!req) {
|
||||
return false;
|
||||
}
|
||||
|
||||
free(req->data);
|
||||
req->data = NULL;
|
||||
|
||||
// the other fields are not relevant, return now
|
||||
return true;
|
||||
}
|
||||
|
||||
nRF5xGattServer::long_write_request_t* nRF5xGattServer::findLongWriteRequest(uint16_t connection_handle) {
|
||||
for (size_t i = 0; i < TOTAL_CONCURRENT_LONG_WRITE_REQUESTS; ++i) {
|
||||
long_write_request_t& req = long_write_requests[i];
|
||||
if (req.data != NULL && req.conn_handle == connection_handle) {
|
||||
return &req;
|
||||
}
|
||||
}
|
||||
// if nothing has been found then return null
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nRF5xGattServer::releaseAllWriteRequests() {
|
||||
for (size_t i = 0; i < TOTAL_CONCURRENT_LONG_WRITE_REQUESTS; ++i) {
|
||||
long_write_request_t& req = long_write_requests[i];
|
||||
if (req.data != NULL) {
|
||||
free(req.data);
|
||||
req.data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef __NRF51822_GATT_SERVER_H__
|
||||
#define __NRF51822_GATT_SERVER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ble/blecommon.h"
|
||||
#include "headers/nrf_ble.h" /* nordic ble */
|
||||
#include "ble/Gap.h"
|
||||
#include "ble/GattServer.h"
|
||||
|
||||
class nRF5xGattServer : public GattServer
|
||||
{
|
||||
public:
|
||||
/* Functions that must be implemented from GattServer */
|
||||
virtual ble_error_t addService(GattService &);
|
||||
virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
|
||||
virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
|
||||
virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
|
||||
virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
|
||||
virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP);
|
||||
virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP);
|
||||
virtual ble_error_t reset(void);
|
||||
|
||||
/* nRF51 Functions */
|
||||
void eventCallback(void);
|
||||
void hwCallback(const ble_evt_t *p_ble_evt);
|
||||
|
||||
|
||||
private:
|
||||
const static unsigned BLE_TOTAL_CHARACTERISTICS = 20;
|
||||
const static unsigned BLE_TOTAL_DESCRIPTORS = 8;
|
||||
const static unsigned TOTAL_CONCURRENT_LONG_WRITE_REQUESTS = 3;
|
||||
|
||||
private:
|
||||
struct long_write_request_t {
|
||||
// the connection handle for a long write request
|
||||
uint16_t conn_handle;
|
||||
|
||||
// the attribute handle for the long write request
|
||||
// This implementation folow the bluetooth route
|
||||
// where a write request target a single characteristic
|
||||
// (see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] - 4.9.4)
|
||||
uint16_t attr_handle;
|
||||
|
||||
// offset of the transaction
|
||||
uint16_t offset;
|
||||
|
||||
// length of the data
|
||||
uint16_t length;
|
||||
|
||||
// current data
|
||||
uint8_t* data;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* resolve a value attribute to its owning characteristic.
|
||||
* @param valueHandle the value handle to be resolved.
|
||||
* @return characteristic index if a resolution is found, else -1.
|
||||
*/
|
||||
int resolveValueHandleToCharIndex(GattAttribute::Handle_t valueHandle) const {
|
||||
unsigned charIndex;
|
||||
for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
|
||||
if (nrfCharacteristicHandles[charIndex].value_handle == valueHandle) {
|
||||
return charIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* resolve a CCCD attribute handle to its owning characteristic.
|
||||
* @param cccdHandle the CCCD handle to be resolved.
|
||||
* @return characteristic index if a resolution is found, else -1.
|
||||
*/
|
||||
int resolveCCCDHandleToCharIndex(GattAttribute::Handle_t cccdHandle) const {
|
||||
unsigned charIndex;
|
||||
for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
|
||||
if (nrfCharacteristicHandles[charIndex].cccd_handle == cccdHandle) {
|
||||
return charIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the biggest size used by a characteristic in the server
|
||||
*/
|
||||
uint16_t getBiggestCharacteristicSize() const;
|
||||
|
||||
/**
|
||||
* Allocate a new write long request. return null if no requests are available.
|
||||
* @param connection_handle The connection handle to be associated with the request.
|
||||
* @return the allocated request or NULL if no requests are available.
|
||||
*/
|
||||
long_write_request_t* allocateLongWriteRequest(uint16_t connection_handle);
|
||||
|
||||
/**
|
||||
* Release a long write request and free a slot for subsequent write long requests.
|
||||
* @param connection_handle The connection handle associated with the request
|
||||
* @return true if the request where allocated and was release, false otherwise.
|
||||
*/
|
||||
bool releaseLongWriteRequest(uint16_t connection_handle);
|
||||
|
||||
/**
|
||||
* Find a long write request from a characteristic handle
|
||||
* @param connection_handle The connection handle associated with the request.
|
||||
* @return a pointer to the request if found otherwise NULL.
|
||||
*/
|
||||
long_write_request_t* findLongWriteRequest(uint16_t connection_handle);
|
||||
|
||||
/**
|
||||
* Release all pending write requests.
|
||||
*/
|
||||
void releaseAllWriteRequests();
|
||||
|
||||
/**
|
||||
* Query if updates of a characteristics are enabled for a given connection.
|
||||
*/
|
||||
ble_error_t areUpdatesEnabled(
|
||||
Gap::Handle_t connectionHandle,
|
||||
GattAttribute::Handle_t valueHandle,
|
||||
bool *enabledP
|
||||
);
|
||||
|
||||
private:
|
||||
GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
|
||||
ble_gatts_char_handles_t nrfCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
|
||||
GattAttribute *p_descriptors[BLE_TOTAL_DESCRIPTORS];
|
||||
uint8_t descriptorCount;
|
||||
uint16_t nrfDescriptorHandles[BLE_TOTAL_DESCRIPTORS];
|
||||
long_write_request_t long_write_requests[TOTAL_CONCURRENT_LONG_WRITE_REQUESTS];
|
||||
|
||||
/*
|
||||
* Allow instantiation from nRF5xn when required.
|
||||
*/
|
||||
friend class nRF5xn;
|
||||
|
||||
nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles(), long_write_requests() {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
private:
|
||||
nRF5xGattServer(const nRF5xGattServer &);
|
||||
const nRF5xGattServer& operator=(const nRF5xGattServer &);
|
||||
};
|
||||
|
||||
#endif // ifndef __NRF51822_GATT_SERVER_H__
|
|
@ -0,0 +1,194 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef __NRF51822_SECURITY_MANAGER_H__
|
||||
#define __NRF51822_SECURITY_MANAGER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "nRF5xGap.h"
|
||||
#include "ble/SecurityManager.h"
|
||||
#include "btle_security.h"
|
||||
|
||||
class nRF5xSecurityManager : public SecurityManager
|
||||
{
|
||||
public:
|
||||
/* Functions that must be implemented from SecurityManager */
|
||||
virtual ble_error_t init(bool enableBonding,
|
||||
bool requireMITM,
|
||||
SecurityIOCapabilities_t iocaps,
|
||||
const Passkey_t passkey) {
|
||||
return btle_initializeSecurity(enableBonding, requireMITM, iocaps, passkey);
|
||||
}
|
||||
|
||||
virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
|
||||
return btle_getLinkSecurity(connectionHandle, securityStatusP);
|
||||
}
|
||||
|
||||
virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) {
|
||||
return btle_setLinkSecurity(connectionHandle, securityMode);
|
||||
}
|
||||
|
||||
virtual ble_error_t purgeAllBondingState(void) {
|
||||
return btle_purgeAllBondingState();
|
||||
}
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @return
|
||||
* BLE_ERROR_NONE if successful.
|
||||
*/
|
||||
virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
|
||||
uint8_t i;
|
||||
|
||||
ble_gap_whitelist_t whitelistFromBondTable;
|
||||
ble_gap_addr_t *addressPtr[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
ble_gap_irk_t *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
/* Initialize the structure so that we get as many addreses as the whitelist can hold */
|
||||
whitelistFromBondTable.addr_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
|
||||
whitelistFromBondTable.pp_addrs = addressPtr;
|
||||
whitelistFromBondTable.irk_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
|
||||
whitelistFromBondTable.pp_irks = irkPtr;
|
||||
|
||||
ble_error_t error = createWhitelistFromBondTable(whitelistFromBondTable);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
addresses.size = 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Put all the addresses in the structure */
|
||||
for (i = 0; i < whitelistFromBondTable.addr_count; ++i) {
|
||||
if (i >= addresses.capacity) {
|
||||
/* Ran out of space in the output Gap::Whitelist_t */
|
||||
addresses.size = i;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
memcpy(&addresses.addresses[i], whitelistFromBondTable.pp_addrs[i], sizeof(BLEProtocol::Address_t));
|
||||
}
|
||||
|
||||
/* Update the current address count */
|
||||
addresses.size = i;
|
||||
|
||||
/* The assumption here is that the underlying implementation of
|
||||
* createWhitelistFromBondTable() will not return the private resolvable
|
||||
* addresses (which is the case in the SoftDevice). Rather it returns the
|
||||
* IRKs, so we need to generate the private resolvable address by ourselves.
|
||||
*/
|
||||
for (i = 0; i < whitelistFromBondTable.irk_count; ++i) {
|
||||
if (i + addresses.size >= addresses.capacity) {
|
||||
/* Ran out of space in the output Gap::Whitelist_t */
|
||||
addresses.size += i;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
btle_generateResolvableAddress(
|
||||
*whitelistFromBondTable.pp_irks[i],
|
||||
(ble_gap_addr_t &) addresses.addresses[i + addresses.size]
|
||||
);
|
||||
}
|
||||
|
||||
/* Update the current address count */
|
||||
addresses.size += i;
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
#else // -> NRF_SD_BLE_API_VERSION >= 3
|
||||
/**
|
||||
* @brief Returns a list of addresses from peers in the stacks bond table.
|
||||
*
|
||||
* @param[in/out] addresses
|
||||
* (on input) @ref Gap::Whitelist_t structure where at
|
||||
* most addresses.capacity addresses from bonded peers will
|
||||
* be stored.
|
||||
* (on output) A copy of the addresses from bonded peers.
|
||||
*
|
||||
* @retval BLE_ERROR_NONE if successful.
|
||||
* @retval BLE_ERROR_UNSPECIFIED Bond data could not be found in flash or is inconsistent.
|
||||
*/
|
||||
virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
|
||||
return btle_getAddressesFromBondTable(addresses);
|
||||
}
|
||||
#endif // #if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear nRF5xSecurityManager's state.
|
||||
*
|
||||
* @return
|
||||
* BLE_ERROR_NONE if successful.
|
||||
*/
|
||||
virtual ble_error_t reset(void)
|
||||
{
|
||||
if (SecurityManager::reset() != BLE_ERROR_NONE) {
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool hasInitialized(void) const {
|
||||
return btle_hasInitializedSecurity();
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
* Allow instantiation from nRF5xn when required.
|
||||
*/
|
||||
friend class nRF5xn;
|
||||
|
||||
nRF5xSecurityManager() {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
private:
|
||||
nRF5xSecurityManager(const nRF5xSecurityManager &);
|
||||
const nRF5xSecurityManager& operator=(const nRF5xSecurityManager &);
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/*
|
||||
* Expose an interface that allows us to query the SoftDevice bond table
|
||||
* and extract a whitelist.
|
||||
*/
|
||||
ble_error_t createWhitelistFromBondTable(ble_gap_whitelist_t &whitelistFromBondTable) const {
|
||||
return btle_createWhitelistFromBondTable(&whitelistFromBondTable);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Given a BLE address and a IRK this function check whether the address
|
||||
* can be generated from the IRK. To do so, this function uses the hash
|
||||
* function and algorithm described in the Bluetooth low Energy
|
||||
* Specification. Internally, Nordic SDK functions are used.
|
||||
*/
|
||||
bool matchAddressAndIrk(ble_gap_addr_t *address, ble_gap_irk_t *irk) const {
|
||||
return btle_matchAddressAndIrk(address, irk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give nRF5xGap access to createWhitelistFromBondTable() and
|
||||
* matchAddressAndIrk()
|
||||
*/
|
||||
friend class nRF5xGap;
|
||||
};
|
||||
|
||||
#endif // ifndef __NRF51822_SECURITY_MANAGER_H__
|
|
@ -0,0 +1,241 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifdef YOTTA_CFG_MBED_OS
|
||||
#include "mbed-drivers/mbed.h"
|
||||
#else
|
||||
#include "mbed.h"
|
||||
#endif
|
||||
#include "nRF5xn.h"
|
||||
#include "ble/blecommon.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#include "btle/btle.h"
|
||||
#include "btle/custom/custom_helper.h"
|
||||
#include "nrf_delay.h"
|
||||
|
||||
extern "C" {
|
||||
#include "nrf_sdh.h"
|
||||
}
|
||||
|
||||
#include "nRF5XPalGattClient.h"
|
||||
|
||||
/**
|
||||
* The singleton which represents the nRF51822 transport for the BLE.
|
||||
*/
|
||||
static nRF5xn& getDeviceInstance() {
|
||||
static nRF5xn deviceInstance;
|
||||
return deviceInstance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BLE-API requires an implementation of the following function in order to
|
||||
* obtain its transport handle.
|
||||
*/
|
||||
BLEInstanceBase *
|
||||
createBLEInstance(void)
|
||||
{
|
||||
return &nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
|
||||
}
|
||||
|
||||
nRF5xn& nRF5xn::Instance(BLE::InstanceID_t instanceId)
|
||||
{
|
||||
return getDeviceInstance();
|
||||
}
|
||||
|
||||
nRF5xn::nRF5xn(void) :
|
||||
initialized(false),
|
||||
instanceID(BLE::DEFAULT_INSTANCE),
|
||||
gapInstance(),
|
||||
gattServerInstance(NULL),
|
||||
gattClient(&(ble::pal::vendor::nordic::nRF5XGattClient::get_client())),
|
||||
securityManagerInstance(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
nRF5xn::~nRF5xn(void)
|
||||
{
|
||||
}
|
||||
|
||||
const char *nRF5xn::getVersion(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
return "INITIALIZATION_INCOMPLETE";
|
||||
}
|
||||
|
||||
static char versionString[32];
|
||||
static bool versionFetched = false;
|
||||
|
||||
if (!versionFetched) {
|
||||
ble_version_t version;
|
||||
if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
|
||||
switch (version.version_number) {
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 ver:%u fw:%04x", version.version_number, version.subversion_number);
|
||||
break;
|
||||
default:
|
||||
snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) ver:%u fw:%04x", version.version_number, version.subversion_number);
|
||||
break;
|
||||
}
|
||||
versionFetched = true;
|
||||
} else {
|
||||
strncpy(versionString, "unknown", sizeof(versionString));
|
||||
}
|
||||
}
|
||||
|
||||
return versionString;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialize the BLE stack.
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE if everything executed properly and
|
||||
BLE_ERROR_ALREADY_INITIALIZED if the stack has already
|
||||
been initialized (possibly through a call to nRF5xn::init()).
|
||||
BLE_ERROR_INTERNAL_STACK_FAILURE is returned if initialization
|
||||
of the internal stack (SoftDevice) failed.
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xn::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
|
||||
{
|
||||
if (initialized) {
|
||||
BLE::InitializationCompleteCallbackContext context = {
|
||||
BLE::Instance(instanceID),
|
||||
BLE_ERROR_ALREADY_INITIALIZED
|
||||
};
|
||||
callback.call(&context);
|
||||
return BLE_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
instanceID = instanceID;
|
||||
|
||||
/* ToDo: Clear memory contents, reset the SD, etc. */
|
||||
if (btle_init() != ERROR_NONE) {
|
||||
return BLE_ERROR_INTERNAL_STACK_FAILURE;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
BLE::InitializationCompleteCallbackContext context = {
|
||||
BLE::Instance(instanceID),
|
||||
BLE_ERROR_NONE
|
||||
};
|
||||
callback.call(&context);
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Purge the BLE stack of GATT and GAP state.
|
||||
|
||||
@returns ble_error_t
|
||||
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
|
||||
@note When using S110, GattClient::shutdown() will not be called
|
||||
since Gatt client features are not supported.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xn::shutdown(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown the SoftDevice first. This is because we need to disable all
|
||||
* interrupts. Otherwise if we clear the BLE API and glue code first there
|
||||
* will be many NULL references and no config information which could lead
|
||||
* to errors if the shutdown process is interrupted.
|
||||
*/
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
if (nrf_sdh_disable_request() != NRF_SUCCESS) {
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
#else
|
||||
if (softdevice_handler_sd_disable() != NRF_SUCCESS) {
|
||||
return BLE_STACK_BUSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shutdown the BLE API and nRF51 glue code */
|
||||
ble_error_t error;
|
||||
|
||||
if (gattServerInstance != NULL) {
|
||||
error = gattServerInstance->reset();
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (securityManagerInstance != NULL) {
|
||||
error = securityManagerInstance->reset();
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
/* S110 does not support BLE client features, nothing to reset. */
|
||||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
error = getGattClient().reset();
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Gap instance is always present */
|
||||
error = gapInstance.reset();
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
custom_reset_128bits_uuid_table();
|
||||
|
||||
initialized = false;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
nRF5xn::waitForEvent(void)
|
||||
{
|
||||
processEvents();
|
||||
sd_app_evt_wait();
|
||||
}
|
||||
|
||||
void nRF5xn::processEvents() {
|
||||
core_util_critical_section_enter();
|
||||
while (isEventsSignaled) {
|
||||
isEventsSignaled = false;
|
||||
core_util_critical_section_exit();
|
||||
#if NRF_SD_BLE_API_VERSION >= 5
|
||||
// We use the "polling" dispatch model
|
||||
// http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v14.2.0/group__nrf__sdh.html?cp=4_0_0_6_11_60_20#gab4d7be69304d4f5feefd1d440cc3e6c7
|
||||
// This will process any pending events from the Softdevice
|
||||
nrf_sdh_evts_poll();
|
||||
#else
|
||||
intern_softdevice_events_execute();
|
||||
#endif
|
||||
|
||||
core_util_critical_section_enter();
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef __NRF51822_H__
|
||||
#define __NRF51822_H__
|
||||
|
||||
#include "ble/BLE.h"
|
||||
#include "ble/blecommon.h"
|
||||
#include "ble/BLEInstanceBase.h"
|
||||
#include "ble/generic/GenericGattClient.h"
|
||||
|
||||
#include "nRF5xGap.h"
|
||||
#include "nRF5xGattServer.h"
|
||||
#include "nRF5xSecurityManager.h"
|
||||
|
||||
#include "btle.h"
|
||||
|
||||
class nRF5xn : public BLEInstanceBase
|
||||
{
|
||||
public:
|
||||
nRF5xn(void);
|
||||
virtual ~nRF5xn(void);
|
||||
|
||||
virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback);
|
||||
virtual bool hasInitialized(void) const {
|
||||
return initialized;
|
||||
}
|
||||
virtual ble_error_t shutdown(void);
|
||||
virtual const char *getVersion(void);
|
||||
|
||||
/**
|
||||
* Accessors to GAP. This function checks whether gapInstance points to an
|
||||
* object. If if does not, then the gapInstance is updated to
|
||||
* &_getInstance before returning.
|
||||
*
|
||||
* @return A reference to GattServer.
|
||||
*
|
||||
* @note Unlike the GattClient, GattServer and SecurityManager, Gap is
|
||||
* always needed in a BLE application. Therefore it is allocated
|
||||
* statically.
|
||||
*/
|
||||
virtual Gap &getGap() {
|
||||
return gapInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessors to GATT Server. This function checks whether a GattServer
|
||||
* object was previously instantiated. If such object does not exist, then
|
||||
* it is created before returning.
|
||||
*
|
||||
* @return A reference to GattServer.
|
||||
*/
|
||||
virtual GattServer &getGattServer() {
|
||||
if (gattServerInstance == NULL) {
|
||||
gattServerInstance = new nRF5xGattServer();
|
||||
}
|
||||
return *gattServerInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessors to GATT Client. This function checks whether a GattClient
|
||||
* object was previously instantiated. If such object does not exist, then
|
||||
* it is created before returning.
|
||||
*
|
||||
* @return A reference to GattClient.
|
||||
*/
|
||||
virtual GattClient &getGattClient() {
|
||||
return gattClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessors to Security Manager. This function checks whether a SecurityManager
|
||||
* object was previously instantiated. If such object does not exist, then
|
||||
* it is created before returning.
|
||||
*
|
||||
* @return A reference to GattServer.
|
||||
*/
|
||||
virtual nRF5xSecurityManager &getSecurityManager() {
|
||||
if (securityManagerInstance == NULL) {
|
||||
securityManagerInstance = new nRF5xSecurityManager();
|
||||
}
|
||||
return *securityManagerInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessors to GAP. This function checks whether gapInstance points to an
|
||||
* object. If if does not, then the gapInstance is updated to
|
||||
* &_getInstance before returning.
|
||||
*
|
||||
* @return A const reference to GattServer.
|
||||
*
|
||||
* @note Unlike the GattClient, GattServer and SecurityManager, Gap is
|
||||
* always needed in a BLE application. Therefore it is allocated
|
||||
* statically.
|
||||
*
|
||||
* @note The accessor is able to modify the object's state because the
|
||||
* internal pointer has been declared mutable.
|
||||
*/
|
||||
virtual const nRF5xGap &getGap() const {
|
||||
return gapInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessors to GATT Server. This function checks whether a GattServer
|
||||
* object was previously instantiated. If such object does not exist, then
|
||||
* it is created before returning.
|
||||
*
|
||||
* @return A const reference to GattServer.
|
||||
*
|
||||
* @note The accessor is able to modify the object's state because the
|
||||
* internal pointer has been declared mutable.
|
||||
*/
|
||||
virtual const nRF5xGattServer &getGattServer() const {
|
||||
if (gattServerInstance == NULL) {
|
||||
gattServerInstance = new nRF5xGattServer();
|
||||
}
|
||||
return *gattServerInstance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessors to Security Manager. This function checks whether a SecurityManager
|
||||
* object was previously instantiated. If such object does not exist, then
|
||||
* it is created before returning.
|
||||
*
|
||||
* @return A const reference to GattServer.
|
||||
*
|
||||
* @note The accessor is able to modify the object's state because the
|
||||
* internal pointer has been declared mutable.
|
||||
*/
|
||||
virtual const nRF5xSecurityManager &getSecurityManager() const {
|
||||
if (securityManagerInstance == NULL) {
|
||||
securityManagerInstance = new nRF5xSecurityManager();
|
||||
}
|
||||
return *securityManagerInstance;
|
||||
}
|
||||
|
||||
virtual void waitForEvent(void);
|
||||
|
||||
virtual void processEvents();
|
||||
|
||||
public:
|
||||
static nRF5xn& Instance(BLE::InstanceID_t instanceId);
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
BLE::InstanceID_t instanceID;
|
||||
|
||||
private:
|
||||
mutable nRF5xGap gapInstance; /**< Gap instance whose reference is returned from a call to
|
||||
* getGap(). Unlike the GattClient, GattServer and
|
||||
* SecurityManager, Gap is always needed in a BLE application. */
|
||||
|
||||
private:
|
||||
mutable nRF5xGattServer *gattServerInstance; /**< Pointer to the GattServer object instance.
|
||||
* If NULL, then GattServer has not been initialized.
|
||||
* The pointer has been declared as 'mutable' so that
|
||||
* it can be assigned inside a 'const' function. */
|
||||
ble::generic::GenericGattClient gattClient;
|
||||
|
||||
mutable nRF5xSecurityManager *securityManagerInstance; /**< Pointer to the SecurityManager object instance.
|
||||
* If NULL, then SecurityManager has not been initialized.
|
||||
* The pointer has been declared as 'mutable' so that
|
||||
* it can be assigned inside a 'const' function. */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,136 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#ifndef _PROJECTCONFIG_H_
|
||||
#define _PROJECTCONFIG_H_
|
||||
|
||||
#include "ble/GapAdvertisingData.h"
|
||||
|
||||
/*=========================================================================
|
||||
MCU & BOARD SELCTION
|
||||
|
||||
CFG_BOARD is one of the value defined in board.h
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_BOARD BOARD_PCA10001
|
||||
#define CFG_MCU_STRING "nRF51822"
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
CODE BASE VERSION SETTINGS
|
||||
|
||||
Please do not modify this version number. To set a version number
|
||||
for your project or firmware, change the values in your 'boards/'
|
||||
config file.
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_CODEBASE_VERSION_MAJOR 0
|
||||
#define CFG_CODEBASE_VERSION_MINOR 1
|
||||
#define CFG_CODEBASE_VERSION_REVISION 0
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
FIRMWARE VERSION SETTINGS
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_FIRMWARE_VERSION_MAJOR 0
|
||||
#define CFG_FIRMWARE_VERSION_MINOR 0
|
||||
#define CFG_FIRMWARE_VERSION_REVISION 0
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
DEBUG LEVEL
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_DEBUG Level 3: Full debug output, any failed assert
|
||||
will produce a breakpoint for the
|
||||
debugger
|
||||
Level 2: ATTR_ALWAYS_INLINE is null, ASSERT
|
||||
has text
|
||||
Level 1: ATTR_ALWAYS_INLINE is an attribute,
|
||||
ASSERT has no text
|
||||
Level 0: No debug information generated
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_DEBUG (1)
|
||||
|
||||
#if (CFG_DEBUG > 3) || (CFG_DEBUG < 0)
|
||||
#error "CFG_DEBUG must be a value between 0 (no debug) and 3"
|
||||
#endif
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
GENERAL NRF51 PERIPHERAL SETTINGS
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_SCHEDULER_ENABLE Set this to 'true' or 'false' depending on
|
||||
if you use the event scheduler or not
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_SCHEDULER_ENABLE false
|
||||
|
||||
/*------------------------------- GPIOTE ------------------------------*/
|
||||
#define CFG_GPIOTE_MAX_USERS 1 /**< Maximum number of users of the GPIOTE handler. */
|
||||
|
||||
/*-------------------------------- TIMER ------------------------------*/
|
||||
#define CFG_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. freq = (32768/(PRESCALER+1)) */
|
||||
#define CFG_TIMER_MAX_INSTANCE 1 /**< Maximum number of simultaneously created timers. */
|
||||
#define CFG_TIMER_OPERATION_QUEUE_SIZE 2 /**< Size of timer operation queues. */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
BTLE SETTINGS
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
#define CFG_BLE_TX_POWER_LEVEL 0 /**< in dBm (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
|
||||
|
||||
/*---------------------------- BOND MANAGER ---------------------------*/
|
||||
#define CFG_BLE_BOND_FLASH_PAGE_BOND (BLE_FLASH_PAGE_END-1) /**< Flash page used for bond manager bonding information.*/
|
||||
#define CFG_BLE_BOND_FLASH_PAGE_SYS_ATTR (BLE_FLASH_PAGE_END-3) /**< Flash page used for bond manager system attribute information. TODO check if we can use BLE_FLASH_PAGE_END-2*/
|
||||
#define CFG_BLE_BOND_DELETE_BUTTON_NUM 0 /**< Button to press to delete bond details during init */
|
||||
|
||||
/*------------------------------ SECURITY -----------------------------*/
|
||||
#define CFG_BLE_SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
|
||||
#define CFG_BLE_SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
|
||||
#define CFG_BLE_SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
|
||||
#define CFG_BLE_SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
|
||||
#define CFG_BLE_SEC_PARAM_MAX_KEY_SIZE 16
|
||||
|
||||
/*--------------------------------- GAP -------------------------------*/
|
||||
#define CFG_GAP_APPEARANCE GapAdvertisingData::GENERIC_TAG
|
||||
#define CFG_GAP_LOCAL_NAME "nRF5x"
|
||||
|
||||
#define CFG_GAP_CONNECTION_MIN_INTERVAL_MS 50 /**< Minimum acceptable connection interval */
|
||||
#define CFG_GAP_CONNECTION_MAX_INTERVAL_MS 500 /**< Maximum acceptable connection interval */
|
||||
#define CFG_GAP_CONNECTION_SUPERVISION_TIMEOUT_MS 4000 /**< Connection supervisory timeout */
|
||||
#define CFG_GAP_CONNECTION_SLAVE_LATENCY 0 /**< Slave Latency in number of connection events. */
|
||||
|
||||
#define CFG_GAP_ADV_INTERVAL_MS 25 /**< The advertising interval in miliseconds, should be multiply of 0.625 */
|
||||
#define CFG_GAP_ADV_TIMEOUT_S 180 /**< The advertising timeout in units of seconds. */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
VALIDATION
|
||||
-----------------------------------------------------------------------*/
|
||||
#if CFG_BLE_TX_POWER_LEVEL != -40 && CFG_BLE_TX_POWER_LEVEL != -20 && CFG_BLE_TX_POWER_LEVEL != -16 && CFG_BLE_TX_POWER_LEVEL != -12 && CFG_BLE_TX_POWER_LEVEL != -8 && CFG_BLE_TX_POWER_LEVEL != -4 && CFG_BLE_TX_POWER_LEVEL != 0 && CFG_BLE_TX_POWER_LEVEL != 4
|
||||
#error "CFG_BLE_TX_POWER_LEVEL must be -40, -20, -16, -12, -8, -4, 0 or 4"
|
||||
#endif
|
||||
/*=========================================================================*/
|
||||
|
||||
#endif /* _PROJECTCONFIG_H_ */
|
|
@ -0,0 +1,21 @@
|
|||
# Copyright 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.
|
||||
|
||||
message("suppressing warnings from ble-nrf51822")
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set_target_properties(ble-nrf51822
|
||||
PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function -Wno-missing-field-initializers"
|
||||
)
|
||||
endif()
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
# LF Clock configuration using mbed configuration system
|
||||
|
||||
In order to provide the configuration for a low frequency (LF) clock, add a description of the LF clock inside a mbed configuration JSON file.
|
||||
For example at application level the description might be added in a mbed_app.json file and on target level the description might be added in the hal/target.json file.
|
||||
LF clock source configuration is used for MCU startup initialization and the BLE SoftDevice LF clock configuration (if BLE libraries is used). Advanced configurations are used only for the BLE SoftDevice LF clock configuration.
|
||||
|
||||
|
||||
## Usage:
|
||||
|
||||
1. Clock source
|
||||
|
||||
Default clock source is XTAL oscillator. It is defined at the target level configuration as the target.lf_clock_src key.
|
||||
There are three options that can be configured as the clock source:
|
||||
- NRF_LF_SRC_XTAL
|
||||
- NRF_LF_SRC_RC
|
||||
- NRF_LF_SRC_SYNTH
|
||||
|
||||
In order to override this configuration use targed_override section in configuration file (e.g mbed_app.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"target.lf_clock_src": "NRF_LF_SRC_XTAL"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2a. Advanced configuration of the LFCLK RC oscillator:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"lf_clock_rc_calib_timer_interval": {
|
||||
"value": 16,
|
||||
"macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL"
|
||||
},
|
||||
"lf_clock_rc_calib_mode_config": {
|
||||
"value": 1,
|
||||
"macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
"lf_clock_rc_calib_timer_interval" - Calibration timer interval in 250 ms. It is equivalent to nrf_clock_lf_cfg_t::rc_ctiv.
|
||||
This item generates macro MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL.
|
||||
By default, such configuration is set to 16.
|
||||
|
||||
"lf_clock_rc_calib_mode_config" - This value configures how often the RC oscillator will be calibrated, in number of calibration intervals.
|
||||
It is equivalent to nrf_clock_lf_cfg_t::rc_temp_ctiv.
|
||||
For further information, see the documentation for the [API of a SoftDevice 13x version 2.0.0](http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v2.0.0/structnrf__clock__lf__cfg__t.html)
|
||||
This item generates macro MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG.
|
||||
By default, such configuration is set to 1.
|
||||
|
||||
2b. Advanced configuration of the LFCLK XTAL oscillator:
|
||||
|
||||
Accuracy of the clock source can be set. In order to do so macro MBED_CONF_NORDIC_LF_CLOCK_XTAL_ACCURACY should been provided (e.g. in mbed_app.json).
|
||||
By default such configuration is set to NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM.
|
||||
For further information, see the documentation for the [API of a SoftDevice 13x version 2.0.0](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v2.0.0%2Fgroup___n_r_f___s_d_m___d_e_f_i_n_e_s.html)
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"lf_clock_xtal_accuracy": {
|
||||
"value": "NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM",
|
||||
"macro_name": "MBED_CONF_NORDIC_LF_CLOCK_XTAL_ACCURACY"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
2c. Advance configuration of the LFCLK Synthesized from HFCLK:
|
||||
|
||||
Accuracy of the clock source can be set. In order to do so macro MBED_CONF_NORDIC_LF_CLOCK_SYNTH_ACCURACY should been provided (e.g. in mbed_app.json).
|
||||
By default, such configuration is set to NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM.
|
||||
For further information, see the documentation for the [API of a SoftDevice 13x version 2.0.0](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v2.0.0%2Fgroup___n_r_f___s_d_m___d_e_f_i_n_e_s.html)
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"lf_clock_synth_accuracy": {
|
||||
"value": "NRF_CLOCK_LF_SYNTH_ACCURACY_250_PPM",
|
||||
"macro_name": "MBED_CONF_NORDIC_LF_CLOCK_XTAL_ACCURACY"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PERIPHERALPINS_H
|
||||
#define MBED_PERIPHERALPINS_H
|
||||
|
||||
#include "pinmap.h"
|
||||
#include "PeripheralNames.h"
|
||||
|
||||
#if DEVICE_ANALOGIN
|
||||
/************ADC***************/
|
||||
extern const PinMap PinMap_ADC[];
|
||||
#endif
|
||||
|
||||
#endif // MBED_PERIPHERALPINS_H
|
|
@ -0,0 +1,46 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 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 "pinmap_ex.h"
|
||||
#include "mbed_toolchain.h"
|
||||
|
||||
/* Default mapping between I2C pins and I2C instance.
|
||||
* Can be overwritten by user.
|
||||
*/
|
||||
MBED_WEAK const PinMapI2C PinMap_I2C[1] = {
|
||||
{ NC, NC, NC }
|
||||
};
|
||||
|
||||
/* Default mapping between SPI pins and SPI instance.
|
||||
* Can be overwritten by user.
|
||||
*/
|
||||
MBED_WEAK const PinMapSPI PinMap_SPI[1] = {
|
||||
{ NC, NC, NC, NC }
|
||||
};
|
||||
|
||||
/* Default mapping between PWM pins and PWM instance.
|
||||
* Can be overwritten by user.
|
||||
*/
|
||||
MBED_WEAK const PinMapPWM PinMap_PWM[1] = {
|
||||
{ NC, NC }
|
||||
};
|
||||
|
||||
/* Default mapping between UART pins and UART instance.
|
||||
* Can be overwritten by user.
|
||||
*/
|
||||
MBED_WEAK const PinMapUART PinMap_UART[1] = {
|
||||
{ NC, NC, NC }
|
||||
};
|
|
@ -0,0 +1,153 @@
|
|||
# Nordic NRF52
|
||||
|
||||
## Adding New Targets Based On Nordic NRF52832 And NRF52840 MCUs
|
||||
|
||||
First, create a new entry in `mbed-os/targets/targets.json` using the template below:
|
||||
|
||||
```json
|
||||
{
|
||||
"target_name": {
|
||||
"inherits": [""],
|
||||
"release_versions": ["5"],
|
||||
"device_name": ""
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Where `target_name` is the name of the new target, `inherits` can be either `MCU_NRF52832` or `MCU_NRF52840`, and `device_name` is the ID specifying actual RAM and flash size, for example, `nRF52832_xxAA` and `nRF52840_xxAA`. The `release_version` specifies that the target is compatible with Mbed OS 5.
|
||||
|
||||
This entry enables the new target in the Mbed OS build system.
|
||||
|
||||
Next, add optional target specific configuration in `mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/mbed_lib.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"target_overrides": {
|
||||
"target_name": {
|
||||
"target.macros_add": [
|
||||
"optional macros"
|
||||
],
|
||||
"optional configuration"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The optional configuration includes specifying errata fixes specific for the MCU release used on the target, configuring the low-frequency clock source, and configuring the UART behavior. See targets `NRF52_DK` and `NRF52840_DK` for examples.
|
||||
|
||||
### LF Clock Configuration
|
||||
|
||||
LF clock source configuration is used for MCU startup initialization and the BLE SoftDevice LF clock configuration (if BLE libraries is used). Advanced configurations are used only for the BLE SoftDevice LF clock configuration.
|
||||
|
||||
Default clock source is XTAL oscillator. There are three options that can be configured as the clock source:
|
||||
- NRF_LF_SRC_XTAL
|
||||
- NRF_LF_SRC_RC
|
||||
- NRF_LF_SRC_SYNTH
|
||||
|
||||
Set `lf_clock_src` to what is most suitable for the target. This value can later be overridden by the user application if necessary.
|
||||
|
||||
|
||||
## Mbed HAL Implementation Details
|
||||
|
||||
### SPI and I2C
|
||||
|
||||
The TWI/TWIM (I2C) and SPI/SPIM module shares the same underlying hardware and each instance can only provide one functionality at a time. Both the NRF52832 and NRF52840 have 2 TWI/TWIM modules and 3 SPI/SPIM:
|
||||
|
||||
| Instance 0 | Instance 1 | Instance 2 |
|
||||
| :---: | :---: | :---: |
|
||||
| SPI0/SPIM0 | SPI1/SPIM1 | SPI2/SPIM2 |
|
||||
| TWI0/TWIM0 | TWI1/TWIM1 | |
|
||||
|
||||
When instantiating a new Mbed SPI object or I2C object, the object will be assigned a hardware instance. By default, the HAL implementation will automatically pick a hardware instance based on the assigned pins in the following order:
|
||||
|
||||
1. The driver will look up the pins in the configuration table and pick a pre-assigned instance.
|
||||
1. If the pins can't be found in the configuration table, the driver will check if a hardware instance has already been assigned to those pins so that objects using the same pins will share the same instance.
|
||||
1. If no instance has been assigned, the driver will look for a free instane. For I2C objects instances are assigned from 0 to 1. For SPI objects instances are assigned from 2 to 0. This ensures that no matter the order of instantiation the first three objects can be guaranteed to be on separate instances no matter the pins being used.
|
||||
1. If no unused instance can be found, objects not sharing any pins will be assigned to the same default instance, which is `Instance 0` for I2C and `Instance 2` for SPI.
|
||||
|
||||
#### Customization
|
||||
|
||||
A custom configuration table can be provided by overriding the weakly defined default empty table. In the example below, I2C objects using pins `p1` and `p2` for `SDA` and `SCL` will always be assigned to `Instance 1` and SPI objects using pins `p3`, `p4`, `p5` for `MOSI`, `MISO`, and `CLOCK` will be assigned to `Instance 2` and SPI objects using pins `p6`, `p7`, and `p8` will be assigned to `Instance 0`. The custom configuration table must always be terminated with a row of `NC`.
|
||||
|
||||
```
|
||||
const PinMapI2C PinMap_I2C[] = {
|
||||
{p1, p2, 1},
|
||||
{NC, NC, NC}
|
||||
};
|
||||
|
||||
const PinMapSPI PinMap_SPI[] = {
|
||||
{p3, p4, p5, 2},
|
||||
{p6, p7, p8, 0},
|
||||
{NC, NC, NC, NC}
|
||||
};
|
||||
```
|
||||
|
||||
The tables must be placed in a C compilation file.
|
||||
|
||||
#### Concurrency
|
||||
|
||||
1. When called from the same thread, it is safe to assign I2C and SPI objects to the same instance.
|
||||
1. If an instance is being used exclusively for either I2C or SPI, the objects can safely be called from multiple threads.
|
||||
1. If an instance is being used for both I2C and SPI, the user must provide thread safety between the objects.
|
||||
|
||||
|
||||
### Serial
|
||||
|
||||
The serial implementation uses the UARTE module which works exclusively through EasyDMA and RAM buffers. For optimal performance, each configured instance (NRF52832 has 1, NRF52840 has 2) has three buffers statically assigned:
|
||||
|
||||
1. Rx DMA buffer, which EasyDMA is currently writing to.
|
||||
1. Rx DMA buffer, pre-loaded in EasyDMA for automatic switchover.
|
||||
1. Rx FIFO buffer, for serving data to the application.
|
||||
|
||||
When the first DMA buffer is full or flushed the interrupt handler will automatically copy the DMA buffer to the FIFO buffer. This happens in interrupt context to avoid data loss and with UARTE interrupts set at the highest priority. The FIFO buffer is backed by the Nordic atomic fifo, which can be read and written to safely without disabling interrupts.
|
||||
|
||||
#### Customization
|
||||
|
||||
All buffers can be resized to fit the application:
|
||||
|
||||
```
|
||||
"name": "nordic",
|
||||
"config": {
|
||||
"uart-dma-size": {
|
||||
"help": "UART DMA buffer. 2 buffers per instance. DMA buffer is filled by UARTE",
|
||||
"value": 8
|
||||
},
|
||||
"uart-0-fifo-size": {
|
||||
"help": "UART0 FIFO buffer. FIFO buffer is filled from DMA buffer.",
|
||||
"value": 32
|
||||
},
|
||||
"uart-1-fifo-size": {
|
||||
"help": "UART1 FIFO buffer. FIFO buffer is filled from DMA buffer.",
|
||||
"value": 32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All DMA buffers are the same size and must be at least 5 bytes due to hardware restrictions. DMA buffers should be sized to handle the worst expected interrupt latency. FIFO buffers can be configured per instance and the size should reflect the largest expected burst data. For example, a serial debug port might receive a line of data at a time, so an 80 byte FIFO buffer would be adequate. A serial port connected to a wifi radio should have a FIFO buffer in the kilo byte range.
|
||||
|
||||
For the NRF52840, UARTE instances are assigned based on pins and calling order. Serial objects with the same pin configurations will go to the same instance. A custom configuration table can be provided by overriding the weakly defined default empty table. In the example below, serial objects using pins `p1` and `p2` for `Tx` and `Rx` will always be assigned to `Instance 1` and serial objects using pins `p3` and `p4` for `Tx` and `Rx` will be assigned to `Instance 0` regardless of calling order. The custom configuration table must always be terminated with a row of `NC`.
|
||||
|
||||
```
|
||||
const PinMapI2C PinMap_UART[] = {
|
||||
{p1, p2, 1},
|
||||
{p3, p4, 0},
|
||||
{NC, NC, NC}
|
||||
};
|
||||
```
|
||||
|
||||
The table must be placed in a C compilation file.
|
||||
|
||||
|
||||
#### RTC2
|
||||
|
||||
Because each DMA buffer must be at least 5 bytes deep, each buffer is automatically flushed after a certain idle period to ensure low latency and correctness. This idle timeout is implemented using 2 of the 4 channels on RTC instance 2. This leaves RTC0 for the SoftDevice and RTC1 for Mbed tickers.
|
||||
|
||||
The RTC2 ISR is set at the lowest interrupt priority to ensure that UARTE interrupts take precedence. The last 2 of the 4 RTC channels are used for decoupling UARTE ISR context from Mbed IRQ events. This ensures that any user code will only delay other user callbacks and idle flushing and puts an upper bound on the interrupt handling time for the UARTE ISR.
|
||||
|
||||
#### Limitations
|
||||
|
||||
* The UARTE hardware only supports 8-bit, None/Even parity, and 1 stop bit.
|
||||
* The asynchronous read and write implementation currently only support 255 byte transfers.
|
||||
* The EasyDMA hardware can only read from RAM, which means all Tx buffers must reside in RAM. If a Tx buffer residing in flash is passed to the asynchronous write function, the function will try to copy the Tx buffer to a temporary internal buffer and transmit the data from there.
|
||||
* It is not possible to do an asynchronous write from flash and receive non-asynchronously at the same time since the non-asynchronous receive buffer is being used as the temporary transmission buffer.
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
UART_0 = (int)NRF_UART0_BASE
|
||||
} UARTName;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SPI_0 = (int)NRF_SPI0_BASE,
|
||||
SPI_1 = (int)NRF_SPI1_BASE,
|
||||
SPIS = (int)NRF_SPIS1_BASE
|
||||
} SPIName;
|
||||
|
||||
typedef enum {
|
||||
PWM_1 = 0,
|
||||
PWM_2
|
||||
} PWMName;
|
||||
|
||||
typedef enum {
|
||||
I2C_0 = (int)NRF_TWI0_BASE,
|
||||
I2C_1 = (int)NRF_TWI1_BASE
|
||||
} I2CName;
|
||||
|
||||
typedef enum {
|
||||
ADC0_0 = (int)0
|
||||
} ADCName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
typedef enum {
|
||||
NRF_SAADC_CHANNEL_0 = 0,
|
||||
NRF_SAADC_CHANNEL_1 = 1,
|
||||
NRF_SAADC_CHANNEL_2 = 2,
|
||||
NRF_SAADC_CHANNEL_3 = 3,
|
||||
NRF_SAADC_CHANNEL_4 = 4,
|
||||
NRF_SAADC_CHANNEL_5 = 5,
|
||||
NRF_SAADC_CHANNEL_6 = 6,
|
||||
NRF_SAADC_CHANNEL_7 = 7,
|
||||
} nrf_saadc_channel_t;
|
||||
|
||||
/************ADC***************/
|
||||
/* The third "function" value is used to select the correct ADC channel */
|
||||
#if DEVICE_ANALOGIN
|
||||
const PinMap PinMap_ADC[] = {
|
||||
{ p2, ADC0_0, NRF_SAADC_CHANNEL_0 },
|
||||
{ p3, ADC0_0, NRF_SAADC_CHANNEL_1 },
|
||||
{ p4, ADC0_0, NRF_SAADC_CHANNEL_2 },
|
||||
{ p5, ADC0_0, NRF_SAADC_CHANNEL_3 },
|
||||
{ p28, ADC0_0, NRF_SAADC_CHANNEL_4 },
|
||||
{ p29, ADC0_0, NRF_SAADC_CHANNEL_5 },
|
||||
{ p30, ADC0_0, NRF_SAADC_CHANNEL_6 },
|
||||
{ p31, ADC0_0, NRF_SAADC_CHANNEL_7 },
|
||||
{ NC, NC, NC }
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PORTNAMES_H
|
||||
#define MBED_PORTNAMES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
Port0 = 0 //GPIO pins 0-31
|
||||
} PortName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
|
||||
LED1 = p17,
|
||||
LED2 = p18,
|
||||
LED3 = p19,
|
||||
LED4 = p20,
|
||||
|
||||
BUTTON1 = p13,
|
||||
BUTTON2 = p14,
|
||||
BUTTON3 = p15,
|
||||
BUTTON4 = p16,
|
||||
|
||||
RX_PIN_NUMBER = p11,
|
||||
TX_PIN_NUMBER = p12,
|
||||
CTS_PIN_NUMBER = p13,
|
||||
RTS_PIN_NUMBER = p14,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
|
||||
SPI_PSELMOSI0 = p23,
|
||||
SPI_PSELMISO0 = p24,
|
||||
SPI_PSELSS0 = p22,
|
||||
SPI_PSELSCK0 = p25,
|
||||
|
||||
SPI_PSELMOSI1 = p12,
|
||||
SPI_PSELMISO1 = p13,
|
||||
SPI_PSELSS1 = p11,
|
||||
SPI_PSELSCK1 = p14,
|
||||
|
||||
SPIS_PSELMOSI = p12,
|
||||
SPIS_PSELMISO = p13,
|
||||
SPIS_PSELSS = p11,
|
||||
SPIS_PSELSCK = p14,
|
||||
|
||||
I2C_SDA0 = p26,
|
||||
I2C_SCL0 = p27,
|
||||
|
||||
D0 = p11,
|
||||
D1 = p12,
|
||||
D2 = p13,
|
||||
D3 = p14,
|
||||
D4 = p15,
|
||||
D5 = p16,
|
||||
D6 = p17,
|
||||
D7 = p18,
|
||||
|
||||
D8 = p19,
|
||||
D9 = p20,
|
||||
D10 = p22,
|
||||
D11 = p23,
|
||||
D12 = p24,
|
||||
D13 = p25,
|
||||
|
||||
D14 = p26,
|
||||
D15 = p27,
|
||||
|
||||
A0 = p3,
|
||||
A1 = p4,
|
||||
A2 = p28,
|
||||
A3 = p29,
|
||||
A4 = p30,
|
||||
A5 = p31,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2016 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.
|
||||
*/
|
||||
|
||||
void mbed_sdk_init()
|
||||
{
|
||||
char* debug_date = __DATE__;
|
||||
char* debug_time = __TIME__;
|
||||
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2013 Nordic Semiconductor
|
||||
*
|
||||
* 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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
|
||||
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
P0_31 = p31,
|
||||
|
||||
// Module pins. Refer datasheet for pin numbers.
|
||||
SIO_1 = P0_1,
|
||||
SIO_2 = P0_2,
|
||||
SIO_3 = P0_3,
|
||||
SIO_4 = P0_4,
|
||||
SIO_5 = P0_5,
|
||||
SIO_6 = P0_6,
|
||||
SIO_7 = P0_7,
|
||||
SIO_8 = P0_8,
|
||||
SIO_9 = P0_9, //NFC1
|
||||
SIO_10 = P0_10, //NFC2
|
||||
SIO_11 = P0_11,
|
||||
SIO_12 = P0_12,
|
||||
SIO_13 = P0_13,
|
||||
SIO_14 = P0_14,
|
||||
SIO_15 = P0_15,
|
||||
SIO_16 = P0_16,
|
||||
SIO_17 = P0_17,
|
||||
SIO_18 = P0_18,
|
||||
SIO_19 = P0_19,
|
||||
SIO_20 = P0_20,
|
||||
|
||||
SIO_22 = P0_22,
|
||||
SIO_23 = P0_23,
|
||||
SIO_24 = P0_24,
|
||||
SIO_25 = P0_25,
|
||||
SIO_26 = P0_26,
|
||||
SIO_27 = P0_27,
|
||||
SIO_28 = P0_28,
|
||||
SIO_29 = P0_29,
|
||||
SIO_30 = P0_30,
|
||||
SIO_31 = P0_31,
|
||||
SIO_0 = P0_0,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF,
|
||||
|
||||
//Mbed MTB pin defines.
|
||||
P_1 = NC,
|
||||
P_2 = SIO_24, //MISO
|
||||
P_3 = SIO_23, //MOSI
|
||||
P_4 = SIO_22,
|
||||
// P_5 = SWDIO,
|
||||
// P_6 = SWDCLK,
|
||||
// P_7 = NRST,
|
||||
P_8 = SIO_20,
|
||||
P_9 = SIO_18,
|
||||
P_10 = SIO_16,
|
||||
P_11 = SIO_14,
|
||||
P_12 = SIO_12,
|
||||
P_13 = SIO_11,
|
||||
P_14 = SIO_10,
|
||||
P_15 = SIO_9,
|
||||
P_16 = NC,
|
||||
P_17 = SIO_8,
|
||||
P_18 = SIO_7,
|
||||
P_19 = SIO_6,
|
||||
P_20 = SIO_5,
|
||||
P_21 = SIO_4,
|
||||
P_22 = SIO_3,
|
||||
P_23 = SIO_2,
|
||||
P_24 = SIO_1,
|
||||
P_25 = SIO_0,
|
||||
P_26 = NC,
|
||||
P_27 = NC,
|
||||
P_28 = SIO_13,
|
||||
P_29 = SIO_15,
|
||||
P_30 = SIO_17,
|
||||
P_31 = SIO_19,
|
||||
P_32 = SIO_31,
|
||||
P_33 = SIO_30,
|
||||
P_34 = SIO_29,
|
||||
P_35 = SIO_28,
|
||||
P_36 = SIO_27,
|
||||
P_37 = SIO_26,
|
||||
P_38 = SIO_25,
|
||||
P_39 = NC,
|
||||
|
||||
//LEDs
|
||||
LED1 = SIO_28,
|
||||
LED2 = SIO_29,
|
||||
LED3 = SIO_30,
|
||||
LED_RED = LED1,
|
||||
LED_GREEN = LED2,
|
||||
LED_BLUE = LED3,
|
||||
|
||||
GP0 = SIO_11,
|
||||
//Standardized button name
|
||||
BUTTON1 = GP0,
|
||||
|
||||
//Nordic SDK pin names
|
||||
RX_PIN_NUMBER = SIO_8,
|
||||
TX_PIN_NUMBER = SIO_6,
|
||||
CTS_PIN_NUMBER = SIO_7,
|
||||
RTS_PIN_NUMBER = SIO_5,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
STDIO_UART_CTS = CTS_PIN_NUMBER,
|
||||
STDIO_UART_RTS = RTS_PIN_NUMBER,
|
||||
|
||||
SPI_MOSI = SIO_23,
|
||||
SPI_MISO = SIO_24,
|
||||
SPI_SS0 = SIO_17, //CS for LCD on MTB
|
||||
SPI_SS1 = SIO_10, //CS for SD card on MTB
|
||||
SPI_SCK1 = SIO_25,
|
||||
SPI_SCK2 = SIO_31,
|
||||
|
||||
//Default SPI
|
||||
SPI_SCK = SPI_SCK1,
|
||||
SPI_CS = SPI_SS1,
|
||||
|
||||
I2C_SDA = SIO_26,
|
||||
I2C_SCL = SIO_27,
|
||||
|
||||
//MTB aliases
|
||||
GP1 = SIO_13,
|
||||
AIN0 = SIO_2,
|
||||
AIN1 = SIO_3,
|
||||
AIN2 = SIO_4,
|
||||
GP2 = SIO_10,
|
||||
GP3 = SIO_9,
|
||||
GP4 = SIO_22,
|
||||
GP5 = SIO_19, //A0 for LCD on MTB
|
||||
GP6 = SIO_18, //RESET for LCD on MTB
|
||||
GP7 = SIO_17,
|
||||
GP8 = SIO_15,
|
||||
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016 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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
// nRF52 pin names
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
NC = (int)0xFFFFFFFF, // Not connected
|
||||
|
||||
//NINA-B112 module pin names
|
||||
P_1 = p8,
|
||||
P_2 = p11,
|
||||
P_3 = p12,
|
||||
P_4 = p13,
|
||||
P_5 = p14,
|
||||
P_6 = NC,
|
||||
P_7 = p16,
|
||||
P_8 = p18,
|
||||
P_9 = NC,
|
||||
P_10 = NC,
|
||||
P_11 = NC,
|
||||
P_12 = NC,
|
||||
P_13 = NC,
|
||||
P_14 = NC,
|
||||
P_15 = NC,
|
||||
P_16 = p28,
|
||||
P_17 = p29,
|
||||
P_18 = p30,
|
||||
P_19 = p21,
|
||||
P_20 = p31,
|
||||
P_21 = p7,
|
||||
P_22 = p6,
|
||||
P_23 = p5,
|
||||
P_24 = p2,
|
||||
P_25 = p3,
|
||||
P_26 = NC,
|
||||
P_27 = p4,
|
||||
P_28 = p9,
|
||||
P_29 = p10,
|
||||
P_30 = NC,
|
||||
|
||||
// MTB aliases
|
||||
GPIO18 = p30,
|
||||
|
||||
LED1 = p4, // Red LED
|
||||
LED2 = p10, // Green LED
|
||||
GPIO27 = LED1,
|
||||
// GPIO29 = LED2,
|
||||
|
||||
GPIO7 = p16, //A0 for LCD
|
||||
GPIO16 = p28, //RESET for LCD
|
||||
|
||||
SW1 = p29,
|
||||
GPIO17 = SW1,
|
||||
//Standardized button names
|
||||
BUTTON1 = SW1,
|
||||
|
||||
// Nordic SDK pin names
|
||||
RX_PIN_NUMBER = p5,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7,
|
||||
RTS_PIN_NUMBER = p31,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
|
||||
I2C_SDA = p2,
|
||||
I2C_SCL = p3,
|
||||
|
||||
SPI0_MOSI = p13,
|
||||
SPI0_MISO = p12,
|
||||
SPI0_SCK = p14,
|
||||
SPI0_CS = p11,
|
||||
SPI1_CS = p8,
|
||||
|
||||
SPI_MOSI = SPI0_MOSI,
|
||||
SPI_MISO = SPI0_MISO,
|
||||
SPI_SCK = SPI0_SCK,
|
||||
SPI_CS = SPI0_CS,
|
||||
|
||||
// DAPLink
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
NTRST = p21,
|
||||
SWO = p18,
|
||||
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
P0_31 = p31,
|
||||
|
||||
LED1 = p17,
|
||||
LED2 = p18,
|
||||
LED3 = p19,
|
||||
LED4 = p20,
|
||||
|
||||
BUTTON1 = p13,
|
||||
BUTTON2 = p14,
|
||||
BUTTON3 = p15,
|
||||
BUTTON4 = p16,
|
||||
|
||||
RX_PIN_NUMBER = p8,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7,
|
||||
RTS_PIN_NUMBER = p5,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
STDIO_UART_CTS = CTS_PIN_NUMBER,
|
||||
STDIO_UART_RTS = RTS_PIN_NUMBER,
|
||||
|
||||
SPI_PSELMOSI0 = p23,
|
||||
SPI_PSELMISO0 = p24,
|
||||
SPI_PSELSS0 = p22,
|
||||
SPI_PSELSCK0 = p25,
|
||||
|
||||
SPI_PSELMOSI1 = p12,
|
||||
SPI_PSELMISO1 = p13,
|
||||
SPI_PSELSS1 = p11,
|
||||
SPI_PSELSCK1 = p14,
|
||||
|
||||
SPIS_PSELMOSI = p12,
|
||||
SPIS_PSELMISO = p13,
|
||||
SPIS_PSELSS = p11,
|
||||
SPIS_PSELSCK = p14,
|
||||
|
||||
I2C_SDA0 = p26,
|
||||
I2C_SCL0 = p27,
|
||||
|
||||
D0 = p11,
|
||||
D1 = p12,
|
||||
D2 = p13,
|
||||
D3 = p14,
|
||||
D4 = p15,
|
||||
D5 = p16,
|
||||
D6 = p17,
|
||||
D7 = p18,
|
||||
|
||||
D8 = p19,
|
||||
D9 = p20,
|
||||
D10 = p22,
|
||||
D11 = p23,
|
||||
D12 = p24,
|
||||
D13 = p25,
|
||||
|
||||
D14 = p26,
|
||||
D15 = p27,
|
||||
|
||||
A0 = p3,
|
||||
A1 = p4,
|
||||
A2 = p28,
|
||||
A3 = p29,
|
||||
A4 = p30,
|
||||
A5 = p31,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
|
||||
LED1 = p11,
|
||||
LED2 = p11,
|
||||
LED3 = p11,
|
||||
LED4 = p11,
|
||||
|
||||
RX_PIN_NUMBER = p30,
|
||||
TX_PIN_NUMBER = p29,
|
||||
CTS_PIN_NUMBER = p28,
|
||||
RTS_PIN_NUMBER = p2,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
|
||||
SPI_PSELMOSI0 = p6,
|
||||
SPI_PSELMISO0 = p7,
|
||||
SPI_PSELSS0 = p3,
|
||||
SPI_PSELSCK0 = p8,
|
||||
|
||||
SPI_PSELMOSI1 = p29,
|
||||
SPI_PSELMISO1 = p30,
|
||||
SPI_PSELSS1 = p28,
|
||||
SPI_PSELSCK1 = p2,
|
||||
|
||||
SPIS_PSELMOSI = p29,
|
||||
SPIS_PSELMISO = p30,
|
||||
SPIS_PSELSS = p28,
|
||||
SPIS_PSELSCK = p2,
|
||||
|
||||
I2C_SDA0 = p28,
|
||||
I2C_SCL0 = p2,
|
||||
|
||||
D0 = p30,
|
||||
D1 = p29,
|
||||
D2 = p28,
|
||||
D3 = p2,
|
||||
|
||||
D4 = p3,
|
||||
D5 = p6,
|
||||
D6 = p7,
|
||||
D7 = p8,
|
||||
D8 = p21,
|
||||
|
||||
D9 = p4,
|
||||
D10 = p5,
|
||||
|
||||
D13 = p11,
|
||||
|
||||
A0 = p28,
|
||||
A1 = p29,
|
||||
A2 = p30,
|
||||
A3 = p2,
|
||||
A4 = p4,
|
||||
A5 = p5,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
// nRF52 pin names
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
NC = (int)0xFFFFFFFF, // Not connected
|
||||
|
||||
//NINA-B1 module pin names
|
||||
NINA_B1_GPIO_1 = p8,
|
||||
NINA_B1_GPIO_2 = p11,
|
||||
NINA_B1_GPIO_3 = p12,
|
||||
NINA_B1_GPIO_4 = p13,
|
||||
NINA_B1_GPIO_5 = p14,
|
||||
NINA_B1_GPIO_7 = p16,
|
||||
NINA_B1_GPIO_8 = p18,
|
||||
|
||||
NINA_B1_GPIO_16 = p28,
|
||||
NINA_B1_GPIO_17 = p29,
|
||||
NINA_B1_GPIO_18 = p30,
|
||||
|
||||
NINA_B1_GPIO_20 = p31,
|
||||
NINA_B1_GPIO_21 = p7,
|
||||
NINA_B1_GPIO_22 = p6,
|
||||
NINA_B1_GPIO_23 = p5,
|
||||
NINA_B1_GPIO_24 = p2,
|
||||
NINA_B1_GPIO_25 = p3,
|
||||
NINA_B1_GPIO_27 = p4,
|
||||
NINA_B1_GPIO_28 = p9,
|
||||
NINA_B1_GPIO_29 = p10,
|
||||
|
||||
// Board pins
|
||||
LED1 = NINA_B1_GPIO_7, // ORANGE
|
||||
LED2 = NC,
|
||||
LED3 = NC,
|
||||
LED4 = NC,
|
||||
|
||||
// Nordic SDK pin names
|
||||
RX_PIN_NUMBER = p5,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7,
|
||||
RTS_PIN_NUMBER = p31,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
|
||||
I2C_SDA0 = p2,
|
||||
I2C_SCL0 = p3,
|
||||
|
||||
// mBed interface pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
// nRF52 pin names
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
NC = (int)0xFFFFFFFF, // Not connected
|
||||
|
||||
//NINA-B1 module pin names
|
||||
NINA_B1_GPIO_1 = p8,
|
||||
NINA_B1_GPIO_2 = p11,
|
||||
NINA_B1_GPIO_3 = p12,
|
||||
NINA_B1_GPIO_4 = p13,
|
||||
NINA_B1_GPIO_5 = p14,
|
||||
NINA_B1_GPIO_7 = p16,
|
||||
NINA_B1_GPIO_8 = p18,
|
||||
|
||||
NINA_B1_GPIO_16 = p28,
|
||||
NINA_B1_GPIO_17 = p29,
|
||||
NINA_B1_GPIO_18 = p30,
|
||||
|
||||
NINA_B1_GPIO_20 = p31,
|
||||
NINA_B1_GPIO_21 = p7,
|
||||
NINA_B1_GPIO_22 = p6,
|
||||
NINA_B1_GPIO_23 = p5,
|
||||
NINA_B1_GPIO_24 = p2,
|
||||
NINA_B1_GPIO_25 = p3,
|
||||
NINA_B1_GPIO_27 = p4,
|
||||
NINA_B1_GPIO_28 = p9,
|
||||
NINA_B1_GPIO_29 = p10,
|
||||
|
||||
// EVK-NINA-B1 board
|
||||
LED1 = NINA_B1_GPIO_1, // Red
|
||||
LED2 = NINA_B1_GPIO_7, // Green/SW1
|
||||
LED3 = NINA_B1_GPIO_8, // Blue
|
||||
LED4 = NINA_B1_GPIO_8,
|
||||
SW1 = NINA_B1_GPIO_7,
|
||||
SW2 = NINA_B1_GPIO_18,
|
||||
D0 = NINA_B1_GPIO_23,
|
||||
D1 = NINA_B1_GPIO_22,
|
||||
D2 = NINA_B1_GPIO_21,
|
||||
D3 = NINA_B1_GPIO_20,
|
||||
D4 = NINA_B1_GPIO_8,
|
||||
D5 = NC, // SWDIO
|
||||
D6 = NINA_B1_GPIO_28,
|
||||
D7 = NINA_B1_GPIO_29,
|
||||
D8 = NC, // SWDCLK
|
||||
D9 = NINA_B1_GPIO_1,
|
||||
D10 = NINA_B1_GPIO_2,
|
||||
D11 = NINA_B1_GPIO_4,
|
||||
D12 = NINA_B1_GPIO_3,
|
||||
D13 = NINA_B1_GPIO_5,
|
||||
D14 = NINA_B1_GPIO_24,
|
||||
D15 = NINA_B1_GPIO_25,
|
||||
A0 = NINA_B1_GPIO_25,
|
||||
A1 = NINA_B1_GPIO_24,
|
||||
A2 = NINA_B1_GPIO_27,
|
||||
A3 = NINA_B1_GPIO_18,
|
||||
A4 = NINA_B1_GPIO_17,
|
||||
A5 = NINA_B1_GPIO_16,
|
||||
// Nordic SDK pin names
|
||||
RX_PIN_NUMBER = p5,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7,
|
||||
RTS_PIN_NUMBER = p31,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
STDIO_UART_CTS = CTS_PIN_NUMBER,
|
||||
STDIO_UART_RTS = RTS_PIN_NUMBER,
|
||||
I2C_SDA0 = p2,
|
||||
I2C_SCL0 = p3,
|
||||
// mBed interface pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 2017 VNG IoT Lab, Vietnam
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* PinNames for the VBLUno52 board
|
||||
*/
|
||||
#ifndef MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
typedef enum {
|
||||
p0 = 0,
|
||||
p1 = 1,
|
||||
p2 = 2,
|
||||
p3 = 3,
|
||||
p4 = 4,
|
||||
p5 = 5,
|
||||
p6 = 6,
|
||||
p7 = 7,
|
||||
p8 = 8,
|
||||
p9 = 9,
|
||||
p10 = 10,
|
||||
p11 = 11,
|
||||
p12 = 12,
|
||||
p13 = 13,
|
||||
p14 = 14,
|
||||
p15 = 15,
|
||||
p16 = 16,
|
||||
p17 = 17,
|
||||
p18 = 18,
|
||||
p19 = 19,
|
||||
p20 = 20,
|
||||
p21 = 21,
|
||||
p22 = 22,
|
||||
p23 = 23,
|
||||
p24 = 24,
|
||||
p25 = 25,
|
||||
p26 = 26,
|
||||
p27 = 27,
|
||||
p28 = 28,
|
||||
p29 = 29,
|
||||
p30 = 30,
|
||||
p31 = 31,
|
||||
|
||||
P0_0 = p0,
|
||||
P0_1 = p1,
|
||||
P0_2 = p2,
|
||||
P0_3 = p3,
|
||||
P0_4 = p4,
|
||||
P0_5 = p5,
|
||||
P0_6 = p6,
|
||||
P0_7 = p7,
|
||||
|
||||
P0_8 = p8,
|
||||
P0_9 = p9,
|
||||
P0_10 = p10,
|
||||
P0_11 = p11,
|
||||
P0_12 = p12,
|
||||
P0_13 = p13,
|
||||
P0_14 = p14,
|
||||
P0_15 = p15,
|
||||
|
||||
P0_16 = p16,
|
||||
P0_17 = p17,
|
||||
P0_18 = p18,
|
||||
P0_19 = p19,
|
||||
P0_20 = p20,
|
||||
P0_21 = p21,
|
||||
P0_22 = p22,
|
||||
P0_23 = p23,
|
||||
|
||||
P0_24 = p24,
|
||||
P0_25 = p25,
|
||||
P0_26 = p26,
|
||||
P0_27 = p27,
|
||||
P0_28 = p28,
|
||||
P0_29 = p29,
|
||||
P0_30 = p30,
|
||||
P0_31 = p31,
|
||||
|
||||
//only for mbed test suite
|
||||
LED1 = p12,
|
||||
LED2 = p18,
|
||||
LED3 = p19,
|
||||
LED4 = p20,
|
||||
|
||||
//only for mbed test suite
|
||||
BUTTON1 = p17,
|
||||
BUTTON2 = p3,
|
||||
BUTTON3 = p4,
|
||||
BUTTON4 = p28,
|
||||
|
||||
RX_PIN_NUMBER = p8,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7, //not on Header
|
||||
RTS_PIN_NUMBER = p5, //not on Header
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
STDIO_UART_CTS = CTS_PIN_NUMBER,
|
||||
STDIO_UART_RTS = RTS_PIN_NUMBER,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
|
||||
SPI_PSELMOSI0 = p13,
|
||||
SPI_PSELMISO0 = p14,
|
||||
SPI_PSELSS0 = p11,
|
||||
SPI_PSELSCK0 = p15,
|
||||
|
||||
SPI_PSELMOSI1 = p13,
|
||||
SPI_PSELMISO1 = p14,
|
||||
SPI_PSELSS1 = p11,
|
||||
SPI_PSELSCK1 = p15,
|
||||
|
||||
SPIS_PSELMOSI = p13,
|
||||
SPIS_PSELMISO = p14,
|
||||
SPIS_PSELSS = p11,
|
||||
SPIS_PSELSCK = p15,
|
||||
|
||||
I2C_SDA = p26,
|
||||
I2C_SCL = p27,
|
||||
|
||||
I2C_SDA0 = p26,
|
||||
I2C_SCL0 = p27,
|
||||
|
||||
I2C_SDA1 = p30,
|
||||
I2C_SCL1 = p31,
|
||||
|
||||
RESET = p21,
|
||||
|
||||
NFC1 = p9,
|
||||
NFC2 = p10,
|
||||
|
||||
//Adruino interface pins
|
||||
D0 = p8,
|
||||
D1 = p6,
|
||||
D2 = p24,
|
||||
D3 = p23,
|
||||
D4 = p22,
|
||||
D5 = p18,
|
||||
D6 = p19,
|
||||
D7 = p20,
|
||||
|
||||
D8 = p9,
|
||||
D9 = p10,
|
||||
D10 = p11,
|
||||
D11 = p13,
|
||||
D12 = p14,
|
||||
D13 = p15,
|
||||
|
||||
D14 = p3,
|
||||
D15 = p4,
|
||||
D16 = p28,
|
||||
D17 = p29,
|
||||
D18 = p30,
|
||||
D19 = p31,
|
||||
|
||||
D20 = p26,
|
||||
D21 = p27,
|
||||
|
||||
D22 = p12,
|
||||
D23 = p17,
|
||||
|
||||
D24 = p5,
|
||||
D25 = p7,
|
||||
|
||||
A0 = D14,
|
||||
A1 = D15,
|
||||
A2 = D16,
|
||||
A3 = D17,
|
||||
A4 = D18,
|
||||
A5 = D19,
|
||||
|
||||
SS = D10,
|
||||
MOSI = D11,
|
||||
MISO = D12,
|
||||
SCK = D13,
|
||||
|
||||
SDA0 = D20,
|
||||
SCL0 = D21,
|
||||
SDA1 = D18,
|
||||
SCL1 = D19,
|
||||
SDA = SDA0,
|
||||
SCL = SCL0,
|
||||
|
||||
RX = D0,
|
||||
TX = D1,
|
||||
RTS = D24, //not on Header
|
||||
CTS = D25, //not on Header
|
||||
|
||||
LED = D22, //not on Header
|
||||
BUT = D23, //not on Header
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
#! armcc -E
|
||||
|
||||
/* Default to no softdevice */
|
||||
#if !defined(MBED_APP_START)
|
||||
#define MBED_APP_START 0x0
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_APP_SIZE)
|
||||
#define MBED_APP_SIZE 0x80000
|
||||
#endif
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
#if MBED_APP_START == 0
|
||||
#define MBED_RAM_START 0x20000000
|
||||
#define MBED_RAM_SIZE 0x10000
|
||||
#else
|
||||
#define MBED_RAM_START 0x20003800
|
||||
#define MBED_RAM_SIZE 0xC800
|
||||
#endif
|
||||
|
||||
#define MBED_RAM0_START MBED_RAM_START
|
||||
#define MBED_RAM0_SIZE 0xDC
|
||||
#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE)
|
||||
#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE)
|
||||
|
||||
LR_IROM1 MBED_APP_START MBED_APP_SIZE {
|
||||
ER_IROM1 MBED_APP_START MBED_APP_SIZE {
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_IRAM0 MBED_RAM0_START UNINIT MBED_RAM0_SIZE { ;no init section
|
||||
*(*noinit)
|
||||
}
|
||||
RW_IRAM1 MBED_RAM1_START MBED_RAM1_SIZE {
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
;/* Copyright (c) 2012 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
__initial_sp EQU 0x20010000
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemoryManagement_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler
|
||||
DCD DebugMonitor_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD POWER_CLOCK_IRQHandler
|
||||
DCD RADIO_IRQHandler
|
||||
DCD UARTE0_UART0_IRQHandler_v
|
||||
DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
DCD NFCT_IRQHandler_v
|
||||
DCD GPIOTE_IRQHandler_v
|
||||
DCD SAADC_IRQHandler_v
|
||||
DCD TIMER0_IRQHandler_v
|
||||
DCD TIMER1_IRQHandler_v
|
||||
DCD TIMER2_IRQHandler_v
|
||||
DCD RTC0_IRQHandler
|
||||
DCD TEMP_IRQHandler_v
|
||||
DCD RNG_IRQHandler
|
||||
DCD ECB_IRQHandler
|
||||
DCD CCM_AAR_IRQHandler
|
||||
DCD WDT_IRQHandler_v
|
||||
DCD RTC1_IRQHandler_v
|
||||
DCD QDEC_IRQHandler_v
|
||||
DCD COMP_LPCOMP_IRQHandler_v
|
||||
DCD SWI0_EGU0_IRQHandler_v
|
||||
DCD SWI1_EGU1_IRQHandler_v
|
||||
DCD SWI2_EGU2_IRQHandler_v
|
||||
DCD SWI3_EGU3_IRQHandler_v
|
||||
DCD SWI4_EGU4_IRQHandler
|
||||
DCD SWI5_EGU5_IRQHandler
|
||||
DCD TIMER3_IRQHandler_v
|
||||
DCD TIMER4_IRQHandler_v
|
||||
DCD PWM0_IRQHandler_v
|
||||
DCD PDM_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD MWU_IRQHandler
|
||||
DCD PWM1_IRQHandler_v
|
||||
DCD PWM2_IRQHandler_v
|
||||
DCD SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
DCD RTC2_IRQHandler_v
|
||||
DCD I2S_IRQHandler_v
|
||||
DCD FPU_IRQHandler_v
|
||||
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
; Reset Handler
|
||||
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
IMPORT nrf_reloc_vector_table
|
||||
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemoryManagement_Handler\
|
||||
PROC
|
||||
EXPORT MemoryManagement_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMonitor_Handler\
|
||||
PROC
|
||||
EXPORT DebugMonitor_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT POWER_CLOCK_IRQHandler [WEAK]
|
||||
EXPORT RADIO_IRQHandler [WEAK]
|
||||
EXPORT UARTE0_UART0_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v [WEAK]
|
||||
EXPORT NFCT_IRQHandler_v [WEAK]
|
||||
EXPORT GPIOTE_IRQHandler_v [WEAK]
|
||||
EXPORT SAADC_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER0_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER1_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER2_IRQHandler_v [WEAK]
|
||||
EXPORT RTC0_IRQHandler [WEAK]
|
||||
EXPORT TEMP_IRQHandler_v [WEAK]
|
||||
EXPORT RNG_IRQHandler [WEAK]
|
||||
EXPORT ECB_IRQHandler [WEAK]
|
||||
EXPORT CCM_AAR_IRQHandler [WEAK]
|
||||
EXPORT WDT_IRQHandler_v [WEAK]
|
||||
EXPORT RTC1_IRQHandler_v [WEAK]
|
||||
EXPORT QDEC_IRQHandler_v [WEAK]
|
||||
EXPORT COMP_LPCOMP_IRQHandler_v [WEAK]
|
||||
EXPORT SWI0_EGU0_IRQHandler_v [WEAK]
|
||||
EXPORT SWI1_EGU1_IRQHandler_v [WEAK]
|
||||
EXPORT SWI2_EGU2_IRQHandler_v [WEAK]
|
||||
EXPORT SWI3_EGU3_IRQHandler_v [WEAK]
|
||||
EXPORT SWI4_EGU4_IRQHandler [WEAK]
|
||||
EXPORT SWI5_EGU5_IRQHandler [WEAK]
|
||||
EXPORT TIMER3_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER4_IRQHandler_v [WEAK]
|
||||
EXPORT PWM0_IRQHandler_v [WEAK]
|
||||
EXPORT PDM_IRQHandler_v [WEAK]
|
||||
EXPORT MWU_IRQHandler [WEAK]
|
||||
EXPORT PWM1_IRQHandler_v [WEAK]
|
||||
EXPORT PWM2_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM2_SPIS2_SPI2_IRQHandler_v [WEAK]
|
||||
EXPORT RTC2_IRQHandler_v [WEAK]
|
||||
EXPORT I2S_IRQHandler_v [WEAK]
|
||||
EXPORT FPU_IRQHandler_v [WEAK]
|
||||
POWER_CLOCK_IRQHandler
|
||||
RADIO_IRQHandler
|
||||
UARTE0_UART0_IRQHandler_v
|
||||
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
NFCT_IRQHandler_v
|
||||
GPIOTE_IRQHandler_v
|
||||
SAADC_IRQHandler_v
|
||||
TIMER0_IRQHandler_v
|
||||
TIMER1_IRQHandler_v
|
||||
TIMER2_IRQHandler_v
|
||||
RTC0_IRQHandler
|
||||
TEMP_IRQHandler_v
|
||||
RNG_IRQHandler
|
||||
ECB_IRQHandler
|
||||
CCM_AAR_IRQHandler
|
||||
WDT_IRQHandler_v
|
||||
RTC1_IRQHandler_v
|
||||
QDEC_IRQHandler_v
|
||||
COMP_LPCOMP_IRQHandler_v
|
||||
SWI0_EGU0_IRQHandler_v
|
||||
SWI1_EGU1_IRQHandler_v
|
||||
SWI2_EGU2_IRQHandler_v
|
||||
SWI3_EGU3_IRQHandler_v
|
||||
SWI4_EGU4_IRQHandler
|
||||
SWI5_EGU5_IRQHandler
|
||||
TIMER3_IRQHandler_v
|
||||
TIMER4_IRQHandler_v
|
||||
PWM0_IRQHandler_v
|
||||
PDM_IRQHandler_v
|
||||
MWU_IRQHandler
|
||||
PWM1_IRQHandler_v
|
||||
PWM2_IRQHandler_v
|
||||
SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
RTC2_IRQHandler_v
|
||||
I2S_IRQHandler_v
|
||||
FPU_IRQHandler_v
|
||||
B .
|
||||
ENDP
|
||||
ALIGN
|
||||
END
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
/* Default to no softdevice */
|
||||
#if !defined(MBED_APP_START)
|
||||
#define MBED_APP_START 0x0
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_APP_SIZE)
|
||||
#define MBED_APP_SIZE 0x80000
|
||||
#endif
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
#if MBED_APP_START == 0
|
||||
#define MBED_RAM_START 0x20000000
|
||||
#define MBED_RAM_SIZE 0x10000
|
||||
#else
|
||||
#define MBED_RAM_START 0x20003800
|
||||
#define MBED_RAM_SIZE 0xC800
|
||||
#endif
|
||||
|
||||
#define MBED_RAM0_START MBED_RAM_START
|
||||
#define MBED_RAM0_SIZE 0xDC
|
||||
#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE)
|
||||
#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
|
||||
RAM_NVIC (rwx) : ORIGIN = MBED_RAM0_START, LENGTH = MBED_RAM0_SIZE
|
||||
RAM (rwx) : ORIGIN = MBED_RAM1_START, LENGTH = MBED_RAM1_SIZE
|
||||
}
|
||||
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with the other linker script that defines memory regions FLASH and RAM.
|
||||
* It references the following symbols that must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines the following symbols that the code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.Vectors))
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
.sdh_soc_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_soc_observers = .);
|
||||
KEEP(*(SORT(.sdh_soc_observers*)))
|
||||
PROVIDE(__stop_sdh_soc_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_stack_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_stack_observers = .);
|
||||
KEEP(*(SORT(.sdh_stack_observers*)))
|
||||
PROVIDE(__stop_sdh_stack_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_req_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_req_observers = .);
|
||||
KEEP(*(SORT(.sdh_req_observers*)))
|
||||
PROVIDE(__stop_sdh_req_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_state_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_state_observers = .);
|
||||
KEEP(*(SORT(.sdh_state_observers*)))
|
||||
PROVIDE(__stop_sdh_state_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_ble_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_ble_observers = .);
|
||||
KEEP(*(SORT(.sdh_ble_observers*)))
|
||||
PROVIDE(__stop_sdh_ble_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
PROVIDE(__start_fs_data = .);
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
|
||||
*(.jcr)
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > RAM
|
||||
|
||||
__edata = .;
|
||||
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
PROVIDE(__start_noinit = .);
|
||||
KEEP(*(.noinit))
|
||||
PROVIDE(__stop_noinit = .);
|
||||
} > RAM_NVIC
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.heap (NOLOAD):
|
||||
{
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
*(.heap*);
|
||||
|
||||
/* Expand the heap to reach the stack boundary. */
|
||||
ASSERT(. <= (ORIGIN(RAM) + LENGTH(RAM) - 0x800), "heap region overflowed into stack");
|
||||
. += (ORIGIN(RAM) + LENGTH(RAM) - 0x800) - .;
|
||||
} > RAM
|
||||
PROVIDE(__heap_start = ADDR(.heap));
|
||||
PROVIDE(__heap_size = SIZEOF(.heap));
|
||||
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
|
||||
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
|
||||
|
||||
/* .stack_dummy section does not contain any symbols. It is only
|
||||
* used for the linker script to calculate the size of stack sections
|
||||
* and assign values to stack symbols later. */
|
||||
.stack (NOLOAD):
|
||||
{
|
||||
__StackLimit = .;
|
||||
*(.stack*)
|
||||
. += (ORIGIN(RAM) + LENGTH(RAM) - .);
|
||||
} > RAM
|
||||
|
||||
/* Set the stack top to the end of RAM and move down the stack limit by
|
||||
* the size of the stack_dummy section. */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NOTE: Template files (including this one) are application specific and therefore
|
||||
expected to be copied into the application project folder prior to its use!
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.arch armv7e-m
|
||||
|
||||
.section .Vectors
|
||||
.align 2
|
||||
.globl __Vectors
|
||||
__Vectors:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler
|
||||
.long NMI_Handler
|
||||
.long HardFault_Handler
|
||||
.long MemoryManagement_Handler
|
||||
.long BusFault_Handler
|
||||
.long UsageFault_Handler
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long SVC_Handler
|
||||
.long DebugMon_Handler
|
||||
.long 0 /*Reserved */
|
||||
.long PendSV_Handler
|
||||
.long SysTick_Handler
|
||||
|
||||
/* External Interrupts */
|
||||
.long POWER_CLOCK_IRQHandler
|
||||
.long RADIO_IRQHandler
|
||||
.long UARTE0_UART0_IRQHandler_v
|
||||
.long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
.long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
.long NFCT_IRQHandler_v
|
||||
.long GPIOTE_IRQHandler_v
|
||||
.long SAADC_IRQHandler_v
|
||||
.long TIMER0_IRQHandler_v
|
||||
.long TIMER1_IRQHandler_v
|
||||
.long TIMER2_IRQHandler_v
|
||||
.long RTC0_IRQHandler
|
||||
.long TEMP_IRQHandler_v
|
||||
.long RNG_IRQHandler
|
||||
.long ECB_IRQHandler
|
||||
.long CCM_AAR_IRQHandler
|
||||
.long WDT_IRQHandler_v
|
||||
.long RTC1_IRQHandler_v
|
||||
.long QDEC_IRQHandler_v
|
||||
.long COMP_LPCOMP_IRQHandler_v
|
||||
.long SWI0_EGU0_IRQHandler_v
|
||||
.long SWI1_EGU1_IRQHandler_v
|
||||
.long SWI2_EGU2_IRQHandler_v
|
||||
.long SWI3_EGU3_IRQHandler_v
|
||||
.long SWI4_EGU4_IRQHandler
|
||||
.long SWI5_EGU5_IRQHandler
|
||||
.long TIMER3_IRQHandler_v
|
||||
.long TIMER4_IRQHandler_v
|
||||
.long PWM0_IRQHandler_v
|
||||
.long PDM_IRQHandler_v
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long MWU_IRQHandler
|
||||
.long PWM1_IRQHandler_v
|
||||
.long PWM2_IRQHandler_v
|
||||
.long SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
.long RTC2_IRQHandler_v
|
||||
.long I2S_IRQHandler_v
|
||||
.long FPU_IRQHandler_v
|
||||
|
||||
|
||||
.size __Vectors, . - __Vectors
|
||||
|
||||
/* Reset Handler */
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 1
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
.fnstart
|
||||
|
||||
|
||||
/* Loop to copy data from read only memory to RAM. The ranges
|
||||
* of copy from/to are specified by following symbols evaluated in
|
||||
* linker script.
|
||||
* __etext: End of code section, i.e., begin of data sections to copy from.
|
||||
* __data_start__/__data_end__: RAM address range that data should be
|
||||
* copied to. Both must be aligned to 4 bytes boundary. */
|
||||
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
subs r3, r2
|
||||
ble .LC0
|
||||
|
||||
.LC1:
|
||||
subs r3, 4
|
||||
ldr r0, [r1,r3]
|
||||
str r0, [r2,r3]
|
||||
bgt .LC1
|
||||
.LC0:
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =_start
|
||||
BX R0
|
||||
|
||||
.pool
|
||||
.cantunwind
|
||||
.fnend
|
||||
.size Reset_Handler,.-Reset_Handler
|
||||
|
||||
.section ".text"
|
||||
|
||||
|
||||
/* Dummy Exception Handlers (infinite loops which can be modified) */
|
||||
|
||||
.weak NMI_Handler
|
||||
.type NMI_Handler, %function
|
||||
NMI_Handler:
|
||||
B .
|
||||
.size NMI_Handler, . - NMI_Handler
|
||||
|
||||
|
||||
.weak HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
B .
|
||||
.size HardFault_Handler, . - HardFault_Handler
|
||||
|
||||
|
||||
.weak MemoryManagement_Handler
|
||||
.type MemoryManagement_Handler, %function
|
||||
MemoryManagement_Handler:
|
||||
B .
|
||||
.size MemoryManagement_Handler, . - MemoryManagement_Handler
|
||||
|
||||
|
||||
.weak BusFault_Handler
|
||||
.type BusFault_Handler, %function
|
||||
BusFault_Handler:
|
||||
B .
|
||||
.size BusFault_Handler, . - BusFault_Handler
|
||||
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.type UsageFault_Handler, %function
|
||||
UsageFault_Handler:
|
||||
B .
|
||||
.size UsageFault_Handler, . - UsageFault_Handler
|
||||
|
||||
|
||||
.weak SVC_Handler
|
||||
.type SVC_Handler, %function
|
||||
SVC_Handler:
|
||||
B .
|
||||
.size SVC_Handler, . - SVC_Handler
|
||||
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.type DebugMon_Handler, %function
|
||||
DebugMon_Handler:
|
||||
b .
|
||||
.size DebugMon_Handler, . - DebugMon_Handler
|
||||
|
||||
|
||||
.weak PendSV_Handler
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler:
|
||||
B .
|
||||
.size PendSV_Handler, . - PendSV_Handler
|
||||
|
||||
|
||||
.weak SysTick_Handler
|
||||
.type SysTick_Handler, %function
|
||||
SysTick_Handler:
|
||||
B .
|
||||
.size SysTick_Handler, . - SysTick_Handler
|
||||
|
||||
|
||||
/* IRQ Handlers */
|
||||
|
||||
.globl Default_Handler
|
||||
.type Default_Handler, %function
|
||||
Default_Handler:
|
||||
B .
|
||||
.size Default_Handler, . - Default_Handler
|
||||
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, Default_Handler
|
||||
.endm
|
||||
|
||||
IRQ POWER_CLOCK_IRQHandler /* restricted */
|
||||
IRQ RADIO_IRQHandler /* blocked */
|
||||
IRQ UARTE0_UART0_IRQHandler_v
|
||||
IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
IRQ NFCT_IRQHandler_v
|
||||
IRQ GPIOTE_IRQHandler_v
|
||||
IRQ SAADC_IRQHandler_v
|
||||
IRQ TIMER0_IRQHandler_v
|
||||
IRQ TIMER1_IRQHandler_v
|
||||
IRQ TIMER2_IRQHandler_v
|
||||
IRQ RTC0_IRQHandler /* blocked */
|
||||
IRQ TEMP_IRQHandler_v
|
||||
IRQ RNG_IRQHandler /* restricted */
|
||||
IRQ ECB_IRQHandler /* restricted */
|
||||
IRQ CCM_AAR_IRQHandler /* blocked */
|
||||
IRQ WDT_IRQHandler_v
|
||||
IRQ RTC1_IRQHandler_v
|
||||
IRQ QDEC_IRQHandler_v
|
||||
IRQ COMP_LPCOMP_IRQHandler_v
|
||||
IRQ SWI0_EGU0_IRQHandler_v
|
||||
IRQ SWI1_EGU1_IRQHandler_v /* restricted for Radio Notification */
|
||||
IRQ SWI2_EGU2_IRQHandler_v /* blocked for SoftDevice Event */
|
||||
IRQ SWI3_EGU3_IRQHandler_v
|
||||
IRQ SWI4_EGU4_IRQHandler /* blocked */
|
||||
IRQ SWI5_EGU5_IRQHandler /* blocked */
|
||||
IRQ TIMER3_IRQHandler_v
|
||||
IRQ TIMER4_IRQHandler_v
|
||||
IRQ PWM0_IRQHandler_v
|
||||
IRQ PDM_IRQHandler_v
|
||||
IRQ MWU_IRQHandler /* restricted */
|
||||
IRQ PWM1_IRQHandler_v
|
||||
IRQ PWM2_IRQHandler_v
|
||||
IRQ SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
IRQ RTC2_IRQHandler_v
|
||||
IRQ I2S_IRQHandler_v
|
||||
IRQ FPU_IRQHandler_v
|
||||
|
||||
.end
|
|
@ -0,0 +1,75 @@
|
|||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
|
||||
|
||||
/* Default to no softdevice */
|
||||
if (!isdefinedsymbol(MBED_APP_START)) {
|
||||
define symbol MBED_APP_START = 0x0;
|
||||
}
|
||||
|
||||
if (!isdefinedsymbol(MBED_APP_SIZE)) {
|
||||
define symbol MBED_APP_SIZE = 0x80000;
|
||||
}
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
if (MBED_APP_START == 0) {
|
||||
define symbol MBED_RAM_START = 0x20000000;
|
||||
define symbol MBED_RAM_SIZE = 0x10000;
|
||||
} else {
|
||||
define symbol MBED_RAM_START = 0x20003800;
|
||||
define symbol MBED_RAM_SIZE = 0xC800;
|
||||
}
|
||||
|
||||
define symbol MBED_RAM0_START = MBED_RAM_START;
|
||||
define symbol MBED_RAM0_SIZE = 0xDC;
|
||||
define symbol MBED_RAM1_START = (MBED_RAM_START + MBED_RAM0_SIZE);
|
||||
define symbol MBED_RAM1_SIZE = (MBED_RAM_SIZE - MBED_RAM0_SIZE);
|
||||
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
|
||||
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1;
|
||||
define symbol __ICFEDIT_region_RAM_NVIC_start__ = MBED_RAM0_START;
|
||||
define symbol __ICFEDIT_region_RAM_NVIC_end__ = MBED_RAM0_START + MBED_RAM0_SIZE - 1;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = MBED_RAM1_START;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = MBED_RAM1_START + MBED_RAM1_SIZE - 1;
|
||||
export symbol __ICFEDIT_region_RAM_start__;
|
||||
export symbol __ICFEDIT_region_RAM_end__;
|
||||
|
||||
/*-Sizes-*/
|
||||
/*Heap 1/4 of ram and stack 1/8*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0x800;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x5800;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __code_start_soft_device__ = 0x0;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
place at address mem:__ICFEDIT_region_RAM_NVIC_start__ { section .noinit };
|
||||
|
||||
keep { section .intvec };
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
place in ROM_region { readonly };
|
||||
place in RAM_region { readwrite,
|
||||
block HEAP,
|
||||
block CSTACK };
|
||||
|
||||
/*This is used for mbed applications build inside the Embedded workbench
|
||||
Applications build with the python scritps use a hex merge so need to merge it
|
||||
inside the linker. The linker can only use binary files so the hex merge is not possible
|
||||
through the linker. That is why a binary is used instead of a hex image for the embedded project.
|
||||
*/
|
||||
if(isdefinedsymbol(SOFT_DEVICE_BIN))
|
||||
{
|
||||
place at address mem:__code_start_soft_device__ { section .noinit_softdevice };
|
||||
}
|
|
@ -0,0 +1,381 @@
|
|||
;/* Copyright (c) 2012 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
; The modules in this file are included in the libraries, and may be replaced
|
||||
; by any user-defined modules that define the PUBLIC symbol _program_start or
|
||||
; a user defined start symbol.
|
||||
; To override the cstartup defined in the library, simply add your modified
|
||||
; version to the workbench project.
|
||||
;
|
||||
; The vector table is normally located at address 0.
|
||||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
|
||||
; The name "__vector_table" has special meaning for C-SPY:
|
||||
; it is where the SP start value is found, and the NVIC vector
|
||||
; table register (VTOR) is initialized to this address if != 0.
|
||||
|
||||
|
||||
|
||||
MODULE ?cstartup
|
||||
|
||||
;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW.
|
||||
;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW.
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
EXTERN nrf_reloc_vector_table
|
||||
PUBLIC __vector_table
|
||||
PUBLIC __Vectors
|
||||
PUBLIC __Vectors_End
|
||||
PUBLIC __Vectors_Size
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD Reset_Handler
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemoryManagement_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler
|
||||
DCD DebugMonitor_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD POWER_CLOCK_IRQHandler
|
||||
DCD RADIO_IRQHandler
|
||||
DCD UARTE0_UART0_IRQHandler_v
|
||||
DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
DCD NFCT_IRQHandler_v
|
||||
DCD GPIOTE_IRQHandler_v
|
||||
DCD SAADC_IRQHandler_v
|
||||
DCD TIMER0_IRQHandler_v
|
||||
DCD TIMER1_IRQHandler_v
|
||||
DCD TIMER2_IRQHandler_v
|
||||
DCD RTC0_IRQHandler
|
||||
DCD TEMP_IRQHandler_v
|
||||
DCD RNG_IRQHandler
|
||||
DCD ECB_IRQHandler
|
||||
DCD CCM_AAR_IRQHandler
|
||||
DCD WDT_IRQHandler_v
|
||||
DCD RTC1_IRQHandler_v
|
||||
DCD QDEC_IRQHandler_v
|
||||
DCD COMP_LPCOMP_IRQHandler_v
|
||||
DCD SWI0_EGU0_IRQHandler_v
|
||||
DCD SWI1_EGU1_IRQHandler_v
|
||||
DCD SWI2_EGU2_IRQHandler_v
|
||||
DCD SWI3_EGU3_IRQHandler_v
|
||||
DCD SWI4_EGU4_IRQHandler
|
||||
DCD SWI5_EGU5_IRQHandler
|
||||
DCD TIMER3_IRQHandler_v
|
||||
DCD TIMER4_IRQHandler_v
|
||||
DCD PWM0_IRQHandler_v
|
||||
DCD PDM_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD MWU_IRQHandler
|
||||
DCD PWM1_IRQHandler_v
|
||||
DCD PWM2_IRQHandler_v
|
||||
DCD SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
DCD RTC2_IRQHandler_v
|
||||
DCD I2S_IRQHandler_v
|
||||
DCD FPU_IRQHandler_v
|
||||
|
||||
|
||||
__Vectors_End
|
||||
__Vectors EQU __vector_table
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
|
||||
; Default handlers.
|
||||
THUMB
|
||||
|
||||
PUBWEAK Reset_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
Reset_Handler
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =__iar_program_start
|
||||
BX R0
|
||||
|
||||
; Dummy exception handlers
|
||||
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
NMI_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK HardFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
HardFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK MemoryManagement_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
MemoryManagement_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK BusFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
BusFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK UsageFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
UsageFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SVC_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SVC_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK DebugMonitor_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
DebugMonitor_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK PendSV_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PendSV_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SysTick_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SysTick_Handler
|
||||
B .
|
||||
|
||||
|
||||
; Dummy interrupt handlers
|
||||
|
||||
PUBWEAK POWER_CLOCK_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
POWER_CLOCK_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK RADIO_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RADIO_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK UARTE0_UART0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
UARTE0_UART0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK NFCT_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
NFCT_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK GPIOTE_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
GPIOTE_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SAADC_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SAADC_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC0_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK TEMP_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TEMP_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RNG_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RNG_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK ECB_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
ECB_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK CCM_AAR_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
CCM_AAR_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK WDT_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
WDT_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK QDEC_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
QDEC_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK COMP_LPCOMP_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
COMP_LPCOMP_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI0_EGU0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI0_EGU0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI1_EGU1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI1_EGU1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI2_EGU2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI2_EGU2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI3_EGU3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI3_EGU3_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI4_EGU4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI4_EGU4_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK SWI5_EGU5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI5_EGU5_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER3_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER4_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER4_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PWM0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PDM_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PDM_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK MWU_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
MWU_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK PWM1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PWM2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK I2S_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
I2S_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK FPU_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
FPU_IRQHandler_v
|
||||
B .
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* PackageLicenseDeclared: Apache-2.0
|
||||
* Copyright (c) 2016 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 MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "nrf.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/* mbed Microcontroller Library
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
extern uint32_t nrf_dispatch_vector[NVIC_NUM_VECTORS];
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
nrf_dispatch_vector[IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
return nrf_dispatch_vector[IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* mbed Microcontroller Library
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (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 MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 39) // CORE + MCU Peripherals
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
#include "nrf52.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009-2017 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
|
||||
|
||||
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.
|
||||
|
||||
NOTICE: This file has been modified by Nordic Semiconductor ASA.
|
||||
|
||||
*/
|
||||
|
||||
/* NOTE: Template files (including this one) are application specific and therefore expected to
|
||||
be copied into the application project folder prior to its use! */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
#include "system_nrf52.h"
|
||||
#include "nrf5x_lf_clk_helper.h"
|
||||
|
||||
/*lint ++flb "Enter library region" */
|
||||
|
||||
#define __SYSTEM_CLOCK_64M (64000000UL)
|
||||
|
||||
static bool errata_12(void);
|
||||
static bool errata_16(void);
|
||||
static bool errata_31(void);
|
||||
static bool errata_32(void);
|
||||
static bool errata_36(void);
|
||||
static bool errata_37(void);
|
||||
static bool errata_57(void);
|
||||
static bool errata_66(void);
|
||||
static bool errata_108(void);
|
||||
static bool errata_136(void);
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
|
||||
#elif defined ( __ICCARM__ )
|
||||
__root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
|
||||
#elif defined ( __GNUC__ )
|
||||
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
|
||||
#endif
|
||||
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
SystemCoreClock = __SYSTEM_CLOCK_64M;
|
||||
}
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
|
||||
Specification to see which one). */
|
||||
#if defined (ENABLE_SWO)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
|
||||
/* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
|
||||
Specification to see which ones). */
|
||||
#if defined (ENABLE_TRACE)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
|
||||
/* Workaround for Errata 12 "COMP: Reference ladder not correctly calibrated" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_12()){
|
||||
*(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_16()){
|
||||
*(volatile uint32_t *)0x4007C074 = 3131961357ul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_31()){
|
||||
*(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_32()){
|
||||
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_36()){
|
||||
NRF_CLOCK->EVENTS_DONE = 0;
|
||||
NRF_CLOCK->EVENTS_CTTO = 0;
|
||||
NRF_CLOCK->CTIV = 0;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_37()){
|
||||
*(volatile uint32_t *)0x400005A0 = 0x3;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_57()){
|
||||
*(volatile uint32_t *)0x40005610 = 0x00000005;
|
||||
*(volatile uint32_t *)0x40005688 = 0x00000001;
|
||||
*(volatile uint32_t *)0x40005618 = 0x00000000;
|
||||
*(volatile uint32_t *)0x40005614 = 0x0000003F;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_66()){
|
||||
NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
|
||||
NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
|
||||
NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
|
||||
NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
|
||||
NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
|
||||
NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
|
||||
NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
|
||||
NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
|
||||
NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
|
||||
NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
|
||||
NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
|
||||
NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
|
||||
NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
|
||||
NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
|
||||
NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
|
||||
NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
|
||||
NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_108()){
|
||||
*(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_136()){
|
||||
if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
|
||||
NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
|
||||
* compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
|
||||
* operations are not used in your code. */
|
||||
#if (__FPU_USED == 1)
|
||||
SCB->CPACR |= (3UL << 20) | (3UL << 22);
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
|
||||
/* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
|
||||
two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
|
||||
normal GPIOs. */
|
||||
#if defined (CONFIG_NFCT_PINS_AS_GPIOS)
|
||||
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
|
||||
defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
|
||||
reserved for PinReset and not available as normal GPIO. */
|
||||
#if defined (CONFIG_GPIO_AS_PINRESET)
|
||||
if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
|
||||
((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->PSELRESET[0] = 21;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->PSELRESET[1] = 21;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
// Start the LF oscilator according to the mbed configuration (over the nrf5x_lf_clk_helper.h file)
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_TO_USE << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
|
||||
// Wait for the external oscillator to start up.
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool errata_12(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_16(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_31(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_32(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_36(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_37(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_57(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool errata_66(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_108(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_136(void)
|
||||
{
|
||||
if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){
|
||||
return true;
|
||||
}
|
||||
if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*lint --flb "Leave library region" */
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009-2017 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
|
||||
|
||||
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.
|
||||
|
||||
NOTICE: This file has been modified by Nordic Semiconductor ASA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_NRF52_H
|
||||
#define SYSTEM_NRF52_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
/**
|
||||
* Update SystemCoreClock variable
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Updates the SystemCoreClock with current core Clock
|
||||
* retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_NRF52_H */
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PERIPHERALNAMES_H
|
||||
#define MBED_PERIPHERALNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UART_0 = (int)NRF_UART0_BASE
|
||||
} UARTName;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPI_0 = (int)NRF_SPI0_BASE,
|
||||
SPI_1 = (int)NRF_SPI1_BASE,
|
||||
SPIS = (int)NRF_SPIS1_BASE
|
||||
} SPIName;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PWM_1 = 0,
|
||||
PWM_2
|
||||
} PWMName;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
I2C_0 = (int)NRF_TWI0_BASE,
|
||||
I2C_1 = (int)NRF_TWI1_BASE
|
||||
} I2CName;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC0_0 = (int)0
|
||||
} ADCName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
typedef enum {
|
||||
NRF_SAADC_CHANNEL_0 = 0,
|
||||
NRF_SAADC_CHANNEL_1 = 1,
|
||||
NRF_SAADC_CHANNEL_2 = 2,
|
||||
NRF_SAADC_CHANNEL_3 = 3,
|
||||
NRF_SAADC_CHANNEL_4 = 4,
|
||||
NRF_SAADC_CHANNEL_5 = 5,
|
||||
NRF_SAADC_CHANNEL_6 = 6,
|
||||
NRF_SAADC_CHANNEL_7 = 7,
|
||||
} nrf_saadc_channel_t;
|
||||
|
||||
/************ADC***************/
|
||||
/* The third "function" value is used to select the correct ADC channel */
|
||||
#if DEVICE_ANALOGIN
|
||||
const PinMap PinMap_ADC[] = {
|
||||
{ p2, ADC0_0, NRF_SAADC_CHANNEL_0 },
|
||||
{ p3, ADC0_0, NRF_SAADC_CHANNEL_1 },
|
||||
{ p4, ADC0_0, NRF_SAADC_CHANNEL_2 },
|
||||
{ p5, ADC0_0, NRF_SAADC_CHANNEL_3 },
|
||||
{ p28, ADC0_0, NRF_SAADC_CHANNEL_4 },
|
||||
{ p29, ADC0_0, NRF_SAADC_CHANNEL_5 },
|
||||
{ p30, ADC0_0, NRF_SAADC_CHANNEL_6 },
|
||||
{ p31, ADC0_0, NRF_SAADC_CHANNEL_7 },
|
||||
{ NC, NC, NC }
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PORTNAMES_H
|
||||
#define MBED_PORTNAMES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Port0 = 0, //GPIO pins 0-31 -> 0.0-0.31
|
||||
Port1 = 1 //GPIO pins 32-47 -> 1.0-1.15
|
||||
} PortName;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (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 MBED_PINNAMES_H
|
||||
#define MBED_PINNAMES_H
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PIN_INPUT,
|
||||
PIN_OUTPUT
|
||||
} PinDirection;
|
||||
|
||||
#define PORT_SHIFT 3
|
||||
|
||||
///> define macro producing for example Px_y = NRF_GPIO_PIN_MAP(x, y)
|
||||
#define PinDef(port_num, pin_num) P##port_num##_##pin_num = NRF_GPIO_PIN_MAP(port_num, pin_num)
|
||||
|
||||
|
||||
typedef enum {
|
||||
PinDef(0 , 0), // P0_0 = 0...
|
||||
PinDef(0 , 1),
|
||||
PinDef(0 , 2),
|
||||
PinDef(0 , 3),
|
||||
PinDef(0 , 4),
|
||||
PinDef(0 , 5),
|
||||
PinDef(0 , 6),
|
||||
PinDef(0 , 7),
|
||||
PinDef(0 , 8),
|
||||
PinDef(0 , 9),
|
||||
PinDef(0 , 10),
|
||||
PinDef(0 , 11),
|
||||
PinDef(0 , 12),
|
||||
PinDef(0 , 13),
|
||||
PinDef(0 , 14),
|
||||
PinDef(0 , 15),
|
||||
PinDef(0 , 16),
|
||||
PinDef(0 , 17),
|
||||
PinDef(0 , 18),
|
||||
PinDef(0 , 19),
|
||||
PinDef(0 , 20),
|
||||
PinDef(0 , 21),
|
||||
PinDef(0 , 22),
|
||||
PinDef(0 , 23),
|
||||
PinDef(0 , 24),
|
||||
PinDef(0 , 25),
|
||||
PinDef(0 , 26),
|
||||
PinDef(0 , 27),
|
||||
PinDef(0 , 28),
|
||||
PinDef(0 , 29),
|
||||
PinDef(0 , 30),
|
||||
PinDef(0 , 31),
|
||||
|
||||
PinDef(1 , 0), //P1_1 = 32...
|
||||
PinDef(1 , 1),
|
||||
PinDef(1 , 2),
|
||||
PinDef(1 , 3),
|
||||
PinDef(1 , 4),
|
||||
PinDef(1 , 5),
|
||||
PinDef(1 , 6),
|
||||
PinDef(1 , 7),
|
||||
PinDef(1 , 8),
|
||||
PinDef(1 , 9),
|
||||
PinDef(1 , 10),
|
||||
PinDef(1 , 11),
|
||||
PinDef(1 , 12),
|
||||
PinDef(1 , 13),
|
||||
PinDef(1 , 14),
|
||||
PinDef(1 , 15),
|
||||
|
||||
// Port0
|
||||
p0 = P0_0,
|
||||
p1 = P0_1,
|
||||
p2 = P0_2,
|
||||
p3 = P0_3,
|
||||
p4 = P0_4,
|
||||
p5 = P0_5,
|
||||
p6 = P0_6,
|
||||
p7 = P0_7,
|
||||
p8 = P0_8,
|
||||
p9 = P0_9,
|
||||
p10 = P0_10,
|
||||
p11 = P0_11,
|
||||
p12 = P0_12,
|
||||
p13 = P0_13,
|
||||
p14 = P0_14,
|
||||
p15 = P0_15,
|
||||
p16 = P0_16,
|
||||
p17 = P0_17,
|
||||
p18 = P0_18,
|
||||
p19 = P0_19,
|
||||
p20 = P0_20,
|
||||
p21 = P0_21,
|
||||
p22 = P0_22,
|
||||
p23 = P0_23,
|
||||
p24 = P0_24,
|
||||
p25 = P0_25,
|
||||
p26 = P0_26,
|
||||
p27 = P0_27,
|
||||
p28 = P0_28,
|
||||
p29 = P0_29,
|
||||
p30 = P0_30,
|
||||
p31 = P0_31,
|
||||
|
||||
// Port1
|
||||
p32 = P1_0,
|
||||
p33 = P1_1,
|
||||
p34 = P1_2,
|
||||
p35 = P1_3,
|
||||
p36 = P1_4,
|
||||
p37 = P1_5,
|
||||
p38 = P1_6,
|
||||
p39 = P1_7,
|
||||
p40 = P1_8,
|
||||
p41 = P1_9,
|
||||
p42 = P1_10,
|
||||
p43 = P1_11,
|
||||
p44 = P1_12,
|
||||
p45 = P1_13,
|
||||
p46 = P1_14,
|
||||
p47 = P1_15,
|
||||
|
||||
LED1 = p13,
|
||||
LED2 = p14,
|
||||
LED3 = p15,
|
||||
LED4 = p16,
|
||||
|
||||
BUTTON1 = p11,
|
||||
BUTTON2 = p12,
|
||||
BUTTON3 = p24,
|
||||
BUTTON4 = p25,
|
||||
|
||||
RX_PIN_NUMBER = p8,
|
||||
TX_PIN_NUMBER = p6,
|
||||
CTS_PIN_NUMBER = p7,
|
||||
RTS_PIN_NUMBER = p5,
|
||||
|
||||
// mBed interface Pins
|
||||
USBTX = TX_PIN_NUMBER,
|
||||
USBRX = RX_PIN_NUMBER,
|
||||
STDIO_UART_TX = TX_PIN_NUMBER,
|
||||
STDIO_UART_RX = RX_PIN_NUMBER,
|
||||
STDIO_UART_CTS = CTS_PIN_NUMBER,
|
||||
STDIO_UART_RTS = RTS_PIN_NUMBER,
|
||||
|
||||
SPI_PSELMOSI0 = P1_13,
|
||||
SPI_PSELMISO0 = P1_14,
|
||||
SPI_PSELSS0 = P1_12,
|
||||
SPI_PSELSCK0 = P1_15,
|
||||
|
||||
SPI_PSELMOSI1 = P1_2,
|
||||
SPI_PSELMISO1 = P1_3,
|
||||
SPI_PSELSS1 = P1_1,
|
||||
SPI_PSELSCK1 = P1_4,
|
||||
|
||||
SPIS_PSELMOSI = P1_2,
|
||||
SPIS_PSELMISO = P1_3,
|
||||
SPIS_PSELSS = P1_1,
|
||||
SPIS_PSELSCK = P1_4,
|
||||
|
||||
I2C_SDA0 = p26,
|
||||
I2C_SCL0 = p27,
|
||||
|
||||
D0 = P1_1,
|
||||
D1 = P1_2,
|
||||
D2 = P1_3,
|
||||
D3 = P1_4,
|
||||
D4 = P1_5,
|
||||
D5 = P1_6,
|
||||
D6 = P1_7,
|
||||
D7 = P1_8,
|
||||
|
||||
D8 = P1_10,
|
||||
D9 = P1_11,
|
||||
D10 = P1_12,
|
||||
D11 = P1_13,
|
||||
D12 = P1_14,
|
||||
D13 = P1_15,
|
||||
|
||||
D14 = p26,
|
||||
D15 = p27,
|
||||
|
||||
A0 = p3,
|
||||
A1 = p4,
|
||||
A2 = p28,
|
||||
A3 = p29,
|
||||
A4 = p30,
|
||||
A5 = p31,
|
||||
|
||||
// Not connected
|
||||
NC = (int)0xFFFFFFFF
|
||||
} PinName;
|
||||
|
||||
typedef enum {
|
||||
PullNone = 0,
|
||||
PullDown = 1,
|
||||
PullUp = 3,
|
||||
PullDefault = PullUp
|
||||
} PinMode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
// The 'features' section in 'target.json' is now used to create the device's hardware preprocessor switches.
|
||||
// Check the 'features' section of the target description in 'targets.json' for more details.
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-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.
|
||||
*/
|
||||
#ifndef MBED_DEVICE_H
|
||||
#define MBED_DEVICE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "objects.h"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
#! armcc -E
|
||||
|
||||
/* Default to no softdevice */
|
||||
#if !defined(MBED_APP_START)
|
||||
#define MBED_APP_START 0x0
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_APP_SIZE)
|
||||
#define MBED_APP_SIZE 0x100000
|
||||
#endif
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
#if MBED_APP_START == 0
|
||||
#define MBED_RAM_START 0x20000000
|
||||
#define MBED_RAM_SIZE 0x40000
|
||||
#else
|
||||
#define MBED_RAM_START 0x20003700
|
||||
#define MBED_RAM_SIZE 0x3C900
|
||||
#endif
|
||||
|
||||
#define MBED_RAM0_START MBED_RAM_START
|
||||
#define MBED_RAM0_SIZE 0x100
|
||||
#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE)
|
||||
#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE)
|
||||
|
||||
LR_IROM1 MBED_APP_START MBED_APP_SIZE {
|
||||
ER_IROM1 MBED_APP_START MBED_APP_SIZE {
|
||||
*.o (RESET, +First)
|
||||
*(InRoot$$Sections)
|
||||
.ANY (+RO)
|
||||
}
|
||||
RW_IRAM0 MBED_RAM0_START UNINIT MBED_RAM0_SIZE { ;no init section
|
||||
*(*noinit)
|
||||
}
|
||||
RW_IRAM1 MBED_RAM1_START MBED_RAM1_SIZE {
|
||||
.ANY (+RW +ZI)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
;/* Copyright (c) 2012 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
__initial_sp EQU 0x20040000
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemoryManagement_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler
|
||||
DCD DebugMonitor_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD POWER_CLOCK_IRQHandler
|
||||
DCD RADIO_IRQHandler
|
||||
DCD UARTE0_UART0_IRQHandler_v
|
||||
DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
DCD NFCT_IRQHandler_v
|
||||
DCD GPIOTE_IRQHandler_v
|
||||
DCD SAADC_IRQHandler_v
|
||||
DCD TIMER0_IRQHandler_v
|
||||
DCD TIMER1_IRQHandler_v
|
||||
DCD TIMER2_IRQHandler_v
|
||||
DCD RTC0_IRQHandler
|
||||
DCD TEMP_IRQHandler_v
|
||||
DCD RNG_IRQHandler
|
||||
DCD ECB_IRQHandler
|
||||
DCD CCM_AAR_IRQHandler
|
||||
DCD WDT_IRQHandler_v
|
||||
DCD RTC1_IRQHandler_v
|
||||
DCD QDEC_IRQHandler_v
|
||||
DCD COMP_LPCOMP_IRQHandler_v
|
||||
DCD SWI0_EGU0_IRQHandler_v
|
||||
DCD SWI1_EGU1_IRQHandler_v
|
||||
DCD SWI2_EGU2_IRQHandler_v
|
||||
DCD SWI3_EGU3_IRQHandler_v
|
||||
DCD SWI4_EGU4_IRQHandler
|
||||
DCD SWI5_EGU5_IRQHandler
|
||||
DCD TIMER3_IRQHandler_v
|
||||
DCD TIMER4_IRQHandler_v
|
||||
DCD PWM0_IRQHandler_v
|
||||
DCD PDM_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD MWU_IRQHandler
|
||||
DCD PWM1_IRQHandler_v
|
||||
DCD PWM2_IRQHandler_v
|
||||
DCD SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
DCD RTC2_IRQHandler_v
|
||||
DCD I2S_IRQHandler_v
|
||||
DCD FPU_IRQHandler_v
|
||||
DCD USBD_IRQHandler_v
|
||||
DCD UARTE1_IRQHandler_v
|
||||
DCD QSPI_IRQHandler_v
|
||||
DCD CRYPTOCELL_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PWM3_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD SPIM3_IRQHandler_v
|
||||
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
; Reset Handler
|
||||
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
IMPORT nrf_reloc_vector_table
|
||||
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemoryManagement_Handler\
|
||||
PROC
|
||||
EXPORT MemoryManagement_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMonitor_Handler\
|
||||
PROC
|
||||
EXPORT DebugMonitor_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT POWER_CLOCK_IRQHandler [WEAK]
|
||||
EXPORT RADIO_IRQHandler [WEAK]
|
||||
EXPORT UARTE0_UART0_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v [WEAK]
|
||||
EXPORT NFCT_IRQHandler_v [WEAK]
|
||||
EXPORT GPIOTE_IRQHandler_v [WEAK]
|
||||
EXPORT SAADC_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER0_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER1_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER2_IRQHandler_v [WEAK]
|
||||
EXPORT RTC0_IRQHandler [WEAK]
|
||||
EXPORT TEMP_IRQHandler_v [WEAK]
|
||||
EXPORT RNG_IRQHandler [WEAK]
|
||||
EXPORT ECB_IRQHandler [WEAK]
|
||||
EXPORT CCM_AAR_IRQHandler [WEAK]
|
||||
EXPORT WDT_IRQHandler_v [WEAK]
|
||||
EXPORT RTC1_IRQHandler_v [WEAK]
|
||||
EXPORT QDEC_IRQHandler_v [WEAK]
|
||||
EXPORT COMP_LPCOMP_IRQHandler_v [WEAK]
|
||||
EXPORT SWI0_EGU0_IRQHandler_v [WEAK]
|
||||
EXPORT SWI1_EGU1_IRQHandler_v [WEAK]
|
||||
EXPORT SWI2_EGU2_IRQHandler_v [WEAK]
|
||||
EXPORT SWI3_EGU3_IRQHandler_v [WEAK]
|
||||
EXPORT SWI4_EGU4_IRQHandler [WEAK]
|
||||
EXPORT SWI5_EGU5_IRQHandler [WEAK]
|
||||
EXPORT TIMER3_IRQHandler_v [WEAK]
|
||||
EXPORT TIMER4_IRQHandler_v [WEAK]
|
||||
EXPORT PWM0_IRQHandler_v [WEAK]
|
||||
EXPORT PDM_IRQHandler_v [WEAK]
|
||||
EXPORT MWU_IRQHandler [WEAK]
|
||||
EXPORT PWM1_IRQHandler_v [WEAK]
|
||||
EXPORT PWM2_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM2_SPIS2_SPI2_IRQHandler_v [WEAK]
|
||||
EXPORT RTC2_IRQHandler_v [WEAK]
|
||||
EXPORT I2S_IRQHandler_v [WEAK]
|
||||
EXPORT FPU_IRQHandler_v [WEAK]
|
||||
EXPORT USBD_IRQHandler_v [WEAK]
|
||||
EXPORT UARTE1_IRQHandler_v [WEAK]
|
||||
EXPORT QSPI_IRQHandler_v [WEAK]
|
||||
EXPORT CRYPTOCELL_IRQHandler_v [WEAK]
|
||||
EXPORT SPIM3_IRQHandler_v [WEAK]
|
||||
EXPORT PWM3_IRQHandler_v [WEAK]
|
||||
|
||||
POWER_CLOCK_IRQHandler
|
||||
RADIO_IRQHandler
|
||||
UARTE0_UART0_IRQHandler_v
|
||||
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
NFCT_IRQHandler_v
|
||||
GPIOTE_IRQHandler_v
|
||||
SAADC_IRQHandler_v
|
||||
TIMER0_IRQHandler_v
|
||||
TIMER1_IRQHandler_v
|
||||
TIMER2_IRQHandler_v
|
||||
RTC0_IRQHandler
|
||||
TEMP_IRQHandler_v
|
||||
RNG_IRQHandler
|
||||
ECB_IRQHandler
|
||||
CCM_AAR_IRQHandler
|
||||
WDT_IRQHandler_v
|
||||
RTC1_IRQHandler_v
|
||||
QDEC_IRQHandler_v
|
||||
COMP_LPCOMP_IRQHandler_v
|
||||
SWI0_EGU0_IRQHandler_v
|
||||
SWI1_EGU1_IRQHandler_v
|
||||
SWI2_EGU2_IRQHandler_v
|
||||
SWI3_EGU3_IRQHandler_v
|
||||
SWI4_EGU4_IRQHandler
|
||||
SWI5_EGU5_IRQHandler
|
||||
TIMER3_IRQHandler_v
|
||||
TIMER4_IRQHandler_v
|
||||
PWM0_IRQHandler_v
|
||||
PDM_IRQHandler_v
|
||||
MWU_IRQHandler
|
||||
PWM1_IRQHandler_v
|
||||
PWM2_IRQHandler_v
|
||||
SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
RTC2_IRQHandler_v
|
||||
I2S_IRQHandler_v
|
||||
FPU_IRQHandler_v
|
||||
USBD_IRQHandler_v
|
||||
UARTE1_IRQHandler_v
|
||||
QSPI_IRQHandler_v
|
||||
CRYPTOCELL_IRQHandler_v
|
||||
PWM3_IRQHandler_v
|
||||
SPIM3_IRQHandler_v
|
||||
|
||||
B .
|
||||
ENDP
|
||||
ALIGN
|
||||
END
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
/* Default to no softdevice */
|
||||
#if !defined(MBED_APP_START)
|
||||
#define MBED_APP_START 0x0
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_APP_SIZE)
|
||||
#define MBED_APP_SIZE 0x100000
|
||||
#endif
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
#if MBED_APP_START == 0
|
||||
#define MBED_RAM_START 0x20000000
|
||||
#define MBED_RAM_SIZE 0x40000
|
||||
#else
|
||||
#define MBED_RAM_START 0x20003700
|
||||
#define MBED_RAM_SIZE 0x3C900
|
||||
#endif
|
||||
|
||||
#define MBED_RAM0_START MBED_RAM_START
|
||||
#define MBED_RAM0_SIZE 0x100
|
||||
#define MBED_RAM1_START (MBED_RAM_START + MBED_RAM0_SIZE)
|
||||
#define MBED_RAM1_SIZE (MBED_RAM_SIZE - MBED_RAM0_SIZE)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
|
||||
RAM_NVIC (rwx) : ORIGIN = MBED_RAM0_START, LENGTH = MBED_RAM0_SIZE
|
||||
RAM (rwx) : ORIGIN = MBED_RAM1_START, LENGTH = MBED_RAM1_SIZE
|
||||
}
|
||||
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with the other linker script that defines memory regions FLASH and RAM.
|
||||
* It references the following symbols that must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines the following symbols that the code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.Vectors))
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
.sdh_soc_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_soc_observers = .);
|
||||
KEEP(*(SORT(.sdh_soc_observers*)))
|
||||
PROVIDE(__stop_sdh_soc_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_stack_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_stack_observers = .);
|
||||
KEEP(*(SORT(.sdh_stack_observers*)))
|
||||
PROVIDE(__stop_sdh_stack_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_req_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_req_observers = .);
|
||||
KEEP(*(SORT(.sdh_req_observers*)))
|
||||
PROVIDE(__stop_sdh_req_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_state_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_state_observers = .);
|
||||
KEEP(*(SORT(.sdh_state_observers*)))
|
||||
PROVIDE(__stop_sdh_state_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.sdh_ble_observers :
|
||||
{
|
||||
PROVIDE(__start_sdh_ble_observers = .);
|
||||
KEEP(*(SORT(.sdh_ble_observers*)))
|
||||
PROVIDE(__stop_sdh_ble_observers = .);
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
PROVIDE(__start_fs_data = .);
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
|
||||
*(.jcr)
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > RAM
|
||||
|
||||
__edata = .;
|
||||
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
PROVIDE(__start_noinit = .);
|
||||
KEEP(*(.noinit))
|
||||
PROVIDE(__stop_noinit = .);
|
||||
} > RAM_NVIC
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.heap (NOLOAD):
|
||||
{
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
*(.heap*);
|
||||
|
||||
/* Expand the heap to reach the stack boundary. */
|
||||
ASSERT(. <= (ORIGIN(RAM) + LENGTH(RAM) - 0x800), "heap region overflowed into stack");
|
||||
. += (ORIGIN(RAM) + LENGTH(RAM) - 0x800) - .;
|
||||
} > RAM
|
||||
PROVIDE(__heap_start = ADDR(.heap));
|
||||
PROVIDE(__heap_size = SIZEOF(.heap));
|
||||
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
|
||||
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
|
||||
|
||||
/* .stack_dummy section does not contain any symbols. It is only
|
||||
* used for the linker script to calculate the size of stack sections
|
||||
* and assign values to stack symbols later. */
|
||||
.stack (NOLOAD):
|
||||
{
|
||||
__StackLimit = .;
|
||||
*(.stack*)
|
||||
. += (ORIGIN(RAM) + LENGTH(RAM) - .);
|
||||
} > RAM
|
||||
|
||||
/* Set the stack top to the end of RAM and move down the stack limit by
|
||||
* the size of the stack_dummy section. */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
}
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
|
||||
* integrated circuit in a product or a software update for such product, must reproduce
|
||||
* the above copyright notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary or object form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
NOTE: Template files (including this one) are application specific and therefore
|
||||
expected to be copied into the application project folder prior to its use!
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.arch armv7e-m
|
||||
|
||||
.section .Vectors
|
||||
.align 2
|
||||
.globl __Vectors
|
||||
__Vectors:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler
|
||||
.long NMI_Handler
|
||||
.long HardFault_Handler
|
||||
.long MemoryManagement_Handler
|
||||
.long BusFault_Handler
|
||||
.long UsageFault_Handler
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long SVC_Handler
|
||||
.long DebugMon_Handler
|
||||
.long 0 /*Reserved */
|
||||
.long PendSV_Handler
|
||||
.long SysTick_Handler
|
||||
|
||||
/* External Interrupts */
|
||||
.long POWER_CLOCK_IRQHandler
|
||||
.long RADIO_IRQHandler
|
||||
.long UARTE0_UART0_IRQHandler_v
|
||||
.long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
.long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
.long NFCT_IRQHandler_v
|
||||
.long GPIOTE_IRQHandler_v
|
||||
.long SAADC_IRQHandler_v
|
||||
.long TIMER0_IRQHandler_v
|
||||
.long TIMER1_IRQHandler_v
|
||||
.long TIMER2_IRQHandler_v
|
||||
.long RTC0_IRQHandler
|
||||
.long TEMP_IRQHandler_v
|
||||
.long RNG_IRQHandler
|
||||
.long ECB_IRQHandler
|
||||
.long CCM_AAR_IRQHandler
|
||||
.long WDT_IRQHandler_v
|
||||
.long RTC1_IRQHandler_v
|
||||
.long QDEC_IRQHandler_v
|
||||
.long COMP_LPCOMP_IRQHandler_v
|
||||
.long SWI0_EGU0_IRQHandler_v
|
||||
.long SWI1_EGU1_IRQHandler_v
|
||||
.long SWI2_EGU2_IRQHandler_v
|
||||
.long SWI3_EGU3_IRQHandler_v
|
||||
.long SWI4_EGU4_IRQHandler
|
||||
.long SWI5_EGU5_IRQHandler
|
||||
.long TIMER3_IRQHandler_v
|
||||
.long TIMER4_IRQHandler_v
|
||||
.long PWM0_IRQHandler_v
|
||||
.long PDM_IRQHandler_v
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long MWU_IRQHandler
|
||||
.long PWM1_IRQHandler_v
|
||||
.long PWM2_IRQHandler_v
|
||||
.long SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
.long RTC2_IRQHandler_v
|
||||
.long I2S_IRQHandler_v
|
||||
.long FPU_IRQHandler_v
|
||||
.long USBD_IRQHandler_v
|
||||
.long UARTE1_IRQHandler_v
|
||||
.long QSPI_IRQHandler_v
|
||||
.long CRYPTOCELL_IRQHandler_v
|
||||
.long 0 /*Reserved */
|
||||
.long 0 /*Reserved */
|
||||
.long PWM3_IRQHandler_v
|
||||
.long 0 /*Reserved */
|
||||
.long SPIM3_IRQHandler_v
|
||||
|
||||
|
||||
.size __Vectors, . - __Vectors
|
||||
|
||||
/* Reset Handler */
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 1
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
.fnstart
|
||||
|
||||
|
||||
/* Loop to copy data from read only memory to RAM. The ranges
|
||||
* of copy from/to are specified by following symbols evaluated in
|
||||
* linker script.
|
||||
* __etext: End of code section, i.e., begin of data sections to copy from.
|
||||
* __data_start__/__data_end__: RAM address range that data should be
|
||||
* copied to. Both must be aligned to 4 bytes boundary. */
|
||||
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
subs r3, r2
|
||||
ble .LC0
|
||||
|
||||
.LC1:
|
||||
subs r3, 4
|
||||
ldr r0, [r1,r3]
|
||||
str r0, [r2,r3]
|
||||
bgt .LC1
|
||||
.LC0:
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =_start
|
||||
BX R0
|
||||
|
||||
.pool
|
||||
.cantunwind
|
||||
.fnend
|
||||
.size Reset_Handler,.-Reset_Handler
|
||||
|
||||
.section ".text"
|
||||
|
||||
|
||||
/* Dummy Exception Handlers (infinite loops which can be modified) */
|
||||
|
||||
.weak NMI_Handler
|
||||
.type NMI_Handler, %function
|
||||
NMI_Handler:
|
||||
B .
|
||||
.size NMI_Handler, . - NMI_Handler
|
||||
|
||||
|
||||
.weak HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
B .
|
||||
.size HardFault_Handler, . - HardFault_Handler
|
||||
|
||||
|
||||
.weak MemoryManagement_Handler
|
||||
.type MemoryManagement_Handler, %function
|
||||
MemoryManagement_Handler:
|
||||
B .
|
||||
.size MemoryManagement_Handler, . - MemoryManagement_Handler
|
||||
|
||||
|
||||
.weak BusFault_Handler
|
||||
.type BusFault_Handler, %function
|
||||
BusFault_Handler:
|
||||
B .
|
||||
.size BusFault_Handler, . - BusFault_Handler
|
||||
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.type UsageFault_Handler, %function
|
||||
UsageFault_Handler:
|
||||
B .
|
||||
.size UsageFault_Handler, . - UsageFault_Handler
|
||||
|
||||
|
||||
.weak SVC_Handler
|
||||
.type SVC_Handler, %function
|
||||
SVC_Handler:
|
||||
B .
|
||||
.size SVC_Handler, . - SVC_Handler
|
||||
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.type DebugMon_Handler, %function
|
||||
DebugMon_Handler:
|
||||
b .
|
||||
.size DebugMon_Handler, . - DebugMon_Handler
|
||||
|
||||
|
||||
.weak PendSV_Handler
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler:
|
||||
B .
|
||||
.size PendSV_Handler, . - PendSV_Handler
|
||||
|
||||
|
||||
.weak SysTick_Handler
|
||||
.type SysTick_Handler, %function
|
||||
SysTick_Handler:
|
||||
B .
|
||||
.size SysTick_Handler, . - SysTick_Handler
|
||||
|
||||
|
||||
/* IRQ Handlers */
|
||||
|
||||
.globl Default_Handler
|
||||
.type Default_Handler, %function
|
||||
Default_Handler:
|
||||
B .
|
||||
.size Default_Handler, . - Default_Handler
|
||||
|
||||
.macro IRQ handler
|
||||
.weak \handler
|
||||
.set \handler, Default_Handler
|
||||
.endm
|
||||
|
||||
IRQ POWER_CLOCK_IRQHandler /* restricted */
|
||||
IRQ RADIO_IRQHandler /* blocked */
|
||||
IRQ UARTE0_UART0_IRQHandler_v
|
||||
IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
IRQ NFCT_IRQHandler_v
|
||||
IRQ GPIOTE_IRQHandler_v
|
||||
IRQ SAADC_IRQHandler_v
|
||||
IRQ TIMER0_IRQHandler_v
|
||||
IRQ TIMER1_IRQHandler_v
|
||||
IRQ TIMER2_IRQHandler_v
|
||||
IRQ RTC0_IRQHandler /* blocked */
|
||||
IRQ TEMP_IRQHandler_v
|
||||
IRQ RNG_IRQHandler /* restricted */
|
||||
IRQ ECB_IRQHandler /* restricted */
|
||||
IRQ CCM_AAR_IRQHandler /* blocked */
|
||||
IRQ WDT_IRQHandler_v
|
||||
IRQ RTC1_IRQHandler_v
|
||||
IRQ QDEC_IRQHandler_v
|
||||
IRQ COMP_LPCOMP_IRQHandler_v
|
||||
IRQ SWI0_EGU0_IRQHandler_v
|
||||
IRQ SWI1_EGU1_IRQHandler_v /* restricted for Radio Notification */
|
||||
IRQ SWI2_EGU2_IRQHandler_v /* blocked for SoftDevice Event */
|
||||
IRQ SWI3_EGU3_IRQHandler_v
|
||||
IRQ SWI4_EGU4_IRQHandler /* blocked */
|
||||
IRQ SWI5_EGU5_IRQHandler /* blocked */
|
||||
IRQ TIMER3_IRQHandler_v
|
||||
IRQ TIMER4_IRQHandler_v
|
||||
IRQ PWM0_IRQHandler_v
|
||||
IRQ PDM_IRQHandler_v
|
||||
IRQ MWU_IRQHandler /* restricted */
|
||||
IRQ PWM1_IRQHandler_v
|
||||
IRQ PWM2_IRQHandler_v
|
||||
IRQ SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
IRQ RTC2_IRQHandler_v
|
||||
IRQ I2S_IRQHandler_v
|
||||
IRQ FPU_IRQHandler_v
|
||||
IRQ USBD_IRQHandler_v
|
||||
IRQ UARTE1_IRQHandler_v
|
||||
IRQ QSPI_IRQHandler_v
|
||||
IRQ CRYPTOCELL_IRQHandler_v
|
||||
IRQ PWM3_IRQHandler_v
|
||||
IRQ SPIM3_IRQHandler_v
|
||||
|
||||
.end
|
|
@ -0,0 +1,75 @@
|
|||
/*###ICF### Section handled by ICF editor, don't touch! ****/
|
||||
/*-Editor annotation file-*/
|
||||
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
|
||||
|
||||
/* Default to no softdevice */
|
||||
if (!isdefinedsymbol(MBED_APP_START)) {
|
||||
define symbol MBED_APP_START = 0x0;
|
||||
}
|
||||
|
||||
if (!isdefinedsymbol(MBED_APP_SIZE)) {
|
||||
define symbol MBED_APP_SIZE = 0x100000;
|
||||
}
|
||||
|
||||
/* If app_start is 0, do not set aside space for the softdevice */
|
||||
if (MBED_APP_START == 0) {
|
||||
define symbol MBED_RAM_START = 0x20000000;
|
||||
define symbol MBED_RAM_SIZE = 0x40000;
|
||||
} else {
|
||||
define symbol MBED_RAM_START = 0x20003700;
|
||||
define symbol MBED_RAM_SIZE = 0x3C900;
|
||||
}
|
||||
|
||||
define symbol MBED_RAM0_START = MBED_RAM_START;
|
||||
define symbol MBED_RAM0_SIZE = 0x100;
|
||||
define symbol MBED_RAM1_START = (MBED_RAM_START + MBED_RAM0_SIZE);
|
||||
define symbol MBED_RAM1_SIZE = (MBED_RAM_SIZE - MBED_RAM0_SIZE);
|
||||
|
||||
/*-Specials-*/
|
||||
define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
|
||||
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = MBED_APP_START;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = MBED_APP_START + MBED_APP_SIZE - 1;
|
||||
define symbol __ICFEDIT_region_RAM_NVIC_start__ = MBED_RAM0_START;
|
||||
define symbol __ICFEDIT_region_RAM_NVIC_end__ = MBED_RAM0_START + MBED_RAM0_SIZE - 1;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = MBED_RAM1_START;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = MBED_RAM1_START + MBED_RAM1_SIZE - 1;
|
||||
export symbol __ICFEDIT_region_RAM_start__;
|
||||
export symbol __ICFEDIT_region_RAM_end__;
|
||||
|
||||
/*-Sizes-*/
|
||||
/*Heap 1/4 of ram and stack 1/8*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 0x800;
|
||||
define symbol __ICFEDIT_size_heap__ = 0x17800;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __code_start_soft_device__ = 0x0;
|
||||
|
||||
define memory mem with size = 4G;
|
||||
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
|
||||
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
|
||||
|
||||
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
|
||||
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
|
||||
|
||||
initialize by copy { readwrite };
|
||||
do not initialize { section .noinit };
|
||||
place at address mem:__ICFEDIT_region_RAM_NVIC_start__ { section .noinit };
|
||||
|
||||
keep { section .intvec };
|
||||
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
|
||||
place in ROM_region { readonly };
|
||||
place in RAM_region { readwrite,
|
||||
block HEAP,
|
||||
block CSTACK };
|
||||
|
||||
/*This is used for mbed applications build inside the Embedded workbench
|
||||
Applications build with the python scritps use a hex merge so need to merge it
|
||||
inside the linker. The linker can only use binary files so the hex merge is not possible
|
||||
through the linker. That is why a binary is used instead of a hex image for the embedded project.
|
||||
*/
|
||||
if(isdefinedsymbol(SOFT_DEVICE_BIN))
|
||||
{
|
||||
place at address mem:__code_start_soft_device__ { section .noinit_softdevice };
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
;/* Copyright (c) 2012 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
; The modules in this file are included in the libraries, and may be replaced
|
||||
; by any user-defined modules that define the PUBLIC symbol _program_start or
|
||||
; a user defined start symbol.
|
||||
; To override the cstartup defined in the library, simply add your modified
|
||||
; version to the workbench project.
|
||||
;
|
||||
; The vector table is normally located at address 0.
|
||||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
|
||||
; The name "__vector_table" has special meaning for C-SPY:
|
||||
; it is where the SP start value is found, and the NVIC vector
|
||||
; table register (VTOR) is initialized to this address if != 0.
|
||||
|
||||
|
||||
|
||||
MODULE ?cstartup
|
||||
|
||||
;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW.
|
||||
;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW.
|
||||
|
||||
;; Forward declaration of sections.
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
SECTION .intvec:CODE:NOROOT(2)
|
||||
|
||||
EXTERN __iar_program_start
|
||||
EXTERN SystemInit
|
||||
EXTERN nrf_reloc_vector_table
|
||||
PUBLIC __vector_table
|
||||
PUBLIC __Vectors
|
||||
PUBLIC __Vectors_End
|
||||
PUBLIC __Vectors_Size
|
||||
|
||||
DATA
|
||||
|
||||
__vector_table
|
||||
DCD sfe(CSTACK)
|
||||
DCD Reset_Handler
|
||||
DCD NMI_Handler
|
||||
DCD HardFault_Handler
|
||||
DCD MemoryManagement_Handler
|
||||
DCD BusFault_Handler
|
||||
DCD UsageFault_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler
|
||||
DCD DebugMonitor_Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler
|
||||
DCD SysTick_Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD POWER_CLOCK_IRQHandler
|
||||
DCD RADIO_IRQHandler
|
||||
DCD UARTE0_UART0_IRQHandler_v
|
||||
DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
DCD NFCT_IRQHandler_v
|
||||
DCD GPIOTE_IRQHandler_v
|
||||
DCD SAADC_IRQHandler_v
|
||||
DCD TIMER0_IRQHandler_v
|
||||
DCD TIMER1_IRQHandler_v
|
||||
DCD TIMER2_IRQHandler_v
|
||||
DCD RTC0_IRQHandler
|
||||
DCD TEMP_IRQHandler_v
|
||||
DCD RNG_IRQHandler
|
||||
DCD ECB_IRQHandler
|
||||
DCD CCM_AAR_IRQHandler
|
||||
DCD WDT_IRQHandler_v
|
||||
DCD RTC1_IRQHandler_v
|
||||
DCD QDEC_IRQHandler_v
|
||||
DCD COMP_LPCOMP_IRQHandler_v
|
||||
DCD SWI0_EGU0_IRQHandler_v
|
||||
DCD SWI1_EGU1_IRQHandler_v
|
||||
DCD SWI2_EGU2_IRQHandler_v
|
||||
DCD SWI3_EGU3_IRQHandler_v
|
||||
DCD SWI4_EGU4_IRQHandler
|
||||
DCD SWI5_EGU5_IRQHandler
|
||||
DCD TIMER3_IRQHandler_v
|
||||
DCD TIMER4_IRQHandler_v
|
||||
DCD PWM0_IRQHandler_v
|
||||
DCD PDM_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD MWU_IRQHandler
|
||||
DCD PWM1_IRQHandler_v
|
||||
DCD PWM2_IRQHandler_v
|
||||
DCD SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
DCD RTC2_IRQHandler_v
|
||||
DCD I2S_IRQHandler_v
|
||||
DCD FPU_IRQHandler_v
|
||||
DCD USBD_IRQHandler_v
|
||||
DCD UARTE1_IRQHandler_v
|
||||
DCD QSPI_IRQHandler_v
|
||||
DCD CRYPTOCELL_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PWM3_IRQHandler_v
|
||||
DCD 0 ; Reserved
|
||||
DCD SPIM3_IRQHandler_v
|
||||
|
||||
__Vectors_End
|
||||
__Vectors EQU __vector_table
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
|
||||
; Default handlers.
|
||||
THUMB
|
||||
|
||||
PUBWEAK Reset_Handler
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
Reset_Handler
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =nrf_reloc_vector_table
|
||||
BLX R0
|
||||
LDR R0, =__iar_program_start
|
||||
BX R0
|
||||
|
||||
; Dummy exception handlers
|
||||
|
||||
|
||||
PUBWEAK NMI_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
NMI_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK HardFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
HardFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK MemoryManagement_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
MemoryManagement_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK BusFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
BusFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK UsageFault_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
UsageFault_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SVC_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SVC_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK DebugMonitor_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
DebugMonitor_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK PendSV_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PendSV_Handler
|
||||
B .
|
||||
|
||||
PUBWEAK SysTick_Handler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SysTick_Handler
|
||||
B .
|
||||
|
||||
|
||||
; Dummy interrupt handlers
|
||||
|
||||
PUBWEAK POWER_CLOCK_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
POWER_CLOCK_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK RADIO_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RADIO_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK UARTE0_UART0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
UARTE0_UART0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK NFCT_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
NFCT_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK GPIOTE_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
GPIOTE_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SAADC_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SAADC_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC0_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC0_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK TEMP_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TEMP_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RNG_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RNG_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK ECB_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
ECB_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK CCM_AAR_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
CCM_AAR_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK WDT_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
WDT_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK QDEC_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
QDEC_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK COMP_LPCOMP_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
COMP_LPCOMP_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI0_EGU0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI0_EGU0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI1_EGU1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI1_EGU1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI2_EGU2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI2_EGU2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI3_EGU3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI3_EGU3_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SWI4_EGU4_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI4_EGU4_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK SWI5_EGU5_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SWI5_EGU5_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER3_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK TIMER4_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
TIMER4_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PWM0_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM0_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PDM_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PDM_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK MWU_IRQHandler
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
MWU_IRQHandler
|
||||
B .
|
||||
|
||||
PUBWEAK PWM1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PWM2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM2_SPIS2_SPI2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK RTC2_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
RTC2_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK I2S_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
I2S_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK FPU_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
FPU_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK USBD_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
USBD_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK UARTE1_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
UARTE1_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK QSPI_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
QSPI_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK CRYPTOCELL_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
CRYPTOCELL_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK SPIM3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
SPIM3_IRQHandler_v
|
||||
B .
|
||||
|
||||
PUBWEAK PWM3_IRQHandler_v
|
||||
SECTION .text:CODE:NOROOT(1)
|
||||
PWM3_IRQHandler_v
|
||||
B .
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* PackageLicenseDeclared: Apache-2.0
|
||||
* Copyright (c) 2016 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 MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "nrf.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/* mbed Microcontroller Library
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
extern uint32_t nrf_dispatch_vector[NVIC_NUM_VECTORS];
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
nrf_dispatch_vector[IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
return nrf_dispatch_vector[IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* mbed Microcontroller Library
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of ARM Limited nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (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 MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 48) // CORE + MCU Peripherals
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
#include "nrf.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009-2017 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
|
||||
|
||||
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.
|
||||
|
||||
NOTICE: This file has been modified by Nordic Semiconductor ASA.
|
||||
|
||||
*/
|
||||
|
||||
/* NOTE: Template files (including this one) are application specific and therefore expected to
|
||||
be copied into the application project folder prior to its use! */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
#include "system_nrf52840.h"
|
||||
#include "nrf5x_lf_clk_helper.h"
|
||||
|
||||
/*lint ++flb "Enter library region" */
|
||||
|
||||
#define __SYSTEM_CLOCK_64M (64000000UL)
|
||||
|
||||
static bool errata_36(void);
|
||||
static bool errata_66(void);
|
||||
static bool errata_98(void);
|
||||
static bool errata_103(void);
|
||||
static bool errata_115(void);
|
||||
static bool errata_120(void);
|
||||
static bool errata_136(void);
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
|
||||
#elif defined ( __ICCARM__ )
|
||||
__root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M;
|
||||
#elif defined ( __GNUC__ )
|
||||
uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M;
|
||||
#endif
|
||||
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
SystemCoreClock = __SYSTEM_CLOCK_64M;
|
||||
}
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
|
||||
Specification to see which one). */
|
||||
#if defined (ENABLE_SWO)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
|
||||
/* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
|
||||
Specification to see which ones). */
|
||||
#if defined (ENABLE_TRACE)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P0->PIN_CNF[7] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[12] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[11] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P1->PIN_CNF[9] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
|
||||
/* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_36()){
|
||||
NRF_CLOCK->EVENTS_DONE = 0;
|
||||
NRF_CLOCK->EVENTS_CTTO = 0;
|
||||
NRF_CLOCK->CTIV = 0;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_66()){
|
||||
NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
|
||||
NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
|
||||
NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
|
||||
NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
|
||||
NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
|
||||
NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
|
||||
NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
|
||||
NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
|
||||
NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
|
||||
NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
|
||||
NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
|
||||
NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
|
||||
NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
|
||||
NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
|
||||
NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
|
||||
NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
|
||||
NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_98()){
|
||||
*(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_103()){
|
||||
NRF_CCM->MAXPACKETSIZE = 0xFBul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_115()){
|
||||
*(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F);
|
||||
}
|
||||
|
||||
/* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_120()){
|
||||
*(volatile uint32_t *)0x40029640ul = 0x200ul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
|
||||
for your device located at https://infocenter.nordicsemi.com/ */
|
||||
if (errata_136()){
|
||||
if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){
|
||||
NRF_POWER->RESETREAS = ~POWER_RESETREAS_RESETPIN_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
|
||||
* compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
|
||||
* operations are not used in your code. */
|
||||
#if (__FPU_USED == 1)
|
||||
SCB->CPACR |= (3UL << 20) | (3UL << 22);
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
|
||||
/* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
|
||||
two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as
|
||||
normal GPIOs. */
|
||||
#if defined (CONFIG_NFCT_PINS_AS_GPIOS)
|
||||
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
|
||||
defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be
|
||||
reserved for PinReset and not available as normal GPIO. */
|
||||
#if defined (CONFIG_GPIO_AS_PINRESET)
|
||||
if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
|
||||
((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->PSELRESET[0] = 18;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_UICR->PSELRESET[1] = 18;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
// Start the LF oscilator according to the mbed configuration (over the nrf5x_lf_clk_helper.h file)
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_TO_USE << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
|
||||
// Wait for the external oscillator to start up.
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool errata_36(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_66(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_98(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_103(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_115(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_120(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_136(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*lint --flb "Leave library region" */
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009-2017 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
|
||||
|
||||
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.
|
||||
|
||||
NOTICE: This file has been modified by Nordic Semiconductor ASA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_NRF52840_H
|
||||
#define SYSTEM_NRF52840_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
/**
|
||||
* Update SystemCoreClock variable
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Updates the SystemCoreClock with current core Clock
|
||||
* retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_NRF52840_H */
|
|
@ -0,0 +1,21 @@
|
|||
# Folder origin
|
||||
|
||||
components/ble
|
||||
components/softdevice
|
||||
components/libraries/fstorage/nrf_fstorage_sd.*
|
||||
|
||||
# Modifications
|
||||
|
||||
Removed:
|
||||
* common/nrf_sdh_freertos.c
|
||||
* common/nrf_sdh_freertos.h
|
||||
* s212/*
|
||||
* s332/*
|
||||
|
||||
Moved:
|
||||
* s112/ to ../TARGET_SOFTDEVICE_S112
|
||||
* s132/ to ../TARGET_SOFTDEVICE_s132
|
||||
* s140/ to ../TARGET_SOFTDEVICE_s140
|
||||
|
||||
Renamed:
|
||||
* ble.h to nrf_ble.h
|
|
@ -0,0 +1,12 @@
|
|||
# Folder origin
|
||||
|
||||
components/ble
|
||||
|
||||
# Modifications
|
||||
|
||||
Removed
|
||||
* ble_services/*
|
||||
* ble_dtm/ble_dtm_hw_nrf51.c
|
||||
|
||||
Renamed
|
||||
* #include "ble.h" -> #include "nrf_ble.h"
|
|
@ -0,0 +1,695 @@
|
|||
/**
|
||||
* Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(BLE_ADVERTISING)
|
||||
#include "ble_advdata.h"
|
||||
#include "ble_advertising.h"
|
||||
#include "nrf_soc.h"
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_fstorage.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
#include "nrf_sdh_soc.h"
|
||||
|
||||
#define BLE_ADV_MODES (5) /**< Total number of possible advertising modes. */
|
||||
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
|
||||
static bool whitelist_has_entries(ble_advertising_t * const p_advertising)
|
||||
{
|
||||
return ((p_advertising->whitelist.addr_count != 0) || (p_advertising->whitelist.irk_count != 0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool whitelist_has_entries(ble_advertising_t * const p_advertising)
|
||||
{
|
||||
return p_advertising->whitelist_in_use;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**@brief Function for checking if an address is valid.
|
||||
*/
|
||||
static bool addr_is_valid(uint8_t const * const addr)
|
||||
{
|
||||
for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
|
||||
{
|
||||
if (addr[i] != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode)
|
||||
{
|
||||
return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the Connected event.
|
||||
*
|
||||
* @param[in] p_ble_evt Event received from the BLE stack.
|
||||
*/
|
||||
static void on_connected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
|
||||
{
|
||||
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
|
||||
{
|
||||
p_advertising->current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the Disconnected event.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] p_ble_evt Event received from the BLE stack.
|
||||
*/
|
||||
static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
p_advertising->whitelist_temporarily_disabled = false;
|
||||
|
||||
if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
|
||||
p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
|
||||
{
|
||||
ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED);
|
||||
if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
|
||||
{
|
||||
p_advertising->error_handler(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling the Timeout event.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] p_ble_evt Event received from the BLE stack.
|
||||
*/
|
||||
static void on_timeout(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
|
||||
{
|
||||
ret_code_t ret;
|
||||
|
||||
if (p_ble_evt->evt.gap_evt.params.timeout.src != BLE_GAP_TIMEOUT_SRC_ADVERTISING)
|
||||
{
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
// Start advertising in the next mode.
|
||||
ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));
|
||||
|
||||
if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
|
||||
{
|
||||
p_advertising->error_handler(ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Function to determine if a flash write operation in in progress.
|
||||
*
|
||||
* @return true if a flash operation is in progress, false if not.
|
||||
*/
|
||||
static bool flash_access_in_progress()
|
||||
{
|
||||
return nrf_fstorage_is_busy(NULL);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Get the next available advertising mode.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] adv_mode Requested advertising mode.
|
||||
*
|
||||
* @returns adv_mode if possible, or the best available mode if not.
|
||||
*/
|
||||
static ble_adv_mode_t adv_mode_next_avail_get(ble_advertising_t * const p_advertising,
|
||||
ble_adv_mode_t adv_mode)
|
||||
{
|
||||
bool peer_addr_is_valid = addr_is_valid(p_advertising->peer_address.addr);
|
||||
|
||||
// If a mode is disabled, continue to the next mode.
|
||||
|
||||
switch (adv_mode)
|
||||
{
|
||||
case BLE_ADV_MODE_DIRECTED:
|
||||
if ((p_advertising->adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid)
|
||||
{
|
||||
return BLE_ADV_MODE_DIRECTED;
|
||||
}
|
||||
// Fallthrough.
|
||||
|
||||
case BLE_ADV_MODE_DIRECTED_SLOW:
|
||||
if ((p_advertising->adv_modes_config.ble_adv_directed_slow_enabled) && peer_addr_is_valid)
|
||||
{
|
||||
return BLE_ADV_MODE_DIRECTED_SLOW;
|
||||
}
|
||||
// Fallthrough.
|
||||
|
||||
case BLE_ADV_MODE_FAST:
|
||||
if (p_advertising->adv_modes_config.ble_adv_fast_enabled)
|
||||
{
|
||||
return BLE_ADV_MODE_FAST;
|
||||
}
|
||||
// Fallthrough.
|
||||
|
||||
case BLE_ADV_MODE_SLOW:
|
||||
if (p_advertising->adv_modes_config.ble_adv_slow_enabled)
|
||||
{
|
||||
return BLE_ADV_MODE_SLOW;
|
||||
}
|
||||
// Fallthrough.
|
||||
|
||||
default:
|
||||
return BLE_ADV_MODE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for starting directed advertising.
|
||||
*
|
||||
* @param[in] p_advertising Advertising instance.
|
||||
* @param[out] p_adv_params Advertising parameters.
|
||||
*
|
||||
* @return NRF_SUCCESS
|
||||
*/
|
||||
static ret_code_t set_adv_mode_directed(ble_advertising_t * const p_advertising,
|
||||
ble_gap_adv_params_t * p_adv_params)
|
||||
{
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED;
|
||||
|
||||
p_adv_params->p_peer_addr = &(p_advertising->peer_address);
|
||||
p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
|
||||
p_adv_params->timeout = 0;
|
||||
p_adv_params->interval = 0;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for starting directed slow advertising.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[out] p_adv_params Advertising parameters.
|
||||
*
|
||||
* @return NRF_SUCCESS
|
||||
*/
|
||||
static ret_code_t set_adv_mode_directed_slow(ble_advertising_t * const p_advertising,
|
||||
ble_gap_adv_params_t * p_adv_params)
|
||||
{
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED_SLOW;
|
||||
|
||||
p_adv_params->p_peer_addr = &p_advertising->peer_address;
|
||||
p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
|
||||
p_adv_params->timeout = p_advertising->adv_modes_config.ble_adv_directed_slow_timeout;
|
||||
p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_directed_slow_interval;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for starting fast advertising.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[out] p_adv_params Advertising parameters.
|
||||
*
|
||||
* @return NRF_SUCCESS or an error from @ref ble_advdata_set().
|
||||
*/
|
||||
static ret_code_t set_adv_mode_fast(ble_advertising_t * const p_advertising,
|
||||
ble_gap_adv_params_t * p_adv_params)
|
||||
{
|
||||
ret_code_t ret;
|
||||
|
||||
p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
|
||||
p_adv_params->timeout = p_advertising->adv_modes_config.ble_adv_fast_timeout;
|
||||
|
||||
if ((p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
|
||||
(!p_advertising->whitelist_temporarily_disabled) &&
|
||||
(whitelist_has_entries(p_advertising)))
|
||||
{
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
p_adv_params->p_whitelist = &m_whitelist;
|
||||
#endif
|
||||
|
||||
p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
|
||||
p_advertising->advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
|
||||
|
||||
ret = ble_advdata_set(&(p_advertising->advdata), NULL);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_FAST;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for starting slow advertising.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[out] p_adv_params Advertising parameters.
|
||||
*
|
||||
* @return NRF_SUCCESS or an error from @ref ble_advdata_set().
|
||||
*/
|
||||
static ret_code_t set_adv_mode_slow(ble_advertising_t * const p_advertising,
|
||||
ble_gap_adv_params_t * p_adv_params)
|
||||
{
|
||||
ret_code_t ret;
|
||||
|
||||
p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_slow_interval;
|
||||
p_adv_params->timeout = p_advertising->adv_modes_config.ble_adv_slow_timeout;
|
||||
|
||||
if ((p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
|
||||
(!p_advertising->whitelist_temporarily_disabled) &&
|
||||
(whitelist_has_entries(p_advertising)))
|
||||
{
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
{
|
||||
p_adv_params->p_whitelist = &p_advertising->whitelist;
|
||||
}
|
||||
#endif
|
||||
|
||||
p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
|
||||
p_advertising->advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
|
||||
|
||||
ret = ble_advdata_set(&(p_advertising->advdata), NULL);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_SLOW;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising,
|
||||
uint8_t ble_cfg_tag)
|
||||
{
|
||||
p_advertising->conn_cfg_tag = ble_cfg_tag;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
|
||||
ble_advertising_init_t const * const p_init)
|
||||
{
|
||||
uint32_t ret;
|
||||
if ((p_init == NULL) || (p_advertising == NULL))
|
||||
{
|
||||
return NRF_ERROR_NULL;
|
||||
}
|
||||
|
||||
p_advertising->initialized = true;
|
||||
p_advertising->adv_mode_current = BLE_ADV_MODE_IDLE;
|
||||
p_advertising->adv_modes_config = p_init->config;
|
||||
p_advertising->conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT;
|
||||
p_advertising->evt_handler = p_init->evt_handler;
|
||||
p_advertising->error_handler = p_init->error_handler;
|
||||
p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
|
||||
memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
|
||||
memset(&p_advertising->advdata, 0, sizeof(p_advertising->advdata));
|
||||
|
||||
// Copy advertising data.
|
||||
p_advertising->advdata.name_type = p_init->advdata.name_type;
|
||||
p_advertising->advdata.include_appearance = p_init->advdata.include_appearance;
|
||||
p_advertising->advdata.flags = p_init->advdata.flags;
|
||||
p_advertising->advdata.short_name_len = p_init->advdata.short_name_len;
|
||||
|
||||
p_advertising->advdata.uuids_complete = p_init->advdata.uuids_complete;
|
||||
p_advertising->advdata.uuids_more_available = p_init->advdata.uuids_more_available;
|
||||
p_advertising->advdata.uuids_solicited = p_init->advdata.uuids_solicited;
|
||||
p_advertising->advdata.include_ble_device_addr = p_init->advdata.include_ble_device_addr;
|
||||
|
||||
if (p_init->advdata.p_manuf_specific_data != NULL)
|
||||
{
|
||||
p_advertising->advdata.p_manuf_specific_data = &(p_advertising->manuf_specific_data);
|
||||
p_advertising->manuf_specific_data.data.p_data = p_advertising->manuf_data_array;
|
||||
p_advertising->advdata.p_manuf_specific_data->company_identifier =
|
||||
p_init->advdata.p_manuf_specific_data->company_identifier;
|
||||
p_advertising->advdata.p_manuf_specific_data->data.size = p_init->advdata.p_manuf_specific_data->data.size;
|
||||
|
||||
for (uint32_t i = 0; i < p_advertising->advdata.p_manuf_specific_data->data.size; i++)
|
||||
{
|
||||
p_advertising->manuf_data_array[i] = p_init->advdata.p_manuf_specific_data->data.p_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (p_init->advdata.p_service_data_array != NULL)
|
||||
{
|
||||
p_advertising->service_data.data.p_data = p_advertising->service_data_array;
|
||||
p_advertising->advdata.p_service_data_array = &(p_advertising->service_data);
|
||||
p_advertising->advdata.p_service_data_array->data.p_data = p_advertising->service_data_array;
|
||||
p_advertising->advdata.p_service_data_array->data.size = p_init->advdata.p_service_data_array->data.size;
|
||||
p_advertising->advdata.p_service_data_array->service_uuid = p_init->advdata.p_service_data_array->service_uuid;
|
||||
|
||||
for (uint32_t i = 0; i < p_advertising->advdata.p_service_data_array->data.size; i++)
|
||||
{
|
||||
p_advertising->service_data_array[i] = p_init->advdata.p_service_data_array->data.p_data[i];
|
||||
}
|
||||
|
||||
p_advertising->advdata.service_data_count = p_init->advdata.service_data_count;
|
||||
}
|
||||
|
||||
if (p_init->advdata.p_slave_conn_int != NULL)
|
||||
{
|
||||
p_advertising->advdata.p_slave_conn_int = &(p_advertising->slave_conn_int);
|
||||
p_advertising->advdata.p_slave_conn_int->max_conn_interval = p_init->advdata.p_slave_conn_int->max_conn_interval;
|
||||
p_advertising->advdata.p_slave_conn_int->min_conn_interval = p_init->advdata.p_slave_conn_int->min_conn_interval;
|
||||
}
|
||||
|
||||
if (p_init->advdata.p_tx_power_level != NULL)
|
||||
{
|
||||
p_advertising->advdata.p_tx_power_level = p_init->advdata.p_tx_power_level;
|
||||
}
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
for (int i = 0; i <BLE_GAP_WHITELIST_ADDR_MAX_COUNT ; i++)
|
||||
{
|
||||
p_advertising->whitelist.pp_addrs[i] = &p_advertising->whitelist_addrs[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i <BLE_GAP_WHITELIST_IRK_MAX_COUNT ; i++)
|
||||
{
|
||||
p_advertising->whitelist.pp_irks[i] = &p_advertising->whitelist_irks[i];
|
||||
}
|
||||
#endif
|
||||
ret = ble_advdata_set(&(p_advertising->advdata), &(p_init->srdata));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
|
||||
ble_adv_mode_t advertising_mode)
|
||||
{
|
||||
uint32_t ret;
|
||||
ble_gap_adv_params_t adv_params;
|
||||
|
||||
if (p_advertising->initialized == false)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
p_advertising->adv_mode_current = advertising_mode;
|
||||
|
||||
// Delay starting advertising until the flash operations are complete.
|
||||
if (flash_access_in_progress())
|
||||
{
|
||||
p_advertising->advertising_start_pending = true;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
|
||||
|
||||
if ( ((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
|
||||
||((p_advertising->adv_modes_config.ble_adv_directed_slow_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
|
||||
||((p_advertising->adv_modes_config.ble_adv_directed_slow_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW))
|
||||
)
|
||||
{
|
||||
if (p_advertising->evt_handler != NULL)
|
||||
{
|
||||
p_advertising->peer_addr_reply_expected = true;
|
||||
p_advertising->evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_advertising->peer_addr_reply_expected = false;
|
||||
}
|
||||
}
|
||||
|
||||
p_advertising->adv_mode_current = adv_mode_next_avail_get(p_advertising, advertising_mode);
|
||||
|
||||
// Fetch the whitelist.
|
||||
if ((p_advertising->evt_handler != NULL) &&
|
||||
(p_advertising->adv_mode_current == BLE_ADV_MODE_FAST || p_advertising->adv_mode_current == BLE_ADV_MODE_SLOW) &&
|
||||
(p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
|
||||
(!p_advertising->whitelist_temporarily_disabled))
|
||||
{
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
p_advertising->whitelist_in_use = false;
|
||||
#endif
|
||||
p_advertising->whitelist_reply_expected = true;
|
||||
p_advertising->evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_advertising->whitelist_reply_expected = false;
|
||||
}
|
||||
|
||||
// Initialize advertising parameters with default values.
|
||||
memset(&adv_params, 0, sizeof(adv_params));
|
||||
|
||||
adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
|
||||
adv_params.fp = BLE_GAP_ADV_FP_ANY;
|
||||
|
||||
// Set advertising parameters and events according to selected advertising mode.
|
||||
switch (p_advertising->adv_mode_current)
|
||||
{
|
||||
case BLE_ADV_MODE_DIRECTED:
|
||||
ret = set_adv_mode_directed(p_advertising, &adv_params);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_DIRECTED_SLOW:
|
||||
ret = set_adv_mode_directed_slow(p_advertising, &adv_params);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_FAST:
|
||||
ret = set_adv_mode_fast(p_advertising, &adv_params);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_SLOW:
|
||||
ret = set_adv_mode_slow(p_advertising, &adv_params);
|
||||
break;
|
||||
|
||||
case BLE_ADV_MODE_IDLE:
|
||||
p_advertising->adv_evt = BLE_ADV_EVT_IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
|
||||
{
|
||||
ret = sd_ble_gap_adv_start(&adv_params, p_advertising->conn_cfg_tag);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_advertising->evt_handler != NULL)
|
||||
{
|
||||
p_advertising->evt_handler(p_advertising->adv_evt);
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
|
||||
{
|
||||
ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
|
||||
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
on_connected(p_advertising, p_ble_evt);
|
||||
break;
|
||||
|
||||
// Upon disconnection, whitelist will be activated and direct advertising is started.
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
on_disconnected(p_advertising, p_ble_evt);
|
||||
break;
|
||||
|
||||
// Upon time-out, the next advertising mode is started.
|
||||
case BLE_GAP_EVT_TIMEOUT:
|
||||
on_timeout(p_advertising, p_ble_evt);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ble_advertising_on_sys_evt(uint32_t evt_id, void * p_context)
|
||||
{
|
||||
ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
|
||||
|
||||
switch (evt_id)
|
||||
{
|
||||
//When a flash operation finishes, re-attempt to start advertising operations.
|
||||
case NRF_EVT_FLASH_OPERATION_SUCCESS:
|
||||
case NRF_EVT_FLASH_OPERATION_ERROR:
|
||||
{
|
||||
if (p_advertising->advertising_start_pending)
|
||||
{
|
||||
p_advertising->advertising_start_pending = false;
|
||||
ret_code_t ret = ble_advertising_start(p_advertising,
|
||||
p_advertising->adv_mode_current);
|
||||
|
||||
if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
|
||||
{
|
||||
p_advertising->error_handler(ret);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
|
||||
ble_gap_addr_t * p_peer_address)
|
||||
{
|
||||
if (!p_advertising->peer_addr_reply_expected)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
p_advertising->peer_addr_reply_expected = false;
|
||||
|
||||
memcpy(&p_advertising->peer_address, p_peer_address, sizeof(p_advertising->peer_address));
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
|
||||
ble_gap_addr_t const * p_gap_addrs,
|
||||
uint32_t addr_cnt,
|
||||
ble_gap_irk_t const * p_gap_irks,
|
||||
uint32_t irk_cnt)
|
||||
{
|
||||
if (!p_advertising->whitelist_reply_expected)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
p_advertising->whitelist_reply_expected = false;
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
|
||||
p_advertising->whitelist.addr_count = addr_cnt;
|
||||
p_advertising->whitelist.irk_count = irk_cnt;
|
||||
|
||||
for (uint32_t i = 0; i < addr_cnt; i++)
|
||||
{
|
||||
*p_advertising->whitelist.pp_addrs[i] = p_gap_addrs[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < irk_cnt; i++)
|
||||
{
|
||||
*p_advertising->whitelist.pp_irks[i] = p_gap_irks[i];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
p_advertising->whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0));
|
||||
|
||||
#endif
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
(void) sd_ble_gap_adv_stop();
|
||||
|
||||
p_advertising->whitelist_temporarily_disabled = true;
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
p_advertising->whitelist_in_use = false;
|
||||
#endif
|
||||
|
||||
p_advertising->advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
||||
|
||||
ret = ble_advdata_set(&(p_advertising->advdata), NULL);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ble_advertising_start(p_advertising, p_advertising->adv_mode_current);
|
||||
if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
|
||||
{
|
||||
p_advertising->error_handler(ret);
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
|
||||
ble_adv_modes_config_t const * const p_adv_modes_config)
|
||||
{
|
||||
p_advertising->adv_modes_config = *p_adv_modes_config;
|
||||
}
|
||||
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(BLE_ADVERTISING)
|
|
@ -0,0 +1,355 @@
|
|||
/**
|
||||
* Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ble_advertising Advertising Module
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Module for handling connectable BLE advertising.
|
||||
*
|
||||
* @details The Advertising Module handles connectable advertising for your application. It can
|
||||
* be configured with advertising modes to suit most typical use cases.
|
||||
* Your main application can react to changes in advertising modes
|
||||
* if an event handler is provided.
|
||||
*
|
||||
* @note The Advertising Module supports only applications with a single peripheral link.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BLE_ADVERTISING_H__
|
||||
#define BLE_ADVERTISING_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_ble.h"
|
||||
#include "ble_gattc.h"
|
||||
#include "ble_advdata.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Macro for defining a ble_advertising instance.
|
||||
*
|
||||
* @param _name Name of the instance.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define BLE_ADVERTISING_DEF(_name) \
|
||||
static ble_advertising_t _name; \
|
||||
NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
|
||||
BLE_ADV_BLE_OBSERVER_PRIO, \
|
||||
ble_advertising_on_ble_evt, &_name); \
|
||||
NRF_SDH_SOC_OBSERVER(_name ## _soc_obs, \
|
||||
BLE_ADV_SOC_OBSERVER_PRIO, \
|
||||
ble_advertising_on_sys_evt, &_name)
|
||||
|
||||
|
||||
/**@brief Advertising modes. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing. */
|
||||
BLE_ADV_MODE_DIRECTED, /**< Directed advertising attempts to connect to the most recently disconnected peer. */
|
||||
BLE_ADV_MODE_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */
|
||||
BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */
|
||||
BLE_ADV_MODE_SLOW, /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */
|
||||
} ble_adv_mode_t;
|
||||
|
||||
/**@brief Advertising events.
|
||||
*
|
||||
* @details These events are propagated to the main application if a handler was provided during
|
||||
* initialization of the Advertising Module. Events for modes that are not used can be
|
||||
* ignored. Similarly, BLE_ADV_EVT_WHITELIST_REQUEST and BLE_ADV_EVT_PEER_ADDR_REQUEST
|
||||
* can be ignored if whitelist and direct advertising is not used.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
BLE_ADV_EVT_IDLE, /**< Idle; no connectable advertising is ongoing.*/
|
||||
BLE_ADV_EVT_DIRECTED, /**< Direct advertising mode has started. */
|
||||
BLE_ADV_EVT_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) has started. */
|
||||
BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */
|
||||
BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started. */
|
||||
BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */
|
||||
BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started. */
|
||||
BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */
|
||||
BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */
|
||||
} ble_adv_evt_t;
|
||||
|
||||
/**@brief Options for the different advertisement modes.
|
||||
*
|
||||
* @details This structure is used to enable or disable advertising modes and to configure time-out
|
||||
* periods and advertising intervals.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
bool ble_adv_on_disconnect_disabled; /**< Enable or disable automatic return to advertising upon disconnecting.*/
|
||||
bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
|
||||
bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
|
||||
bool ble_adv_directed_slow_enabled; /**< Enable or disable direct advertising mode. */
|
||||
bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
|
||||
bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
|
||||
uint32_t ble_adv_directed_slow_interval; /**< Advertising interval for directed advertising. */
|
||||
uint32_t ble_adv_directed_slow_timeout; /**< Time-out (number of tries) for direct advertising. */
|
||||
uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
|
||||
uint32_t ble_adv_fast_timeout; /**< Time-out (in seconds) for fast advertising. */
|
||||
uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
|
||||
uint32_t ble_adv_slow_timeout; /**< Time-out (in seconds) for slow advertising. */
|
||||
} ble_adv_modes_config_t;
|
||||
|
||||
/**@brief BLE advertising event handler type. */
|
||||
typedef void (*ble_adv_evt_handler_t) (ble_adv_evt_t const adv_evt);
|
||||
|
||||
/**@brief BLE advertising error handler type. */
|
||||
typedef void (*ble_adv_error_handler_t) (uint32_t nrf_error);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool initialized;
|
||||
bool advertising_start_pending; /**< Flag to keep track of ongoing operations in flash. */
|
||||
|
||||
ble_adv_evt_t adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address. */
|
||||
|
||||
ble_adv_mode_t adv_mode_current; /**< Variable to keep track of the current advertising mode. */
|
||||
ble_adv_modes_config_t adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/
|
||||
uint8_t conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if the advertising results in a connection. */
|
||||
|
||||
ble_gap_addr_t peer_address; /**< Address of the most recently connected peer, used for direct advertising. */
|
||||
bool peer_addr_reply_expected; /**< Flag to verify that peer address is only set when requested. */
|
||||
|
||||
ble_advdata_t advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */
|
||||
ble_advdata_manuf_data_t manuf_specific_data; /**< Manufacturer specific data structure*/
|
||||
uint8_t manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/
|
||||
ble_advdata_service_data_t service_data; /**< Service data structure. */
|
||||
uint8_t service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */
|
||||
ble_advdata_conn_int_t slave_conn_int; /**< Connection interval range structure.*/
|
||||
uint16_t current_slave_link_conn_handle; /**< Connection handle for the active link. */
|
||||
|
||||
ble_adv_evt_handler_t evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */
|
||||
ble_adv_error_handler_t error_handler; /**< Handler for the advertising error events. */
|
||||
|
||||
bool whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */
|
||||
bool whitelist_reply_expected;
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
// For SoftDevices v 2.x, this module caches a whitelist which is retrieved from the
|
||||
// application using an event, and which is passed as a parameter when calling
|
||||
// sd_ble_gap_adv_start().
|
||||
ble_gap_addr_t * p_whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
||||
ble_gap_irk_t * p_whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
|
||||
ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
||||
ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
|
||||
|
||||
ble_gap_whitelist_t m_whitelist =
|
||||
{
|
||||
.pp_addrs = p_whitelist_addrs,
|
||||
.pp_irks = p_whitelist_irks
|
||||
};
|
||||
#else
|
||||
// For SoftDevices v 3.x, this module does not need to cache a whitelist, but it needs to
|
||||
// be aware of whether or not a whitelist has been set (e.g. using the Peer Manager)
|
||||
// in order to start advertising with the proper advertising params (filter policy).
|
||||
bool whitelist_in_use;
|
||||
#endif
|
||||
} ble_advertising_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t interval;
|
||||
uint32_t timeout;
|
||||
bool enabled;
|
||||
} ble_adv_mode_config_t;
|
||||
|
||||
/**@brief Initialization parameters for the Advertising Module.
|
||||
* @details This structure is used to pass advertising options, advertising data,
|
||||
* and an event handler to the Advertising Module during initialization.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ble_advdata_t advdata; /**< Advertising data: name, appearance, discovery flags, and more. */
|
||||
ble_advdata_t srdata; /**< Scan response data: Supplement to advertising data. */
|
||||
ble_adv_modes_config_t config; /**< Select which advertising modes and intervals will be utilized.*/
|
||||
ble_adv_evt_handler_t evt_handler; /**< Event handler that will be called upon advertising events. */
|
||||
ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
|
||||
} ble_advertising_init_t;
|
||||
|
||||
|
||||
/**@brief Function for handling BLE events.
|
||||
*
|
||||
* @details This function must be called from the BLE stack event dispatcher for
|
||||
* the module to handle BLE events that are relevant for the Advertising Module.
|
||||
*
|
||||
* @param[in] p_ble_evt BLE stack event.
|
||||
* @param[in] p_adv Advertising module instance.
|
||||
*/
|
||||
void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_adv);
|
||||
|
||||
|
||||
/**@brief Function for handling system events.
|
||||
*
|
||||
* @details This function must be called to handle system events that are relevant
|
||||
* for the Advertising Module. Specifically, the advertising module can not use the
|
||||
* softdevice as long as there are pending writes to the flash memory. This
|
||||
* event handler is designed to delay advertising until there is no flash operation.
|
||||
*
|
||||
* @param[in] sys_evt System event.
|
||||
* @param[in] p_adv Advertising module instance.
|
||||
*/
|
||||
void ble_advertising_on_sys_evt(uint32_t sys_evt, void * p_adv);
|
||||
|
||||
|
||||
/**@brief Function for initializing the Advertising Module.
|
||||
*
|
||||
* @details Encodes the required advertising data and passes it to the stack.
|
||||
* Also builds a structure to be passed to the stack when starting advertising.
|
||||
* The supplied advertising data is copied to a local structure and is manipulated
|
||||
* depending on what advertising modes are started in @ref ble_advertising_start.
|
||||
*
|
||||
* @param[out] p_advertising Advertising module instance. This structure must be supplied by
|
||||
* the application. It is initialized by this function and will later
|
||||
* be used to identify this particular module instance.
|
||||
* @param[in] p_init Information needed to initialize the module.
|
||||
*
|
||||
* @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
|
||||
*/
|
||||
uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
|
||||
ble_advertising_init_t const * const p_init);
|
||||
|
||||
|
||||
/**@brief Function for changing the connection settings tag that will be used for upcoming connections.
|
||||
*
|
||||
* @details See @ref sd_ble_cfg_set for more details about changing connection settings. If this
|
||||
* function is never called, @ref BLE_CONN_CFG_TAG_DEFAULT will be used.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] ble_cfg_tag Configuration for the connection settings (see @ref sd_ble_cfg_set).
|
||||
*/
|
||||
void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising, uint8_t ble_cfg_tag);
|
||||
|
||||
/**@brief Function for starting advertising.
|
||||
*
|
||||
* @details You can start advertising in any of the advertising modes that you enabled
|
||||
* during initialization.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] advertising_mode Advertising mode.
|
||||
*
|
||||
* @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure.
|
||||
* @retval @ref NRF_ERROR_INVALID_STATE If the module is not initialized.
|
||||
*/
|
||||
uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
|
||||
ble_adv_mode_t advertising_mode);
|
||||
|
||||
|
||||
/**@brief Function for setting the peer address.
|
||||
*
|
||||
* @details The peer address must be set by the application upon receiving a
|
||||
* @ref BLE_ADV_EVT_PEER_ADDR_REQUEST event. Without the peer address, the directed
|
||||
* advertising mode will not be run.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] p_peer_addr Pointer to a peer address.
|
||||
*
|
||||
* @retval @ref NRF_SUCCESS Successfully stored the peer address pointer in the advertising module.
|
||||
* @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected.
|
||||
*/
|
||||
uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
|
||||
ble_gap_addr_t * p_peer_addr);
|
||||
|
||||
|
||||
/**@brief Function for setting a whitelist.
|
||||
*
|
||||
* @details The whitelist must be set by the application upon receiving a
|
||||
* @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist
|
||||
* advertising for fast and slow modes will not be run.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] p_gap_addrs The list of GAP addresses to whitelist.
|
||||
* @param[in] addr_cnt The number of GAP addresses to whitelist.
|
||||
* @param[in] p_gap_irks The list of peer IRK to whitelist.
|
||||
* @param[in] irk_cnt The number of peer IRK to whitelist.
|
||||
*
|
||||
* @retval @ref NRF_SUCCESS If the operation was successful.
|
||||
* @retval @ref NRF_ERROR_INVALID_STATE If a call to this function was made without a
|
||||
* BLE_ADV_EVT_WHITELIST_REQUEST event being received.
|
||||
*/
|
||||
uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
|
||||
ble_gap_addr_t const * p_gap_addrs,
|
||||
uint32_t addr_cnt,
|
||||
ble_gap_irk_t const * p_gap_irks,
|
||||
uint32_t irk_cnt);
|
||||
|
||||
|
||||
/**@brief Function for disabling whitelist advertising.
|
||||
*
|
||||
* @details This function temporarily disables whitelist advertising.
|
||||
* Calling this function resets the current time-out countdown.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
*
|
||||
* @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice.
|
||||
*/
|
||||
uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising);
|
||||
|
||||
|
||||
/**@brief Function for changing advertising modes configuration.
|
||||
*
|
||||
* @details This function can be called if you wish to reconfigure the advertising modes that the
|
||||
* advertising module will cycle through. Enable or disable modes as listed in
|
||||
* @ref ble_adv_mode_t; or change the duration of the advertising and use of whitelist.
|
||||
*
|
||||
* Keep in mind that @ref ble_adv_modes_config_t is also supplied when calling
|
||||
* @ref ble_advertising_init. Calling @ref ble_advertising_modes_config_set
|
||||
* is only necessary if your application requires this behaviour to change.
|
||||
*
|
||||
* @param[in] p_advertising Advertising module instance.
|
||||
* @param[in] p_adv_modes_config Struct to keep track of disabled and enabled advertising modes,
|
||||
* as well as time-outs and intervals.
|
||||
*/
|
||||
void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
|
||||
ble_adv_modes_config_t const * const p_adv_modes_config);
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_ADVERTISING_H__
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,986 @@
|
|||
/**
|
||||
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sdk_common.h"
|
||||
|
||||
#if NRF_MODULE_ENABLED(BLE_DB_DISCOVERY)
|
||||
#include "ble_db_discovery.h"
|
||||
#include <stdlib.h>
|
||||
#include "ble_srv_common.h"
|
||||
#define NRF_LOG_MODULE_NAME ble_db_disc
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */
|
||||
#define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */
|
||||
#define MODULE_INITIALIZED (m_initialized == true) /**< Macro designating whether the module has been initialized properly. */
|
||||
|
||||
|
||||
/**@brief Array of structures containing information about the registered application modules. */
|
||||
static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS];
|
||||
|
||||
|
||||
/**@brief Array of structures containing pending events to be sent to the application modules.
|
||||
*
|
||||
* @details Whenever a discovery related event is to be raised to a user module, it will be stored
|
||||
* in this array first. When all services needed to be discovered have been
|
||||
* discovered, all pending events will be sent to the corresponding user modules.
|
||||
**/
|
||||
static struct
|
||||
{
|
||||
ble_db_discovery_evt_t evt; /**< The pending event. */
|
||||
ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */
|
||||
} m_pending_user_evts[DB_DISCOVERY_MAX_USERS];
|
||||
|
||||
static ble_db_discovery_evt_handler_t m_evt_handler;
|
||||
static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */
|
||||
static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */
|
||||
static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */
|
||||
|
||||
/**@brief Function for fetching the event handler provided by a registered application module.
|
||||
*
|
||||
* @param[in] srv_uuid UUID of the service.
|
||||
*
|
||||
* @retval evt_handler Event handler of the module, registered for the given service UUID.
|
||||
* @retval NULL If no event handler is found.
|
||||
*/
|
||||
static ble_db_discovery_evt_handler_t registered_handler_get(ble_uuid_t const * p_srv_uuid)
|
||||
{
|
||||
for (uint32_t i = 0; i < m_num_of_handlers_reg; i++)
|
||||
{
|
||||
if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid))
|
||||
{
|
||||
return (m_evt_handler);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for storing the event handler provided by a registered application module.
|
||||
*
|
||||
* @param[in] p_srv_uuid The UUID of the service.
|
||||
* @param[in] p_evt_handler The event handler provided by the application.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the handler was stored or already present in the list.
|
||||
* @retval NRF_ERROR_NO_MEM If there is no space left to store the handler.
|
||||
*/
|
||||
static uint32_t registered_handler_set(ble_uuid_t const * p_srv_uuid,
|
||||
ble_db_discovery_evt_handler_t p_evt_handler)
|
||||
{
|
||||
if (registered_handler_get(p_srv_uuid) != NULL)
|
||||
{
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS)
|
||||
{
|
||||
m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid;
|
||||
m_num_of_handlers_reg++;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for sending all pending discovery events to the corresponding user modules.
|
||||
*/
|
||||
static void pending_user_evts_send(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < m_num_of_handlers_reg; i++)
|
||||
{
|
||||
// Pass the event to the corresponding event handler.
|
||||
m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt));
|
||||
}
|
||||
|
||||
m_pending_usr_evt_index = 0;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for indicating error to the application.
|
||||
*
|
||||
* @details This function will fetch the event handler based on the UUID of the service being
|
||||
* discovered. (The event handler is registered by the application beforehand).
|
||||
* The error code is added to the pending events together with the event handler.
|
||||
* If no event handler was found, then this function will do nothing.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB discovery structure.
|
||||
* @param[in] err_code Error code that should be provided to the application.
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
*
|
||||
*/
|
||||
static void discovery_error_evt_trigger(ble_db_discovery_t * p_db_discovery,
|
||||
uint32_t err_code,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
ble_db_discovery_evt_handler_t p_evt_handler;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
|
||||
|
||||
if (p_evt_handler != NULL)
|
||||
{
|
||||
ble_db_discovery_evt_t evt =
|
||||
{
|
||||
.conn_handle = conn_handle,
|
||||
.evt_type = BLE_DB_DISCOVERY_ERROR,
|
||||
.params.err_code = err_code,
|
||||
};
|
||||
|
||||
p_evt_handler(&evt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for triggering a Discovery Complete or Service Not Found event to the
|
||||
* application.
|
||||
*
|
||||
* @details This function will fetch the event handler based on the UUID of the service being
|
||||
* discovered. (The event handler is registered by the application beforehand).
|
||||
* It then triggers an event indicating the completion of the service discovery.
|
||||
* If no event handler was found, then this function will do nothing.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB discovery structure.
|
||||
* @param[in] is_srv_found Variable to indicate if the service was found at the peer.
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
*/
|
||||
static void discovery_complete_evt_trigger(ble_db_discovery_t * p_db_discovery,
|
||||
bool is_srv_found,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
ble_db_discovery_evt_handler_t p_evt_handler;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
|
||||
|
||||
if (p_evt_handler != NULL)
|
||||
{
|
||||
if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS)
|
||||
{
|
||||
// Insert an event into the pending event list.
|
||||
m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle;
|
||||
m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db =
|
||||
*p_srv_being_discovered;
|
||||
|
||||
if (is_srv_found)
|
||||
{
|
||||
m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
|
||||
BLE_DB_DISCOVERY_COMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
|
||||
BLE_DB_DISCOVERY_SRV_NOT_FOUND;
|
||||
}
|
||||
|
||||
m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler;
|
||||
m_pending_usr_evt_index++;
|
||||
|
||||
if (m_pending_usr_evt_index == m_num_of_handlers_reg)
|
||||
{
|
||||
// All registered modules have pending events. Send all pending events to the user
|
||||
// modules.
|
||||
pending_user_evts_send();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too many events pending. Do nothing. (Ideally this should not happen.)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling service discovery completion.
|
||||
*
|
||||
* @details This function will be used to determine if there are more services to be discovered,
|
||||
* and if so, initiate the discovery of the next service.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery Structure.
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
*/
|
||||
static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
p_db_discovery->discoveries_count++;
|
||||
|
||||
// Check if more services need to be discovered.
|
||||
if (p_db_discovery->discoveries_count < m_num_of_handlers_reg)
|
||||
{
|
||||
// Reset the current characteristic index since a new service discovery is about to start.
|
||||
p_db_discovery->curr_char_ind = 0;
|
||||
|
||||
// Initiate discovery of the next service.
|
||||
p_db_discovery->curr_srv_ind++;
|
||||
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
|
||||
|
||||
// Reset the characteristic count in the current service to zero since a new service
|
||||
// discovery is about to start.
|
||||
p_srv_being_discovered->char_count = 0;
|
||||
|
||||
NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.",
|
||||
p_srv_being_discovered->srv_uuid.uuid, conn_handle);
|
||||
|
||||
uint32_t err_code;
|
||||
|
||||
err_code = sd_ble_gattc_primary_services_discover(conn_handle,
|
||||
SRV_DISC_START_HANDLE,
|
||||
&(p_srv_being_discovered->srv_uuid));
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
|
||||
// Error with discovering the service.
|
||||
// Indicate the error to the registered user application.
|
||||
discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle);
|
||||
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = conn_handle;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more service discovery is needed.
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = conn_handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for finding out if a characteristic discovery should be performed after the
|
||||
* last discovered characteristic.
|
||||
*
|
||||
* @details This function is used during the time of database discovery to find out if there is
|
||||
* a need to do more characteristic discoveries. The value handles of the
|
||||
* last discovered characteristic is compared with the end handle of the service.
|
||||
* If the service handle is greater than one of the former characteristic handles,
|
||||
* it means that a characteristic discovery is required.
|
||||
*
|
||||
* @param[in] p_db_discovery The pointer to the DB Discovery structure.
|
||||
* @param[in] p_after_char The pointer to the last discovered characteristic.
|
||||
*
|
||||
* @retval True if a characteristic discovery is required.
|
||||
* @retval False if a characteristic discovery is NOT required.
|
||||
*/
|
||||
static bool is_char_discovery_reqd(ble_db_discovery_t * p_db_discovery,
|
||||
ble_gattc_char_t * p_after_char)
|
||||
{
|
||||
if (p_after_char->handle_value <
|
||||
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle)
|
||||
{
|
||||
// Handle value of the characteristic being discovered is less than the end handle of
|
||||
// the service being discovered. There is a possibility of more characteristics being
|
||||
// present. Hence a characteristic discovery is required.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function to find out if a descriptor discovery is required.
|
||||
*
|
||||
* @details This function finds out if there is a possibility of existence of descriptors between
|
||||
* current characteristic and the next characteristic. If so, this function will compute
|
||||
* the handle range on which the descriptors may be present and will return it.
|
||||
* If the current characteristic is the last known characteristic, then this function
|
||||
* will use the service end handle to find out if the current characteristic can have
|
||||
* descriptors.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] p_curr_char Pointer to the current characteristic.
|
||||
* @param[in] p_next_char Pointer to the next characteristic. This should be NULL if the
|
||||
* caller knows that there is no characteristic after the current
|
||||
* characteristic at the peer.
|
||||
* @param[out] p_handle_range Pointer to the handle range in which descriptors may exist at the
|
||||
* the peer.
|
||||
*
|
||||
* @retval True If a descriptor discovery is required.
|
||||
* @retval False If a descriptor discovery is NOT required.
|
||||
*/
|
||||
static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery,
|
||||
ble_gatt_db_char_t * p_curr_char,
|
||||
ble_gatt_db_char_t * p_next_char,
|
||||
ble_gattc_handle_range_t * p_handle_range)
|
||||
{
|
||||
if (p_next_char == NULL)
|
||||
{
|
||||
// Current characteristic is the last characteristic in the service. Check if the value
|
||||
// handle of the current characteristic is equal to the service end handle.
|
||||
if (
|
||||
p_curr_char->characteristic.handle_value ==
|
||||
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle
|
||||
)
|
||||
{
|
||||
// No descriptors can be present for the current characteristic. p_curr_char is the last
|
||||
// characteristic with no descriptors.
|
||||
return false;
|
||||
}
|
||||
|
||||
p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
|
||||
|
||||
// Since the current characteristic is the last characteristic in the service, the end
|
||||
// handle should be the end handle of the service.
|
||||
p_handle_range->end_handle =
|
||||
p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// p_next_char != NULL. Check for existence of descriptors between the current and the next
|
||||
// characteristic.
|
||||
if ((p_curr_char->characteristic.handle_value + 1) == p_next_char->characteristic.handle_decl)
|
||||
{
|
||||
// No descriptors can exist between the two characteristic.
|
||||
return false;
|
||||
}
|
||||
|
||||
p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
|
||||
p_handle_range->end_handle = p_next_char->characteristic.handle_decl - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for performing characteristic discovery.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
*
|
||||
* @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic
|
||||
* discovery. Otherwise an error code. This function returns the error code returned
|
||||
* by the SoftDevice API @ref sd_ble_gattc_characteristics_discover.
|
||||
*/
|
||||
static uint32_t characteristics_discover(ble_db_discovery_t * p_db_discovery,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
ble_gattc_handle_range_t handle_range;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
if (p_db_discovery->curr_char_ind != 0)
|
||||
{
|
||||
// This is not the first characteristic being discovered. Hence the 'start handle' to be
|
||||
// used must be computed using the handle_value of the previous characteristic.
|
||||
ble_gattc_char_t * p_prev_char;
|
||||
uint8_t prev_char_ind = p_db_discovery->curr_char_ind - 1;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_prev_char = &(p_srv_being_discovered->charateristics[prev_char_ind].characteristic);
|
||||
|
||||
handle_range.start_handle = p_prev_char->handle_value + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the first characteristic of this service being discovered.
|
||||
handle_range.start_handle = p_srv_being_discovered->handle_range.start_handle;
|
||||
}
|
||||
|
||||
handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle;
|
||||
|
||||
return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for performing descriptor discovery, if required.
|
||||
*
|
||||
* @details This function will check if descriptor discovery is required and then perform it if
|
||||
* needed. If no more descriptor discovery is required for the service, then the output
|
||||
* parameter p_raise_discov_complete is set to true, indicating to the caller that a
|
||||
* discovery complete event can be triggered to the application.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if
|
||||
* the Discovery Complete event can be triggered to the
|
||||
* application.
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
*
|
||||
* @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor
|
||||
* discovery, or if no more descriptor discovery is required. Otherwise an error code.
|
||||
* This function returns the error code returned by the SoftDevice API @ref
|
||||
* sd_ble_gattc_descriptors_discover.
|
||||
*/
|
||||
static uint32_t descriptors_discover(ble_db_discovery_t * p_db_discovery,
|
||||
bool * p_raise_discov_complete,
|
||||
uint16_t conn_handle)
|
||||
{
|
||||
ble_gattc_handle_range_t handle_range;
|
||||
ble_gatt_db_char_t * p_curr_char_being_discovered;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
bool is_discovery_reqd = false;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_curr_char_being_discovered =
|
||||
&(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
|
||||
|
||||
if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
|
||||
{
|
||||
// This is the last characteristic of this service.
|
||||
is_discovery_reqd = is_desc_discovery_reqd(p_db_discovery,
|
||||
p_curr_char_being_discovered,
|
||||
NULL,
|
||||
&handle_range);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t i;
|
||||
ble_gatt_db_char_t * p_next_char;
|
||||
|
||||
for (i = p_db_discovery->curr_char_ind; i < p_srv_being_discovered->char_count; i++)
|
||||
{
|
||||
if (i == (p_srv_being_discovered->char_count - 1))
|
||||
{
|
||||
// The current characteristic is the last characteristic in the service.
|
||||
p_next_char = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_next_char = &(p_srv_being_discovered->charateristics[i + 1]);
|
||||
}
|
||||
|
||||
// Check if it is possible for the current characteristic to have a descriptor.
|
||||
if (is_desc_discovery_reqd(p_db_discovery,
|
||||
p_curr_char_being_discovered,
|
||||
p_next_char,
|
||||
&handle_range))
|
||||
{
|
||||
is_discovery_reqd = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No descriptors can exist.
|
||||
p_curr_char_being_discovered = p_next_char;
|
||||
p_db_discovery->curr_char_ind++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_discovery_reqd)
|
||||
{
|
||||
// No more descriptor discovery required. Discovery is complete.
|
||||
// This informs the caller that a discovery complete event can be triggered.
|
||||
*p_raise_discov_complete = true;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
*p_raise_discov_complete = false;
|
||||
|
||||
return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling primary service discovery response.
|
||||
*
|
||||
* @details This function will handle the primary service discovery response and start the
|
||||
* discovery of characteristics within that service.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
|
||||
*/
|
||||
static void on_primary_srv_discovery_rsp(ble_db_discovery_t * p_db_discovery,
|
||||
ble_gattc_evt_t const * p_ble_gattc_evt)
|
||||
{
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
|
||||
{
|
||||
uint32_t err_code;
|
||||
ble_gattc_evt_prim_srvc_disc_rsp_t const * p_prim_srvc_disc_rsp_evt;
|
||||
|
||||
NRF_LOG_DEBUG("Found service UUID 0x%x.", p_srv_being_discovered->srv_uuid.uuid);
|
||||
|
||||
p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp);
|
||||
|
||||
p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid;
|
||||
p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range;
|
||||
|
||||
err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
|
||||
// Error with discovering the service.
|
||||
// Indicate the error to the registered user application.
|
||||
discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_LOG_DEBUG("Service UUID 0x%x not found.", p_srv_being_discovered->srv_uuid.uuid);
|
||||
// Trigger Service Not Found event to the application.
|
||||
discovery_complete_evt_trigger(p_db_discovery, false, p_ble_gattc_evt->conn_handle);
|
||||
on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling characteristic discovery response.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
|
||||
*/
|
||||
static void on_characteristic_discovery_rsp(ble_db_discovery_t * p_db_discovery,
|
||||
ble_gattc_evt_t const * p_ble_gattc_evt)
|
||||
{
|
||||
uint32_t err_code;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
bool perform_desc_discov = false;
|
||||
|
||||
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
|
||||
{
|
||||
ble_gattc_evt_char_disc_rsp_t const * p_char_disc_rsp_evt;
|
||||
|
||||
p_char_disc_rsp_evt = &(p_ble_gattc_evt->params.char_disc_rsp);
|
||||
|
||||
// Find out the number of characteristics that were previously discovered (in earlier
|
||||
// characteristic discovery responses, if any).
|
||||
uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count;
|
||||
|
||||
// Find out the number of characteristics that are currently discovered (in the
|
||||
// characteristic discovery response being handled).
|
||||
uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count;
|
||||
|
||||
// Check if the total number of discovered characteristics are supported by this module.
|
||||
if ((num_chars_prev_disc + num_chars_curr_disc) <= BLE_GATT_DB_MAX_CHARS)
|
||||
{
|
||||
// Update the characteristics count.
|
||||
p_srv_being_discovered->char_count += num_chars_curr_disc;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The number of characteristics discovered at the peer is more than the supported
|
||||
// maximum. This module will store only the characteristics found up to this point.
|
||||
p_srv_being_discovered->char_count = BLE_GATT_DB_MAX_CHARS;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
for (i = num_chars_prev_disc, j = 0; i < p_srv_being_discovered->char_count; i++, j++)
|
||||
{
|
||||
p_srv_being_discovered->charateristics[i].characteristic =
|
||||
p_char_disc_rsp_evt->chars[j];
|
||||
|
||||
p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID;
|
||||
p_srv_being_discovered->charateristics[i].ext_prop_handle = BLE_GATT_HANDLE_INVALID;
|
||||
p_srv_being_discovered->charateristics[i].user_desc_handle = BLE_GATT_HANDLE_INVALID;
|
||||
p_srv_being_discovered->charateristics[i].report_ref_handle = BLE_GATT_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
ble_gattc_char_t * p_last_known_char;
|
||||
|
||||
p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic);
|
||||
|
||||
// If no more characteristic discovery is required, or if the maximum number of supported
|
||||
// characteristic per service has been reached, descriptor discovery will be performed.
|
||||
if ( !is_char_discovery_reqd(p_db_discovery, p_last_known_char)
|
||||
|| (p_srv_being_discovered->char_count == BLE_GATT_DB_MAX_CHARS))
|
||||
{
|
||||
perform_desc_discov = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the current characteristic index.
|
||||
p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count;
|
||||
|
||||
// Perform another round of characteristic discovery.
|
||||
err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
|
||||
discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The previous characteristic discovery resulted in no characteristics.
|
||||
// descriptor discovery should be performed.
|
||||
perform_desc_discov = true;
|
||||
}
|
||||
|
||||
if (perform_desc_discov)
|
||||
{
|
||||
bool raise_discov_complete;
|
||||
|
||||
p_db_discovery->curr_char_ind = 0;
|
||||
|
||||
err_code = descriptors_discover(p_db_discovery,
|
||||
&raise_discov_complete,
|
||||
p_ble_gattc_evt->conn_handle);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
|
||||
discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
|
||||
|
||||
return;
|
||||
}
|
||||
if (raise_discov_complete)
|
||||
{
|
||||
// No more characteristics and descriptors need to be discovered. Discovery is complete.
|
||||
// Send a discovery complete event to the user application.
|
||||
NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success"
|
||||
" on connection handle 0x%x.",
|
||||
p_srv_being_discovered->srv_uuid.uuid,
|
||||
p_ble_gattc_evt->conn_handle);
|
||||
|
||||
discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle);
|
||||
on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling descriptor discovery response.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
|
||||
*/
|
||||
static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_discovery,
|
||||
const ble_gattc_evt_t * const p_ble_gattc_evt)
|
||||
{
|
||||
const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
|
||||
p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp);
|
||||
|
||||
ble_gatt_db_char_t * p_char_being_discovered =
|
||||
&(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
|
||||
|
||||
if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
|
||||
{
|
||||
// The descriptor was found at the peer.
|
||||
// Iterate through and collect CCCD, Extended Properties,
|
||||
// User Description & Report Reference descriptor handles.
|
||||
for (uint32_t i = 0; i < p_desc_disc_rsp_evt->count; i++)
|
||||
{
|
||||
switch (p_desc_disc_rsp_evt->descs[i].uuid.uuid)
|
||||
{
|
||||
case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
|
||||
p_char_being_discovered->cccd_handle =
|
||||
p_desc_disc_rsp_evt->descs[i].handle;
|
||||
break;
|
||||
|
||||
case BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP:
|
||||
p_char_being_discovered->ext_prop_handle =
|
||||
p_desc_disc_rsp_evt->descs[i].handle;
|
||||
break;
|
||||
|
||||
case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
|
||||
p_char_being_discovered->user_desc_handle =
|
||||
p_desc_disc_rsp_evt->descs[i].handle;
|
||||
break;
|
||||
|
||||
case BLE_UUID_REPORT_REF_DESCR:
|
||||
p_char_being_discovered->report_ref_handle =
|
||||
p_desc_disc_rsp_evt->descs[i].handle;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Break if we've found all the descriptors we are looking for. */
|
||||
if (p_char_being_discovered->cccd_handle != BLE_GATT_HANDLE_INVALID &&
|
||||
p_char_being_discovered->ext_prop_handle != BLE_GATT_HANDLE_INVALID &&
|
||||
p_char_being_discovered->user_desc_handle != BLE_GATT_HANDLE_INVALID &&
|
||||
p_char_being_discovered->report_ref_handle != BLE_GATT_HANDLE_INVALID)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool raise_discov_complete = false;
|
||||
|
||||
if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
|
||||
{
|
||||
// No more characteristics and descriptors need to be discovered. Discovery is complete.
|
||||
// Send a discovery complete event to the user application.
|
||||
|
||||
raise_discov_complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Begin discovery of descriptors for the next characteristic.
|
||||
uint32_t err_code;
|
||||
|
||||
p_db_discovery->curr_char_ind++;
|
||||
|
||||
err_code = descriptors_discover(p_db_discovery,
|
||||
&raise_discov_complete,
|
||||
p_ble_gattc_evt->conn_handle);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
|
||||
// Error with discovering the service.
|
||||
// Indicate the error to the registered user application.
|
||||
discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
|
||||
|
||||
m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
|
||||
m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (raise_discov_complete)
|
||||
{
|
||||
NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success"
|
||||
" on connection handle 0x%x.",
|
||||
p_srv_being_discovered->srv_uuid.uuid,
|
||||
p_ble_gattc_evt->conn_handle);
|
||||
|
||||
discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle);
|
||||
on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler)
|
||||
{
|
||||
uint32_t err_code = NRF_SUCCESS;
|
||||
VERIFY_PARAM_NOT_NULL(evt_handler);
|
||||
|
||||
m_num_of_handlers_reg = 0;
|
||||
m_initialized = true;
|
||||
m_pending_usr_evt_index = 0;
|
||||
m_evt_handler = evt_handler;
|
||||
|
||||
return err_code;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_db_discovery_close()
|
||||
{
|
||||
m_num_of_handlers_reg = 0;
|
||||
m_initialized = false;
|
||||
m_pending_usr_evt_index = 0;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_db_discovery_evt_register(ble_uuid_t const * p_uuid)
|
||||
{
|
||||
VERIFY_PARAM_NOT_NULL(p_uuid);
|
||||
VERIFY_MODULE_INITIALIZED();
|
||||
|
||||
return registered_handler_set(p_uuid, m_evt_handler);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
|
||||
{
|
||||
uint32_t err_code;
|
||||
ble_gatt_db_srv_t * p_srv_being_discovered;
|
||||
|
||||
memset(p_db_discovery, 0x00, sizeof(ble_db_discovery_t));
|
||||
|
||||
p_db_discovery->conn_handle = conn_handle;
|
||||
|
||||
m_pending_usr_evt_index = 0;
|
||||
|
||||
p_db_discovery->discoveries_count = 0;
|
||||
p_db_discovery->curr_srv_ind = 0;
|
||||
p_db_discovery->curr_char_ind = 0;
|
||||
|
||||
p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
|
||||
p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
|
||||
|
||||
NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.",
|
||||
p_srv_being_discovered->srv_uuid.uuid, conn_handle);
|
||||
|
||||
err_code = sd_ble_gattc_primary_services_discover(conn_handle,
|
||||
SRV_DISC_START_HANDLE,
|
||||
&(p_srv_being_discovered->srv_uuid));
|
||||
if (err_code != NRF_ERROR_BUSY)
|
||||
{
|
||||
VERIFY_SUCCESS(err_code);
|
||||
p_db_discovery->discovery_in_progress = true;
|
||||
p_db_discovery->discovery_pending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = true;
|
||||
p_db_discovery->discovery_pending = true;
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
|
||||
{
|
||||
VERIFY_PARAM_NOT_NULL(p_db_discovery);
|
||||
VERIFY_MODULE_INITIALIZED();
|
||||
|
||||
if (m_num_of_handlers_reg == 0)
|
||||
{
|
||||
// No user modules were registered. There are no services to discover.
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (p_db_discovery->discovery_in_progress)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
return discovery_start(p_db_discovery, conn_handle);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling disconnected event.
|
||||
*
|
||||
* @param[in] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] p_ble_gattc_evt Pointer to the GAP event.
|
||||
*/
|
||||
static void on_disconnected(ble_db_discovery_t * p_db_discovery,
|
||||
ble_gap_evt_t const * p_evt)
|
||||
{
|
||||
if (p_evt->conn_handle == p_db_discovery->conn_handle)
|
||||
{
|
||||
p_db_discovery->discovery_in_progress = false;
|
||||
p_db_discovery->discovery_pending = false;
|
||||
p_db_discovery->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ble_db_discovery_on_ble_evt(ble_evt_t const * p_ble_evt,
|
||||
void * p_context)
|
||||
{
|
||||
VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
|
||||
VERIFY_PARAM_NOT_NULL_VOID(p_context);
|
||||
VERIFY_MODULE_INITIALIZED_VOID();
|
||||
|
||||
ble_db_discovery_t * p_db_discovery = (ble_db_discovery_t *)p_context;
|
||||
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
|
||||
on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
|
||||
break;
|
||||
|
||||
case BLE_GATTC_EVT_CHAR_DISC_RSP:
|
||||
on_characteristic_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
|
||||
break;
|
||||
|
||||
case BLE_GATTC_EVT_DESC_DISC_RSP:
|
||||
on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (p_db_discovery->discovery_pending)
|
||||
&& (p_ble_evt->header.evt_id >= BLE_GATTC_EVT_BASE)
|
||||
&& (p_ble_evt->header.evt_id <= BLE_GATTC_EVT_LAST)
|
||||
&& (p_ble_evt->evt.gattc_evt.conn_handle == p_db_discovery->conn_handle))
|
||||
{
|
||||
(void)discovery_start(p_db_discovery, p_db_discovery->conn_handle);
|
||||
}
|
||||
}
|
||||
#endif // NRF_MODULE_ENABLED(BLE_DB_DISCOVERY)
|
|
@ -0,0 +1,235 @@
|
|||
/**
|
||||
* Copyright (c) 2013 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**@file
|
||||
*
|
||||
* @defgroup ble_db_discovery Database Discovery
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Database discovery module.
|
||||
*
|
||||
* @details This module contains the APIs and types exposed by the DB Discovery module. These APIs
|
||||
* and types can be used by the application to perform discovery of a service and its
|
||||
* characteristics at the peer server. This module can also be used to discover the
|
||||
* desired services in multiple remote devices.
|
||||
*
|
||||
* @warning The maximum number of characteristics per service that can be discovered by this module
|
||||
* is determined by the number of characteristics in the service structure defined in
|
||||
* db_disc_config.h. If the peer has more than the supported number of characteristics, then
|
||||
* the first found will be discovered and any further characteristics will be ignored. Only the
|
||||
* following descriptors will be searched for at the peer: Client Characteristic Configuration,
|
||||
* Characteristic Extended Properties, Characteristic User Description, and Report Reference.
|
||||
*
|
||||
* @note Presently only one instance of a Primary Service can be discovered by this module. If
|
||||
* there are multiple instances of the service at the peer, only the first instance
|
||||
* of it at the peer is fetched and returned to the application.
|
||||
*
|
||||
* @note The application must propagate BLE stack events to this module by calling
|
||||
* ble_db_discovery_on_ble_evt().
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BLE_DB_DISCOVERY_H__
|
||||
#define BLE_DB_DISCOVERY_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_ble.h"
|
||||
#include "ble_gattc.h"
|
||||
#include "ble_gatt_db.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Macro for defining a ble_db_discovery instance.
|
||||
*
|
||||
* @param _name Name of the instance.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define BLE_DB_DISCOVERY_DEF(_name) \
|
||||
static ble_db_discovery_t _name = {.discovery_in_progress = 0, \
|
||||
.discovery_pending = 0, \
|
||||
.conn_handle = BLE_CONN_HANDLE_INVALID}; \
|
||||
NRF_SDH_BLE_OBSERVER(_name ## _obs, \
|
||||
BLE_DB_DISC_BLE_OBSERVER_PRIO, \
|
||||
ble_db_discovery_on_ble_evt, &_name)
|
||||
|
||||
/** @brief Macro for defining multiple ble_db_discovery instances.
|
||||
*
|
||||
* @param _name Name of the array of instances.
|
||||
* @param _cnt Number of instances to define.
|
||||
*/
|
||||
#define BLE_DB_DISCOVERY_ARRAY_DEF(_name, _cnt) \
|
||||
static ble_db_discovery_t _name[_cnt] = {{.discovery_in_progress = 0, \
|
||||
.discovery_pending = 0, \
|
||||
.conn_handle = BLE_CONN_HANDLE_INVALID}}; \
|
||||
NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
|
||||
BLE_DB_DISC_BLE_OBSERVER_PRIO, \
|
||||
ble_db_discovery_on_ble_evt, &_name, _cnt)
|
||||
|
||||
#define BLE_DB_DISCOVERY_MAX_SRV 6 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module (one user per service). */
|
||||
|
||||
|
||||
/**@brief DB Discovery event type. */
|
||||
typedef enum
|
||||
{
|
||||
BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the discovery of one service is complete. */
|
||||
BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/
|
||||
BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the peer.*/
|
||||
BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery instance is available.*/
|
||||
} ble_db_discovery_evt_type_t;
|
||||
|
||||
/**@brief Structure for holding the information related to the GATT database at the server.
|
||||
*
|
||||
* @details This module identifies a remote database. Use one instance of this structure per
|
||||
* connection.
|
||||
*
|
||||
* @warning This structure must be zero-initialized.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ble_gatt_db_srv_t services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. This is intended for internal use during service discovery.*/
|
||||
uint8_t srv_count; /**< Number of services at the peers GATT database.*/
|
||||
uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
|
||||
uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
|
||||
bool discovery_in_progress; /**< Variable to indicate if there is a service discovery in progress. */
|
||||
bool discovery_pending; /**< Discovery was requested, but could not start because the SoftDevice was busy. */
|
||||
uint8_t discoveries_count; /**< Number of service discoveries made, both successful and unsuccessful. */
|
||||
uint16_t conn_handle; /**< Connection handle on which the discovery is started*/
|
||||
} ble_db_discovery_t;
|
||||
|
||||
/**@brief Structure containing the event from the DB discovery module to the application. */
|
||||
typedef struct
|
||||
{
|
||||
ble_db_discovery_evt_type_t evt_type; /**< Type of event. */
|
||||
uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
|
||||
union
|
||||
{
|
||||
ble_gatt_db_srv_t discovered_db; /**< Structure containing the information about the GATT Database at the server. This will be filled when the event type is @ref BLE_DB_DISCOVERY_COMPLETE. The UUID field of this will be filled when the event type is @ref BLE_DB_DISCOVERY_SRV_NOT_FOUND. */
|
||||
uint32_t err_code; /**< nRF Error code indicating the type of error which occurred in the DB Discovery module. This will be filled when the event type is @ref BLE_DB_DISCOVERY_ERROR. */
|
||||
} params;
|
||||
} ble_db_discovery_evt_t;
|
||||
|
||||
/**@brief DB Discovery event handler type. */
|
||||
typedef void (* ble_db_discovery_evt_handler_t)(ble_db_discovery_evt_t * p_evt);
|
||||
|
||||
|
||||
/**@brief Function for initializing the DB Discovery module.
|
||||
*
|
||||
* @param[in] evt_handler Event handler to be called by the DB discovery module when any event
|
||||
* related to discovery of the registered service occurs.
|
||||
*
|
||||
* @retval NRF_SUCCESS On successful initialization.
|
||||
* @retval NRF_ERROR_NULL If the handler was NULL.
|
||||
*/
|
||||
uint32_t ble_db_discovery_init(ble_db_discovery_evt_handler_t evt_handler);
|
||||
|
||||
|
||||
/**@brief Function for closing the DB Discovery module.
|
||||
*
|
||||
* @details This function will clear up any internal variables and states maintained by the
|
||||
* module. To re-use the module after calling this function, the function @ref
|
||||
* ble_db_discovery_init must be called again.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
*/
|
||||
uint32_t ble_db_discovery_close(void);
|
||||
|
||||
|
||||
/**@brief Function for registering with the DB Discovery module.
|
||||
*
|
||||
* @details The application can use this function to inform which service it is interested in
|
||||
* discovering at the server.
|
||||
*
|
||||
* @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server.
|
||||
*
|
||||
* @note The total number of services that can be discovered by this module is @ref
|
||||
* BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of
|
||||
* registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
|
||||
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
|
||||
* @ref ble_db_discovery_init.
|
||||
* @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module
|
||||
* has been reached.
|
||||
*/
|
||||
uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid);
|
||||
|
||||
|
||||
/**@brief Function for starting the discovery of the GATT database at the server.
|
||||
*
|
||||
* @param[out] p_db_discovery Pointer to the DB Discovery structure.
|
||||
* @param[in] conn_handle The handle of the connection for which the discovery should be
|
||||
* started.
|
||||
*
|
||||
* @retval NRF_SUCCESS Operation success.
|
||||
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
|
||||
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
|
||||
* @ref ble_db_discovery_init, or without calling
|
||||
* @ref ble_db_discovery_evt_register.
|
||||
* @retval NRF_ERROR_BUSY If a discovery is already in progress using
|
||||
* @p p_db_discovery. Use a different @ref ble_db_discovery_t
|
||||
* structure, or wait for a DB Discovery event before retrying.
|
||||
*
|
||||
* @return This API propagates the error code returned by the
|
||||
* SoftDevice API @ref sd_ble_gattc_primary_services_discover.
|
||||
*/
|
||||
uint32_t ble_db_discovery_start(ble_db_discovery_t * p_db_discovery,
|
||||
uint16_t conn_handle);
|
||||
|
||||
|
||||
/**@brief Function for handling the Application's BLE Stack events.
|
||||
*
|
||||
* @param[in] p_ble_evt Pointer to the BLE event received.
|
||||
* @param[in,out] p_context Pointer to the DB Discovery structure.
|
||||
*/
|
||||
void ble_db_discovery_on_ble_evt(ble_evt_t const * p_ble_evt,
|
||||
void * p_context);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_DB_DISCOVERY_H__
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,942 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(BLE_DTM)
|
||||
#include "ble_dtm.h"
|
||||
#include "ble_dtm_hw.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "nrf.h"
|
||||
|
||||
#define DTM_HEADER_OFFSET 0 /**< Index where the header of the pdu is located. */
|
||||
#define DTM_HEADER_SIZE 2 /**< Size of PDU header. */
|
||||
#define DTM_PAYLOAD_MAX_SIZE 255 /**< Maximum payload size allowed during dtm execution. */
|
||||
#define DTM_LENGTH_OFFSET (DTM_HEADER_OFFSET + 1) /**< Index where the length of the payload is encoded. */
|
||||
#define DTM_PDU_MAX_MEMORY_SIZE (DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE) /**< Maximum PDU size allowed during dtm execution. */
|
||||
#define DTM_ON_AIR_OVERHEAD_SIZE 10 /**< Size of the packet on air without the payload (preamble + sync word + type + RFU + length + CRC). */
|
||||
|
||||
#define RX_MODE true /**< Constant defining RX mode for radio during dtm test. */
|
||||
#define TX_MODE false /**< Constant defining TX mode for radio during dtm test. */
|
||||
|
||||
#define PHYS_CH_MAX 39 /**< Maximum number of valid channels in BLE. */
|
||||
|
||||
// Values that for now are "constants" - they could be configured by a function setting them,
|
||||
// but most of these are set by the BLE DTM standard, so changing them is not relevant.
|
||||
#define RFPHY_TEST_0X0F_REF_PATTERN 0x0f /**< RF-PHY test packet patterns, for the repeated octet packets. */
|
||||
#define RFPHY_TEST_0X55_REF_PATTERN 0x55 /**< RF-PHY test packet patterns, for the repeated octet packets. */
|
||||
#define RFPHY_TEST_0XFF_REF_PATTERN 0xFF /**< RF-PHY test packet patterns, for the repeated octet packets. */
|
||||
|
||||
#define PRBS9_CONTENT {0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, \
|
||||
0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, \
|
||||
0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, \
|
||||
0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, \
|
||||
0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, \
|
||||
0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, \
|
||||
0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, \
|
||||
0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, \
|
||||
0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, \
|
||||
0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, \
|
||||
0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, \
|
||||
0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, \
|
||||
0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, \
|
||||
0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, \
|
||||
0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, \
|
||||
0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, \
|
||||
0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, \
|
||||
0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, \
|
||||
0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, \
|
||||
0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, \
|
||||
0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, \
|
||||
0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, \
|
||||
0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, \
|
||||
0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, \
|
||||
0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, \
|
||||
0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, \
|
||||
0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, \
|
||||
0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, \
|
||||
0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, \
|
||||
0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, \
|
||||
0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, \
|
||||
0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7} /**< The PRBS9 sequence used as packet payload.
|
||||
The bytes in the sequence is in the right order, but the bits of each byte in the array is reverse.
|
||||
of that found by running the PRBS9 algorithm. This is because of the endianess of the nRF5 radio. */
|
||||
|
||||
/**@brief Structure holding the PDU used for transmitting/receiving a PDU.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t content[DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE]; /**< PDU packet content. */
|
||||
} pdu_type_t;
|
||||
|
||||
/**@brief States used for the DTM test implementation.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
STATE_UNINITIALIZED, /**< The DTM is uninitialized. */
|
||||
STATE_IDLE, /**< State when system has just initialized, or current test has completed. */
|
||||
STATE_TRANSMITTER_TEST, /**< State used when a DTM Transmission test is running. */
|
||||
STATE_CARRIER_TEST, /**< State used when a DTM Carrier test is running (Vendor specific test). */
|
||||
STATE_RECEIVER_TEST /**< State used when a DTM Receive test is running. */
|
||||
} state_t;
|
||||
|
||||
|
||||
// Internal variables set as side effects of commands or events.
|
||||
static state_t m_state = STATE_UNINITIALIZED; /**< Current machine state. */
|
||||
static uint16_t m_rx_pkt_count; /**< Number of valid packets received. */
|
||||
static pdu_type_t m_pdu; /**< PDU to be sent. */
|
||||
static uint16_t m_event; /**< current command status - initially "ok", may be set if error detected, or to packet count. */
|
||||
static bool m_new_event; /**< Command has been processed - number of not yet reported event bytes. */
|
||||
static uint32_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */
|
||||
static dtm_pkt_type_t m_packet_type; /**< Bits 0..1 of 16-bit transmit command, or 0xFFFFFFFF. */
|
||||
static dtm_freq_t m_phys_ch; /**< 0..39 physical channel number (base 2402 MHz, Interval 2 MHz), bits 8:13 of 16-bit dtm command. */
|
||||
static uint32_t m_current_time = 0; /**< Counter for interrupts from timer to ensure that the 2 bytes forming a DTM command are received within the time window. */
|
||||
|
||||
// Nordic specific configuration values (not defined by BLE standard).
|
||||
// Definition of initial values found in ble_dtm.h
|
||||
static int32_t m_tx_power = DEFAULT_TX_POWER; /**< TX power for transmission test, default to maximum value (+4 dBm). */
|
||||
static NRF_TIMER_Type * mp_timer = DEFAULT_TIMER; /**< Timer to be used. */
|
||||
static IRQn_Type m_timer_irq = DEFAULT_TIMER_IRQn; /**< which interrupt line to clear on every timeout */
|
||||
|
||||
static uint8_t const m_prbs_content[] = PRBS9_CONTENT; /**< Pseudo-random bit sequence defined by the BLE standard. */
|
||||
static uint8_t m_packetHeaderLFlen = 8; /**< Length of length field in packet Header (in bits). */
|
||||
static uint8_t m_packetHeaderS0len = 1; /**< Length of S0 field in packet Header (in bytes). */
|
||||
static uint8_t m_packetHeaderS1len = 0; /**< Length of S1 field in packet Header (in bits). */
|
||||
static uint8_t m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit; /**< Length of the preamble. */
|
||||
|
||||
static uint8_t m_crcConfSkipAddr = 1; /**< Leave packet address field out of CRC calculation. */
|
||||
static uint8_t m_static_length = 0; /**< Number of bytes sent in addition to the var.length payload. */
|
||||
static uint32_t m_balen = 3; /**< Base address length in bytes. */
|
||||
static uint32_t m_endian = RADIO_PCNF1_ENDIAN_Little; /**< On air endianess of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */
|
||||
static uint32_t m_whitening = RADIO_PCNF1_WHITEEN_Disabled; /**< Whitening disabled. */
|
||||
static uint8_t m_crcLength = RADIO_CRCCNF_LEN_Three; /**< CRC Length (in bytes). */
|
||||
static uint32_t m_address = 0x71764129; /**< Address. */
|
||||
static uint32_t m_crc_poly = 0x0000065B; /**< CRC polynomial. */
|
||||
static uint32_t m_crc_init = 0x00555555; /**< Initial value for CRC calculation. */
|
||||
static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode value. */
|
||||
static uint32_t m_txIntervaluS = 2500; /**< Time between start of Tx packets (in uS). */
|
||||
|
||||
|
||||
/**@brief Function for verifying that a received PDU has the expected structure and content.
|
||||
*/
|
||||
static bool check_pdu(void)
|
||||
{
|
||||
uint8_t k; // Byte pointer for running through PDU payload
|
||||
uint8_t pattern; // Repeating octet value in payload
|
||||
dtm_pkt_type_t pdu_packet_type; // Note: PDU packet type is a 4-bit field in HCI, but 2 bits in BLE DTM
|
||||
uint32_t length = 0;
|
||||
|
||||
pdu_packet_type = (dtm_pkt_type_t)(m_pdu.content[DTM_HEADER_OFFSET] & 0x0F);
|
||||
length = m_pdu.content[DTM_LENGTH_OFFSET];
|
||||
|
||||
// Check that the length is valid.
|
||||
if (length > DTM_PAYLOAD_MAX_SIZE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the 1Mbit or 2Mbit radio mode is active, check that one of the three valid uncoded DTM packet types are selected.
|
||||
if ((m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit) && (pdu_packet_type > (dtm_pkt_type_t)DTM_PKT_0X55))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef NRF52840_XXAA
|
||||
// If a long range radio mode is active, check that one of the four valid coded DTM packet types are selected.
|
||||
if ((m_radio_mode == RADIO_MODE_MODE_Ble_LR500Kbit || m_radio_mode == RADIO_MODE_MODE_Ble_LR125Kbit) && (pdu_packet_type > (dtm_pkt_type_t)DTM_PKT_0XFF))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pdu_packet_type == DTM_PKT_PRBS9)
|
||||
{
|
||||
// Payload does not consist of one repeated octet; must compare ir with entire block into
|
||||
return (memcmp(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length) == 0);
|
||||
}
|
||||
|
||||
if (pdu_packet_type == DTM_PKT_0X0F)
|
||||
{
|
||||
pattern = RFPHY_TEST_0X0F_REF_PATTERN;
|
||||
}
|
||||
else if (pdu_packet_type == DTM_PKT_0X55)
|
||||
{
|
||||
pattern = RFPHY_TEST_0X55_REF_PATTERN;
|
||||
}
|
||||
else if (pdu_packet_type == DTM_PKT_0XFF)
|
||||
{
|
||||
pattern = RFPHY_TEST_0XFF_REF_PATTERN;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No valid packet type set.
|
||||
return false;
|
||||
}
|
||||
|
||||
for (k = 0; k < length; k++)
|
||||
{
|
||||
// Check repeated pattern filling the PDU payload
|
||||
if (m_pdu.content[k + 2] != pattern)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for turning off the radio after a test.
|
||||
* Also called after test done, to be ready for next test.
|
||||
*/
|
||||
static void radio_reset(void)
|
||||
{
|
||||
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk | PPI_CHENCLR_CH1_Msk;
|
||||
|
||||
NRF_RADIO->SHORTS = 0;
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
NRF_RADIO->TASKS_DISABLE = 1;
|
||||
|
||||
while (NRF_RADIO->EVENTS_DISABLED == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
NRF_RADIO->TASKS_RXEN = 0;
|
||||
NRF_RADIO->TASKS_TXEN = 0;
|
||||
|
||||
m_rx_pkt_count = 0;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for initializing the radio for DTM.
|
||||
*/
|
||||
static uint32_t radio_init(void)
|
||||
{
|
||||
if (dtm_radio_validate(m_tx_power, m_radio_mode) != DTM_SUCCESS)
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
|
||||
// Turn off radio before configuring it
|
||||
radio_reset();
|
||||
|
||||
NRF_RADIO->TXPOWER = m_tx_power;
|
||||
NRF_RADIO->MODE = m_radio_mode << RADIO_MODE_MODE_Pos;
|
||||
|
||||
// Set the access address, address0/prefix0 used for both Rx and Tx address
|
||||
NRF_RADIO->PREFIX0 &= ~RADIO_PREFIX0_AP0_Msk;
|
||||
NRF_RADIO->PREFIX0 |= (m_address >> 24) & RADIO_PREFIX0_AP0_Msk;
|
||||
NRF_RADIO->BASE0 = m_address << 8;
|
||||
NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos;
|
||||
NRF_RADIO->TXADDRESS = (0x00 << RADIO_TXADDRESS_TXADDRESS_Pos) & RADIO_TXADDRESS_TXADDRESS_Msk;
|
||||
|
||||
// Configure CRC calculation
|
||||
NRF_RADIO->CRCCNF = (m_crcConfSkipAddr << RADIO_CRCCNF_SKIP_ADDR_Pos) |
|
||||
(m_crcLength << RADIO_CRCCNF_LEN_Pos);
|
||||
|
||||
if (m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit)
|
||||
{
|
||||
// Non-coded PHY
|
||||
NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) |
|
||||
(m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) |
|
||||
(m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos) |
|
||||
(m_packetHeaderPlen << RADIO_PCNF0_PLEN_Pos);
|
||||
}
|
||||
#ifdef NRF52840_XXAA
|
||||
else
|
||||
{
|
||||
// Coded PHY (Long range)
|
||||
NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) |
|
||||
(m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) |
|
||||
(m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos) |
|
||||
(3 << RADIO_PCNF0_TERMLEN_Pos) |
|
||||
(2 << RADIO_PCNF0_CILEN_Pos) |
|
||||
(m_packetHeaderPlen << RADIO_PCNF0_PLEN_Pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
NRF_RADIO->PCNF1 = (m_whitening << RADIO_PCNF1_WHITEEN_Pos) |
|
||||
(m_endian << RADIO_PCNF1_ENDIAN_Pos) |
|
||||
(m_balen << RADIO_PCNF1_BALEN_Pos) |
|
||||
(m_static_length << RADIO_PCNF1_STATLEN_Pos) |
|
||||
(DTM_PAYLOAD_MAX_SIZE << RADIO_PCNF1_MAXLEN_Pos);
|
||||
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for preparing the radio. At start of each test: Turn off RF, clear interrupt flags of RF, initialize the radio
|
||||
* at given RF channel.
|
||||
*
|
||||
*@param[in] rx boolean indicating if radio should be prepared in rx mode (true) or tx mode.
|
||||
*/
|
||||
static void radio_prepare(bool rx)
|
||||
{
|
||||
dtm_turn_off_test();
|
||||
NRF_RADIO->CRCPOLY = m_crc_poly;
|
||||
NRF_RADIO->CRCINIT = m_crc_init;
|
||||
NRF_RADIO->FREQUENCY = (m_phys_ch << 1) + 2; // Actual frequency (MHz): 2400 + register value
|
||||
NRF_RADIO->PACKETPTR = (uint32_t)&m_pdu; // Setting packet pointer will start the radio
|
||||
NRF_RADIO->EVENTS_READY = 0;
|
||||
NRF_RADIO->SHORTS = (1 << RADIO_SHORTS_READY_START_Pos) | // Shortcut between READY event and START task
|
||||
(1 << RADIO_SHORTS_END_DISABLE_Pos); // Shortcut between END event and DISABLE task
|
||||
|
||||
if (rx)
|
||||
{
|
||||
NRF_RADIO->EVENTS_END = 0;
|
||||
NRF_RADIO->TASKS_RXEN = 1; // shorts will start radio in RX mode when it is ready
|
||||
}
|
||||
else // tx
|
||||
{
|
||||
NRF_RADIO->TXPOWER = m_tx_power;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for terminating the ongoing test (if any) and closing down the radio.
|
||||
*/
|
||||
static void dtm_test_done(void)
|
||||
{
|
||||
dtm_turn_off_test();
|
||||
NRF_PPI->CHENCLR = 0x01;
|
||||
NRF_PPI->CH[0].EEP = 0; // Break connection from timer to radio to stop transmit loop
|
||||
NRF_PPI->CH[0].TEP = 0;
|
||||
|
||||
radio_reset();
|
||||
m_state = STATE_IDLE;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for configuring the timer for 625us cycle time.
|
||||
*/
|
||||
static uint32_t timer_init(void)
|
||||
{
|
||||
// Use 16MHz from external crystal
|
||||
// This could be customized for RC/Xtal, or even to use a 32 kHz crystal
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_HFCLKSTART = 1;
|
||||
|
||||
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
|
||||
{
|
||||
// Do nothing while waiting for the clock to start
|
||||
}
|
||||
|
||||
mp_timer->TASKS_STOP = 1; // Stop timer, if it was running
|
||||
mp_timer->TASKS_CLEAR = 1;
|
||||
mp_timer->MODE = TIMER_MODE_MODE_Timer; // Timer mode (not counter)
|
||||
mp_timer->EVENTS_COMPARE[0] = 0; // clean up possible old events
|
||||
mp_timer->EVENTS_COMPARE[1] = 0;
|
||||
mp_timer->EVENTS_COMPARE[2] = 0;
|
||||
mp_timer->EVENTS_COMPARE[3] = 0;
|
||||
|
||||
// Timer is polled, but enable the compare0 interrupt in order to wakeup from CPU sleep
|
||||
mp_timer->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
|
||||
mp_timer->SHORTS = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos; // Clear the count every time timer reaches the CCREG0 count
|
||||
mp_timer->PRESCALER = 4; // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us
|
||||
mp_timer->CC[0] = m_txIntervaluS; // 625uS with 1MHz clock to the timer
|
||||
mp_timer->CC[1] = UART_POLL_CYCLE; // Depends on the baud rate of the UART. Default baud rate of 19200 will result in a 260uS time with 1MHz clock to the timer
|
||||
mp_timer->TASKS_START = 1; // Start the timer - it will be running continuously
|
||||
m_current_time = 0;
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for handling vendor specific commands.
|
||||
* Used when packet type is set to Vendor specific.
|
||||
* The length field is used for encoding vendor specific command.
|
||||
* The frequency field is used for encoding vendor specific options to the command.
|
||||
*
|
||||
* @param[in] vendor_cmd Vendor specific command to be executed.
|
||||
* @param[in] vendor_option Vendor specific option to the vendor command.
|
||||
*
|
||||
* @return DTM_SUCCESS or one of the DTM_ERROR_ values
|
||||
*/
|
||||
static uint32_t dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_option)
|
||||
{
|
||||
switch (vendor_cmd)
|
||||
{
|
||||
// nRFgo Studio uses CARRIER_TEST_STUDIO to indicate a continuous carrier without
|
||||
// a modulated signal.
|
||||
case CARRIER_TEST:
|
||||
case CARRIER_TEST_STUDIO:
|
||||
// Not a packet type, but used to indicate that a continuous carrier signal
|
||||
// should be transmitted by the radio.
|
||||
radio_prepare(TX_MODE);
|
||||
|
||||
dtm_constant_carrier();
|
||||
|
||||
// Shortcut between READY event and START task
|
||||
NRF_RADIO->SHORTS = 1 << RADIO_SHORTS_READY_START_Pos;
|
||||
|
||||
// Shortcut will start radio in Tx mode when it is ready
|
||||
NRF_RADIO->TASKS_TXEN = 1;
|
||||
m_state = STATE_CARRIER_TEST;
|
||||
break;
|
||||
|
||||
case SET_TX_POWER:
|
||||
if (!dtm_set_txpower(vendor_option))
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
break;
|
||||
|
||||
case SELECT_TIMER:
|
||||
if (!dtm_set_timer(vendor_option))
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Event code is unchanged, successful
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t dtm_packet_interval_calculate(uint32_t test_payload_length, uint32_t mode)
|
||||
{
|
||||
uint32_t test_packet_length = 0; // [us] NOTE: bits are us at 1Mbit
|
||||
uint32_t packet_interval = 0; // us
|
||||
uint32_t overhead_bits = 0; // bits
|
||||
|
||||
/* packet overhead
|
||||
* see BLE [Vol 6, Part F] page 213
|
||||
* 4.1 LE TEST PACKET FORMAT */
|
||||
if (mode == RADIO_MODE_MODE_Ble_2Mbit)
|
||||
{
|
||||
// 16 preamble
|
||||
// 32 sync word
|
||||
// 8 PDU header, actually packetHeaderS0len * 8
|
||||
// 8 PDU length, actually packetHeaderLFlen
|
||||
// 24 CRC
|
||||
overhead_bits = 88; // 11 bytes
|
||||
}
|
||||
else if (mode == RADIO_MODE_MODE_Ble_1Mbit)
|
||||
{
|
||||
// 8 preamble
|
||||
// 32 sync word
|
||||
// 8 PDU header, actually packetHeaderS0len * 8
|
||||
// 8 PDU length, actually packetHeaderLFlen
|
||||
// 24 CRC
|
||||
overhead_bits = 80; // 10 bytes
|
||||
}
|
||||
#ifdef NRF52840_XXAA
|
||||
else if (mode == RADIO_MODE_MODE_Ble_LR125Kbit)
|
||||
{
|
||||
// 80 preamble
|
||||
// 32 * 8 sync word coding=8
|
||||
// 2 * 8 Coding indicator, coding=8
|
||||
// 3 * 8 TERM1 coding=8
|
||||
// 8 * 8 PDU header, actually packetHeaderS0len * 8 coding=8
|
||||
// 8 * 8 PDU length, actually packetHeaderLFlen coding=8
|
||||
// 24 * 8 CRC coding=8
|
||||
// 3 * 8 TERM2 coding=8
|
||||
overhead_bits = 720; // 90 bytes
|
||||
}
|
||||
else if (mode == RADIO_MODE_MODE_Ble_LR500Kbit)
|
||||
{
|
||||
// 80 preamble
|
||||
// 32 * 8 sync word coding=8
|
||||
// 2 * 8 Coding indicator, coding=8
|
||||
// 3 * 8 TERM 1 coding=8
|
||||
// 8 * 2 PDU header, actually packetHeaderS0len * 8 coding=2
|
||||
// 8 * 2 PDU length, actually packetHeaderLFlen coding=2
|
||||
// 24 * 2 CRC coding=2
|
||||
// 3 * 2 TERM2 coding=2
|
||||
// NOTE: this makes us clock out 46 bits for CI + TERM1 + TERM2
|
||||
// assumption the radio will handle this
|
||||
overhead_bits = 462; // 57.75 bytes
|
||||
}
|
||||
#endif
|
||||
/* add PDU payload test_payload length */
|
||||
test_packet_length = (test_payload_length * 8); // in bits
|
||||
#ifdef NRF52840_XXAA
|
||||
// account for the encoding of PDU
|
||||
if (mode == RADIO_MODE_MODE_Ble_LR125Kbit)
|
||||
{
|
||||
test_packet_length *= 8; // 1 to 8 encoding
|
||||
}
|
||||
if (mode == RADIO_MODE_MODE_Ble_LR500Kbit)
|
||||
{
|
||||
test_packet_length *= 2; // 1 to 2 encoding
|
||||
}
|
||||
#endif
|
||||
// add overhead calculated above
|
||||
test_packet_length += overhead_bits;
|
||||
// we remember this bits are us in 1Mbit
|
||||
if (mode == RADIO_MODE_MODE_Ble_2Mbit)
|
||||
{
|
||||
test_packet_length /= 2; // double speed
|
||||
}
|
||||
|
||||
/*
|
||||
* packet_interval = ceil((test_packet_length+249)/625)*625
|
||||
* NOTE: To avoid floating point an equivalent calculation is used.
|
||||
*/
|
||||
uint32_t i = 0;
|
||||
uint32_t timeout = 0;
|
||||
do
|
||||
{
|
||||
i++;
|
||||
timeout = i * 625;
|
||||
} while (test_packet_length + 249 > timeout);
|
||||
packet_interval = i * 625;
|
||||
|
||||
return packet_interval;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dtm_init(void)
|
||||
{
|
||||
if ((timer_init() != DTM_SUCCESS) || (radio_init() != DTM_SUCCESS))
|
||||
{
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
m_new_event = false;
|
||||
m_state = STATE_IDLE;
|
||||
m_packet_length = 0;
|
||||
|
||||
// Enable wake-up on event
|
||||
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
|
||||
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t dtm_wait(void)
|
||||
{
|
||||
// Enable wake-up on event
|
||||
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Event may be the reception of a packet -
|
||||
// handle radio first, to give it highest priority:
|
||||
if (NRF_RADIO->EVENTS_END != 0)
|
||||
{
|
||||
NRF_RADIO->EVENTS_END = 0;
|
||||
NVIC_ClearPendingIRQ(RADIO_IRQn);
|
||||
|
||||
if (m_state == STATE_RECEIVER_TEST)
|
||||
{
|
||||
NRF_RADIO->TASKS_RXEN = 1;
|
||||
if ((NRF_RADIO->CRCSTATUS == 1) && check_pdu())
|
||||
{
|
||||
// Count the number of successfully received packets
|
||||
m_rx_pkt_count++;
|
||||
}
|
||||
// Note that failing packets are simply ignored (CRC or contents error).
|
||||
|
||||
// Zero fill all pdu fields to avoid stray data
|
||||
memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
|
||||
}
|
||||
// If no RECEIVER_TEST is running, ignore incoming packets (but do clear IRQ!)
|
||||
}
|
||||
|
||||
// Check for timeouts:
|
||||
if (mp_timer->EVENTS_COMPARE[0] != 0)
|
||||
{
|
||||
mp_timer->EVENTS_COMPARE[0] = 0;
|
||||
}
|
||||
else if (mp_timer->EVENTS_COMPARE[1] != 0)
|
||||
{
|
||||
// Reset timeout event flag for next iteration.
|
||||
mp_timer->EVENTS_COMPARE[1] = 0;
|
||||
NVIC_ClearPendingIRQ(m_timer_irq);
|
||||
return ++m_current_time;
|
||||
}
|
||||
|
||||
// Other events: No processing
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload)
|
||||
{
|
||||
// Save specified packet in static variable for tx/rx functions to use.
|
||||
// Note that BLE conformance testers always use full length packets.
|
||||
m_packet_length = (m_packet_length & 0xC0) | ((uint8_t)length & 0x3F);
|
||||
m_packet_type = payload;
|
||||
m_phys_ch = freq;
|
||||
|
||||
// If 1 Mbit or 2 Mbit radio mode is in use check for Vendor Specific payload.
|
||||
if ((m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit) && payload == DTM_PKT_VENDORSPECIFIC)
|
||||
{
|
||||
/* Note that in a HCI adaption layer, as well as in the DTM PDU format,
|
||||
the value 0x03 is a distinct bit pattern (PRBS15). Even though BLE does not
|
||||
support PRBS15, this implementation re-maps 0x03 to DTM_PKT_VENDORSPECIFIC,
|
||||
to avoid the risk of confusion, should the code be extended to greater coverage.
|
||||
*/
|
||||
m_packet_type = DTM_PKT_TYPE_VENDORSPECIFIC;
|
||||
}
|
||||
|
||||
// Clean out any non-retrieved event that might linger from an earlier test
|
||||
m_new_event = true;
|
||||
|
||||
// Set default event; any error will set it to LE_TEST_STATUS_EVENT_ERROR
|
||||
m_event = LE_TEST_STATUS_EVENT_SUCCESS;
|
||||
|
||||
if (m_state == STATE_UNINITIALIZED)
|
||||
{
|
||||
// Application has not explicitly initialized DTM,
|
||||
return DTM_ERROR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (cmd == LE_TEST_SETUP)
|
||||
{
|
||||
// Note that timer will continue running after a reset
|
||||
dtm_test_done();
|
||||
if (freq == LE_TEST_SETUP_RESET)
|
||||
{
|
||||
if (length != 0x00)
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
// Reset the packet length upper bits.
|
||||
m_packet_length = 0;
|
||||
|
||||
// Reset the selected PHY to 1Mbit
|
||||
m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit;
|
||||
m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit;
|
||||
|
||||
#ifdef NRF52840_XXAA
|
||||
// Workaround for Errata ID 164
|
||||
*(volatile uint32_t *)0x4000173C &= ~0x80000000;
|
||||
#endif
|
||||
}
|
||||
else if (freq == LE_TEST_SETUP_SET_UPPER)
|
||||
{
|
||||
if (length > 0x03)
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
m_packet_length = length << 6;
|
||||
}
|
||||
else if (freq == LE_TEST_SETUP_SET_PHY)
|
||||
{
|
||||
switch (length)
|
||||
{
|
||||
case LE_PHY_1M:
|
||||
m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit;
|
||||
m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit;
|
||||
|
||||
#ifdef NRF52840_XXAA
|
||||
// Workaround for Errata ID 164
|
||||
*(volatile uint32_t *)0x4000173C &= ~0x80000000;
|
||||
#endif
|
||||
|
||||
return radio_init();
|
||||
|
||||
case LE_PHY_2M:
|
||||
m_radio_mode = RADIO_MODE_MODE_Ble_2Mbit;
|
||||
m_packetHeaderPlen = RADIO_PCNF0_PLEN_16bit;
|
||||
|
||||
#ifdef NRF52840_XXAA
|
||||
// Workaround for Errata ID 164
|
||||
*(volatile uint32_t *)0x4000173C &= ~0x80000000;
|
||||
#endif
|
||||
|
||||
return radio_init();
|
||||
|
||||
case LE_PHY_LE_CODED_S8:
|
||||
#ifdef NRF52840_XXAA
|
||||
m_radio_mode = RADIO_MODE_MODE_Ble_LR125Kbit;
|
||||
m_packetHeaderPlen = RADIO_PCNF0_PLEN_LongRange;
|
||||
|
||||
// Workaround for Errata ID 164
|
||||
*(volatile uint32_t *)0x4000173C |= 0x80000000;
|
||||
*(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C);
|
||||
|
||||
return radio_init();
|
||||
#else
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
#endif // NRF52840_XXAA
|
||||
case LE_PHY_LE_CODED_S2:
|
||||
#ifdef NRF52840_XXAA
|
||||
m_radio_mode = RADIO_MODE_MODE_Ble_LR500Kbit;
|
||||
m_packetHeaderPlen = RADIO_PCNF0_PLEN_LongRange;
|
||||
|
||||
// Workaround for Errata ID 164
|
||||
*(volatile uint32_t *)0x4000173C |= 0x80000000;
|
||||
*(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C);
|
||||
|
||||
return radio_init();
|
||||
#else
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
#endif
|
||||
default:
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
}
|
||||
else if(freq == LE_TEST_SETUP_SELECT_MODULATION)
|
||||
{
|
||||
if (length > 0x01)
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
// Only standard modulation is supported.
|
||||
}
|
||||
else if (freq == LE_TEST_SETUP_READ_SUPPORTED)
|
||||
{
|
||||
if (length != 0x00)
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
// 0XXXXXXXXXXX0110 indicate that 2Mbit and DLE is supported and stable modulation is not supported (No nRF5 device supports this).
|
||||
m_event = 0x0006;
|
||||
}
|
||||
else if (freq == LE_TEST_SETUP_READ_MAX)
|
||||
{
|
||||
// Read max supported value.
|
||||
switch (length)
|
||||
{
|
||||
case 0x00:
|
||||
// Read supportedMaxTxOctets
|
||||
m_event = 0x01FE;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
// Read supportedMaxTxTime
|
||||
m_event = 0x4290;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
// Read supportedMaxRxOctets
|
||||
m_event = 0x01FE;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
// Read supportedMaxRxTime
|
||||
m_event = 0x4290;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
if (cmd == LE_TEST_END)
|
||||
{
|
||||
if (m_state == STATE_IDLE)
|
||||
{
|
||||
// Sequencing error - only rx or tx test may be ended!
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_INVALID_STATE;
|
||||
}
|
||||
m_event = LE_PACKET_REPORTING_EVENT | m_rx_pkt_count;
|
||||
dtm_test_done();
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
if (m_state != STATE_IDLE)
|
||||
{
|
||||
// Sequencing error - only TEST_END/RESET are legal while test is running
|
||||
// Note: State is unchanged; ongoing test not affected
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Check for illegal values of m_phys_ch. Skip the check if the packet is vendor spesific.
|
||||
if (payload != DTM_PKT_VENDORSPECIFIC && m_phys_ch > PHYS_CH_MAX)
|
||||
{
|
||||
// Parameter error
|
||||
// Note: State is unchanged; ongoing test not affected
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
|
||||
return DTM_ERROR_ILLEGAL_CHANNEL;
|
||||
}
|
||||
|
||||
m_rx_pkt_count = 0;
|
||||
|
||||
if (cmd == LE_RECEIVER_TEST)
|
||||
{
|
||||
// Zero fill all pdu fields to avoid stray data from earlier test run
|
||||
memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
|
||||
radio_prepare(RX_MODE); // Reinitialize "everything"; RF interrupts OFF
|
||||
m_state = STATE_RECEIVER_TEST;
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
if (cmd == LE_TRANSMITTER_TEST)
|
||||
{
|
||||
// Check for illegal values of m_packet_length. Skip the check if the packet is vendor spesific.
|
||||
if (m_packet_type != DTM_PKT_TYPE_VENDORSPECIFIC && m_packet_length > DTM_PAYLOAD_MAX_SIZE)
|
||||
{
|
||||
// Parameter error
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
m_pdu.content[DTM_LENGTH_OFFSET] = m_packet_length;
|
||||
// Note that PDU uses 4 bits even though BLE DTM uses only 2 (the HCI SDU uses all 4)
|
||||
switch (m_packet_type)
|
||||
{
|
||||
case DTM_PKT_PRBS9:
|
||||
m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_PRBS9;
|
||||
// Non-repeated, must copy entire pattern to PDU
|
||||
memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, m_packet_length);
|
||||
break;
|
||||
|
||||
case DTM_PKT_0X0F:
|
||||
m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0X0F;
|
||||
// Bit pattern 00001111 repeated
|
||||
memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, m_packet_length);
|
||||
break;
|
||||
|
||||
case DTM_PKT_0X55:
|
||||
m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0X55;
|
||||
// Bit pattern 01010101 repeated
|
||||
memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, m_packet_length);
|
||||
break;
|
||||
|
||||
case DTM_PKT_0XFF:
|
||||
m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0XFF;
|
||||
// Bit pattern 11111111 repeated. Only available in coded PHY (Long range).
|
||||
memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0XFF_REF_PATTERN, m_packet_length);
|
||||
break;
|
||||
|
||||
case DTM_PKT_TYPE_VENDORSPECIFIC:
|
||||
// The length field is for indicating the vendor specific command to execute.
|
||||
// The frequency field is used for vendor specific options to the command.
|
||||
return dtm_vendor_specific_pkt(length, freq);
|
||||
|
||||
default:
|
||||
// Parameter error
|
||||
m_event = LE_TEST_STATUS_EVENT_ERROR;
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
|
||||
// Initialize CRC value, set channel:
|
||||
radio_prepare(TX_MODE);
|
||||
|
||||
// Set the timer to the correct period. The delay between each packet is described in the
|
||||
// Bluetooth Core Spsification version 4.2 Vol. 6 Part F Section 4.1.6.
|
||||
mp_timer->CC[0] = dtm_packet_interval_calculate(m_packet_length, m_radio_mode);
|
||||
|
||||
// Configure PPI so that timer will activate radio every 625 us
|
||||
NRF_PPI->CH[0].EEP = (uint32_t)&mp_timer->EVENTS_COMPARE[0];
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN;
|
||||
NRF_PPI->CHENSET = 0x01;
|
||||
m_state = STATE_TRANSMITTER_TEST;
|
||||
}
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
bool dtm_event_get(dtm_event_t *p_dtm_event)
|
||||
{
|
||||
bool was_new = m_new_event;
|
||||
// mark the current event as retrieved
|
||||
m_new_event = false;
|
||||
*p_dtm_event = m_event;
|
||||
// return value indicates whether this value was already retrieved.
|
||||
return was_new;
|
||||
}
|
||||
|
||||
|
||||
// =================================================================================================
|
||||
// Configuration functions (only for parameters not definitely determined by the BLE DTM standard).
|
||||
// These functions return true if successful, false if value could not be set
|
||||
|
||||
|
||||
/**@brief Function for configuring the output power for transmitter test.
|
||||
This function may be called directly, or through dtm_cmd() specifying
|
||||
DTM_PKT_VENDORSPECIFIC as payload, SET_TX_POWER as length, and the dBm value as frequency.
|
||||
*/
|
||||
bool dtm_set_txpower(uint32_t new_tx_power)
|
||||
{
|
||||
// radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed
|
||||
int8_t new_power8 = (int8_t)(new_tx_power & 0xFF);
|
||||
|
||||
// The two most significant bits are not sent in the 6 bit field of the DTM command.
|
||||
// These two bits are 1's if and only if the tx_power is a negative number.
|
||||
// All valid negative values have the fourth most significant bit as 1.
|
||||
// All valid positive values have the fourth most significant bit as 0.
|
||||
// By checking this bit, the two most significant bits can be determined.
|
||||
new_power8 = (new_power8 & 0x30) != 0 ? (new_power8 | 0xC0) : new_power8;
|
||||
|
||||
if (m_state > STATE_IDLE)
|
||||
{
|
||||
// radio must be idle to change the tx power
|
||||
return false;
|
||||
}
|
||||
|
||||
m_tx_power = new_power8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for selecting a timer resource.
|
||||
* This function may be called directly, or through dtm_cmd() specifying
|
||||
* DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq
|
||||
*
|
||||
* @param[in] new_timer Timer id for the timer to use: 0, 1, or 2.
|
||||
*
|
||||
* @return true if the timer was successfully changed, false otherwise.
|
||||
*/
|
||||
bool dtm_set_timer(uint32_t new_timer)
|
||||
{
|
||||
if (m_state > STATE_IDLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return dtm_hw_set_timer(&mp_timer, &m_timer_irq, new_timer);
|
||||
}
|
||||
|
||||
/// @}
|
||||
#endif // NRF_MODULE_ENABLED(BLE_DTM)
|
|
@ -0,0 +1,237 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ble_dtm DTM - Direct Test Mode
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Module for testing RF/PHY using DTM commands.
|
||||
*/
|
||||
|
||||
#ifndef BLE_DTM_H__
|
||||
#define BLE_DTM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Configuration parameters. */
|
||||
#define DTM_BITRATE UARTE_BAUDRATE_BAUDRATE_Baud19200 /**< Serial bitrate on the UART */
|
||||
#define DEFAULT_TX_POWER RADIO_TXPOWER_TXPOWER_0dBm /**< Default Transmission power using in the DTM module. */
|
||||
#define DEFAULT_TIMER NRF_TIMER0 /**< Default timer used for timing. */
|
||||
#define DEFAULT_TIMER_IRQn TIMER0_IRQn /**< IRQ used for timer. NOTE: MUST correspond to DEFAULT_TIMER. */
|
||||
|
||||
/**@brief BLE DTM command codes. */
|
||||
typedef uint32_t dtm_cmd_t; /**< DTM command type. */
|
||||
|
||||
#define LE_TEST_SETUP 0 /**< DTM command: Set PHY or modulation, configure upper two bits of length,
|
||||
request matrix of supported features or request max values of parameters. */
|
||||
#define LE_RECEIVER_TEST 1 /**< DTM command: Start receive test. */
|
||||
#define LE_TRANSMITTER_TEST 2 /**< DTM command: Start transmission test. */
|
||||
#define LE_TEST_END 3 /**< DTM command: End test and send packet report. */
|
||||
|
||||
#define LE_TEST_SETUP_RESET 0 /**< DTM command parameter: Stop TX/RX, reset the packet length upper bits and set the PHY to 1Mbit. */
|
||||
#define LE_TEST_SETUP_SET_UPPER 1 /**< DTM command parameter: Set the upper two bits of the length field. */
|
||||
#define LE_TEST_SETUP_SET_PHY 2 /**< DTM command parameter: Select the PHY to be used for packets. */
|
||||
#define LE_TEST_SETUP_SELECT_MODULATION 3 /**< DTM command parameter: Select standard or stable modulation index. Stable modulation index is not supported. */
|
||||
#define LE_TEST_SETUP_READ_SUPPORTED 4 /**< DTM command parameter: Read the supported test case features. */
|
||||
#define LE_TEST_SETUP_READ_MAX 5 /**< DTM command parameter: Read the max supported time and length for packets. */
|
||||
|
||||
#define LE_PHY_1M 1 /**< DTM command parameter: Set PHY for future packets to use 1MBit PHY. */
|
||||
#define LE_PHY_2M 2 /**< DTM command parameter: Set PHY for future packets to use 2MBit PHY. */
|
||||
#define LE_PHY_LE_CODED_S8 3 /**< DTM command parameter: Set PHY for future packets to use coded PHY with S=8. */
|
||||
#define LE_PHY_LE_CODED_S2 4 /**< DTM command parameter: Set PHY for future packets to use coded PHY with S=2 */
|
||||
|
||||
// Configuration options used as parameter 2
|
||||
// when cmd == LE_TRANSMITTER_TEST and payload == DTM_PKT_VENDORSPECIFIC
|
||||
// Configuration value, if any, is supplied in parameter 3
|
||||
|
||||
#define CARRIER_TEST 0 /**< Length=0 indicates a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
|
||||
#define CARRIER_TEST_STUDIO 1 /**< nRFgo Studio uses value 1 in length field, to indicate a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
|
||||
#define SET_TX_POWER 2 /**< Set transmission power, value -40..+4 dBm in steps of 4 */
|
||||
#define SELECT_TIMER 3 /**< Select on of the 16 MHz timers 0, 1 or 2 */
|
||||
|
||||
#define LE_PACKET_REPORTING_EVENT 0x8000 /**< DTM Packet reporting event, returned by the device to the tester. */
|
||||
#define LE_TEST_STATUS_EVENT_SUCCESS 0x0000 /**< DTM Status event, indicating success. */
|
||||
#define LE_TEST_STATUS_EVENT_ERROR 0x0001 /**< DTM Status event, indicating an error. */
|
||||
|
||||
#define DTM_PKT_PRBS9 0x00 /**< Bit pattern PRBS9. */
|
||||
#define DTM_PKT_0X0F 0x01 /**< Bit pattern 11110000 (LSB is the leftmost bit). */
|
||||
#define DTM_PKT_0X55 0x02 /**< Bit pattern 10101010 (LSB is the leftmost bit). */
|
||||
#define DTM_PKT_0XFF 0x03 /**< Bit pattern 11111111 (Used only for coded PHY). */
|
||||
#define DTM_PKT_VENDORSPECIFIC 0x03 /**< Vendor specific PKT field value. Nordic: Continuous carrier test, or configuration. */
|
||||
#define DTM_PKT_TYPE_VENDORSPECIFIC 0xFF /**< Vendor specific packet type for internal use. */
|
||||
|
||||
// The pdu payload type for each bit pattern. Identical to the PKT value except pattern 0xFF which is 0x04.
|
||||
#define DTM_PDU_TYPE_PRBS9 0x00 /**< PDU payload type for bit pattern PRBS9. */
|
||||
#define DTM_PDU_TYPE_0X0F 0x01 /**< PDU payload type for bit pattern 11110000 (LSB is the leftmost bit). */
|
||||
#define DTM_PDU_TYPE_0X55 0x02 /**< PDU payload type for bit pattern 10101010 (LSB is the leftmost bit). */
|
||||
#define DTM_PDU_TYPE_0XFF 0x04 /**< PDU payload type for bit pattern 11111111 (Used only for coded PHY). */
|
||||
|
||||
/**@brief Return codes from dtm_cmd(). */
|
||||
#define DTM_SUCCESS 0x00 /**< Indicate that the DTM function completed with success. */
|
||||
#define DTM_ERROR_ILLEGAL_CHANNEL 0x01 /**< Physical channel number must be in the range 0..39. */
|
||||
#define DTM_ERROR_INVALID_STATE 0x02 /**< Sequencing error: Command is not valid now. */
|
||||
#define DTM_ERROR_ILLEGAL_LENGTH 0x03 /**< Payload size must be in the range 0..37. */
|
||||
#define DTM_ERROR_ILLEGAL_CONFIGURATION 0x04 /**< Parameter out of range (legal range is function dependent). */
|
||||
#define DTM_ERROR_UNINITIALIZED 0x05 /**< DTM module has not been initialized by the application. */
|
||||
|
||||
/**@details The UART poll cycle in micro seconds.
|
||||
* A baud rate of e.g. 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control,
|
||||
* give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us.
|
||||
* To ensure no loss of bytes, the UART should be polled every 260 us.
|
||||
*/
|
||||
#if DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud9600
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/9600/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud14400
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/14400/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud19200
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/19200/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud28800
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/28800/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud38400
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/38400/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud57600
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/57600/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud76800
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/768000/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud115200
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/115200/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud230400
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/230400/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud250000
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/250000/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud460800
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/460800/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud921600
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/921600/2))
|
||||
#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud1M
|
||||
#define UART_POLL_CYCLE ((uint32_t)(10*1e6/1e6/2))
|
||||
#else
|
||||
// It is possible to find values that work for other baud rates, but the formula above is not
|
||||
// guaranteed to work for all values. Suitable values may have to be found by trial and error.
|
||||
#error "Unsupported baud rate set."
|
||||
#endif
|
||||
|
||||
// Note: DTM_PKT_VENDORSPECIFIC, is not a packet type
|
||||
#define PACKET_TYPE_MAX DTM_PKT_0XFF /**< Highest value allowed as DTM Packet type. */
|
||||
|
||||
/** @brief BLE DTM event type. */
|
||||
typedef uint32_t dtm_event_t; /**< Type for handling DTM event. */
|
||||
|
||||
/** @brief BLE DTM frequency type. */
|
||||
typedef uint32_t dtm_freq_t; /**< Physical channel, valid range: 0..39. */
|
||||
|
||||
/**@brief BLE DTM packet types. */
|
||||
typedef uint32_t dtm_pkt_type_t; /**< Type for holding the requested DTM payload type.*/
|
||||
|
||||
|
||||
/**@brief Function for initializing or re-initializing DTM module
|
||||
*
|
||||
* @return DTM_SUCCESS on successful initialization of the DTM module.
|
||||
*/
|
||||
uint32_t dtm_init(void);
|
||||
|
||||
|
||||
/**@brief Function for giving control to dtmlib for handling timer and radio events.
|
||||
* Will return to caller at 625us intervals or whenever another event than radio occurs
|
||||
* (such as UART input). Function will put MCU to sleep between events.
|
||||
*
|
||||
* @return Time counter, incremented every 625 us.
|
||||
*/
|
||||
uint32_t dtm_wait(void);
|
||||
|
||||
|
||||
/**@brief Function for calling when a complete command has been prepared by the Tester.
|
||||
*
|
||||
* @param[in] cmd One of the DTM_CMD values (bits 14:15 in the 16-bit UART format).
|
||||
* @param[in] freq Phys. channel no - actual frequency = (2402 + freq * 2) MHz (bits 8:13 in
|
||||
* the 16-bit UART format).
|
||||
* @param[in] length Payload length, 0..37 (bits 2:7 in the 16-bit UART format).
|
||||
* @param[in] payload One of the DTM_PKT values (bits 0:1 in the 16-bit UART format).
|
||||
*
|
||||
* @return DTM_SUCCESS or one of the DTM_ERROR_ values
|
||||
*/
|
||||
uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload);
|
||||
|
||||
|
||||
/**@brief Function for reading the result of a DTM command
|
||||
*
|
||||
* @param[out] p_dtm_event Pointer to buffer for 16 bit event code according to DTM standard.
|
||||
*
|
||||
* @return true: new event, false: no event since last call, this event has been read earlier
|
||||
*/
|
||||
bool dtm_event_get(dtm_event_t * p_dtm_event);
|
||||
|
||||
|
||||
/**@brief Function for configuring the timer to use.
|
||||
*
|
||||
* @note Must be called when no DTM test is running.
|
||||
*
|
||||
* @param[in] new_timer Index (0..2) of timer to be used by the DTM library
|
||||
*
|
||||
* @return true: success, new timer was selected, false: parameter error
|
||||
*/
|
||||
bool dtm_set_timer(uint32_t new_timer);
|
||||
|
||||
|
||||
/**@brief Function for configuring the transmit power.
|
||||
*
|
||||
* @note Must be called when no DTM test is running.
|
||||
*
|
||||
* @param[in] new_tx_power New output level, +4..-40, in steps of 4.
|
||||
*
|
||||
* @return true: tx power setting changed, false: parameter error
|
||||
*/
|
||||
bool dtm_set_txpower(uint32_t new_tx_power);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_DTM_H__
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ble_dtm_hw Direct Test Mode HW
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Module contains hardware related function for testing RF/PHY using DTM commands.
|
||||
*/
|
||||
|
||||
#ifndef BLE_DTM_HW_H__
|
||||
#define BLE_DTM_HW_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**@brief Function for selecting a timer resource.
|
||||
* This function may be called directly, or through dtm_cmd() specifying
|
||||
* DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq
|
||||
*
|
||||
* @param[out] mp_timer Pointer to timer instance used in dtm source file.
|
||||
* @param[out] m_timer_irq Pointer to timer interrupt related to mp_timer.
|
||||
* @param[in] new_timer Timer id for the timer to use.
|
||||
*
|
||||
* @retval true if the timer was successfully changed.
|
||||
* @retval false if the error occurs.
|
||||
*/
|
||||
|
||||
bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer);
|
||||
|
||||
|
||||
/**@brief Function for turning off radio test.
|
||||
* This function is platform depending. For now only nRF51 requieres this special function.
|
||||
*/
|
||||
void dtm_turn_off_test(void);
|
||||
|
||||
|
||||
/**@brief Function for setting constant carrier in radio settings.
|
||||
* This function is used to handle vendor specific command testing continous carrier without
|
||||
* a modulated signal.
|
||||
*/
|
||||
void dtm_constant_carrier(void);
|
||||
|
||||
|
||||
/**@brief Function for validating tx power and radio move settings.
|
||||
* @param[in] m_tx_power TX power for transmission test.
|
||||
* @param[in] m_radio_mode Radio mode value.
|
||||
*
|
||||
* @retval DTM_SUCCESS if input parameters values are correct.
|
||||
* @retval DTM_ERROR_ILLEGAL_CONFIGURATION if input parameters values are not correct.
|
||||
*/
|
||||
uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_DTM_HW_H__
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "ble_dtm_hw.h"
|
||||
#include "ble_dtm.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "nrf.h"
|
||||
|
||||
|
||||
void dtm_turn_off_test()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void dtm_constant_carrier()
|
||||
{
|
||||
NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) |
|
||||
(RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos);
|
||||
}
|
||||
|
||||
|
||||
uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode)
|
||||
{
|
||||
// Initializing code below is quite generic - for BLE, the values are fixed, and expressions
|
||||
// are constant. Non-constant values are essentially set in radio_prepare().
|
||||
if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Pos3dBm ||
|
||||
m_tx_power == RADIO_TXPOWER_TXPOWER_Neg40dBm
|
||||
) ||
|
||||
|
||||
!(
|
||||
#ifdef NRF52840_XXAA
|
||||
m_radio_mode == RADIO_MODE_MODE_Ble_LR125Kbit ||
|
||||
m_radio_mode == RADIO_MODE_MODE_Ble_LR500Kbit ||
|
||||
#endif //NRF52840_XXAA
|
||||
m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit ||
|
||||
m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit
|
||||
)
|
||||
)
|
||||
{
|
||||
return DTM_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
|
||||
return DTM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer)
|
||||
{
|
||||
if (new_timer == 0)
|
||||
{
|
||||
*mp_timer = NRF_TIMER0;
|
||||
*m_timer_irq = TIMER0_IRQn;
|
||||
}
|
||||
else if (new_timer == 1)
|
||||
{
|
||||
*mp_timer = NRF_TIMER1;
|
||||
*m_timer_irq = TIMER1_IRQn;
|
||||
}
|
||||
else if (new_timer == 2)
|
||||
{
|
||||
*mp_timer = NRF_TIMER2;
|
||||
*m_timer_irq = TIMER2_IRQn;
|
||||
}
|
||||
#ifndef NRF52810_XXAA
|
||||
else if (new_timer == 3)
|
||||
{
|
||||
*mp_timer = NRF_TIMER3;
|
||||
*m_timer_irq = TIMER3_IRQn;
|
||||
}
|
||||
else if (new_timer == 4)
|
||||
{
|
||||
*mp_timer = NRF_TIMER4;
|
||||
*m_timer_irq = TIMER4_IRQn;
|
||||
}
|
||||
#endif //NRF52810_XXAA
|
||||
else
|
||||
{
|
||||
// Parameter error: Only TIMER 0, 1, 2, 3 and 4 provided by nRF52
|
||||
return false;
|
||||
}
|
||||
// New timer has been selected:
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(BLE_RACP)
|
||||
#include "ble_racp.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void ble_racp_decode(uint8_t data_len, uint8_t const * p_data, ble_racp_value_t * p_racp_val)
|
||||
{
|
||||
p_racp_val->opcode = 0xFF;
|
||||
p_racp_val->operator = 0xFF;
|
||||
p_racp_val->operand_len = 0;
|
||||
p_racp_val->p_operand = NULL;
|
||||
|
||||
if (data_len > 0)
|
||||
{
|
||||
p_racp_val->opcode = p_data[0];
|
||||
}
|
||||
if (data_len > 1)
|
||||
{
|
||||
p_racp_val->operator = p_data[1]; //lint !e415
|
||||
}
|
||||
if (data_len > 2)
|
||||
{
|
||||
p_racp_val->operand_len = data_len - 2;
|
||||
p_racp_val->p_operand = (uint8_t*)&p_data[2]; //lint !e416
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data)
|
||||
{
|
||||
uint8_t len = 0;
|
||||
int i;
|
||||
|
||||
if (p_data != NULL)
|
||||
{
|
||||
p_data[len++] = p_racp_val->opcode;
|
||||
p_data[len++] = p_racp_val->operator;
|
||||
|
||||
for (i = 0; i < p_racp_val->operand_len; i++)
|
||||
{
|
||||
p_data[len++] = p_racp_val->p_operand[i];
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif // NRF_MODULE_ENABLED(BLE_RACP)
|
|
@ -0,0 +1,135 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ble_racp Record Access Control Point
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Record Access Control Point library.
|
||||
*/
|
||||
|
||||
#ifndef BLE_RACP_H__
|
||||
#define BLE_RACP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf_ble.h"
|
||||
#include "ble_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Record Access Control Point opcodes. */
|
||||
#define RACP_OPCODE_RESERVED 0 /**< Record Access Control Point opcode - Reserved for future use. */
|
||||
#define RACP_OPCODE_REPORT_RECS 1 /**< Record Access Control Point opcode - Report stored records. */
|
||||
#define RACP_OPCODE_DELETE_RECS 2 /**< Record Access Control Point opcode - Delete stored records. */
|
||||
#define RACP_OPCODE_ABORT_OPERATION 3 /**< Record Access Control Point opcode - Abort operation. */
|
||||
#define RACP_OPCODE_REPORT_NUM_RECS 4 /**< Record Access Control Point opcode - Report number of stored records. */
|
||||
#define RACP_OPCODE_NUM_RECS_RESPONSE 5 /**< Record Access Control Point opcode - Number of stored records response. */
|
||||
#define RACP_OPCODE_RESPONSE_CODE 6 /**< Record Access Control Point opcode - Response code. */
|
||||
|
||||
/**@brief Record Access Control Point operators. */
|
||||
#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */
|
||||
#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */
|
||||
#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */
|
||||
#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */
|
||||
#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */
|
||||
#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */
|
||||
#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */
|
||||
#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */
|
||||
|
||||
/**@brief Record Access Control Point Operand Filter Type Value. */
|
||||
#define RACP_OPERAND_FILTER_TYPE_TIME_OFFSET 1 /**< Record Access Control Point Operand Filter Type Value - Time Offset- */
|
||||
|
||||
/**@brief Record Access Control Point response codes. */
|
||||
#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */
|
||||
#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */
|
||||
#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */
|
||||
#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */
|
||||
#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */
|
||||
#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */
|
||||
#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */
|
||||
#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */
|
||||
#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */
|
||||
#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */
|
||||
|
||||
/**@brief Record Access Control Point value structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t opcode; /**< Op Code. */
|
||||
uint8_t operator; /**< Operator. */
|
||||
uint8_t operand_len; /**< Length of the operand. */
|
||||
uint8_t * p_operand; /**< Pointer to the operand. */
|
||||
} ble_racp_value_t;
|
||||
|
||||
/**@brief Function for decoding a Record Access Control Point write.
|
||||
*
|
||||
* @details This call decodes a write to the Record Access Control Point.
|
||||
*
|
||||
* @param[in] data_len Length of data in received write.
|
||||
* @param[in] p_data Pointer to received data.
|
||||
* @param[out] p_racp_val Pointer to decoded Record Access Control Point write.
|
||||
* @note This does not do a data copy. It assumes the data pointed to by
|
||||
* p_data is persistant until no longer needed.
|
||||
*/
|
||||
void ble_racp_decode(uint8_t data_len, uint8_t const * p_data, ble_racp_value_t * p_racp_val);
|
||||
|
||||
/**@brief Function for encoding a Record Access Control Point response.
|
||||
*
|
||||
* @details This call encodes a response from the Record Access Control Point response.
|
||||
*
|
||||
* @param[in] p_racp_val Pointer to Record Access Control Point to encode.
|
||||
* @param[out] p_data Pointer to where encoded data is written.
|
||||
* NOTE! It is calling routines respsonsibility to make sure.
|
||||
*
|
||||
* @return Length of encoded data.
|
||||
*/
|
||||
uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_RACP_H__
|
||||
|
||||
/** @} */
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ble_radio_notification.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nrf_nvic.h"
|
||||
|
||||
static bool m_radio_active = false; /**< Current radio state. */
|
||||
static ble_radio_notification_evt_handler_t m_evt_handler = NULL; /**< Application event handler for handling Radio Notification events. */
|
||||
|
||||
|
||||
void SWI1_IRQHandler(void)
|
||||
{
|
||||
m_radio_active = !m_radio_active;
|
||||
if (m_evt_handler != NULL)
|
||||
{
|
||||
m_evt_handler(m_radio_active);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t ble_radio_notification_init(uint32_t irq_priority,
|
||||
uint8_t distance,
|
||||
ble_radio_notification_evt_handler_t evt_handler)
|
||||
{
|
||||
uint32_t err_code;
|
||||
|
||||
m_evt_handler = evt_handler;
|
||||
|
||||
// Initialize Radio Notification software interrupt
|
||||
err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
// Configure the event
|
||||
return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup ble_radio_notification Radio Notification Event Handler
|
||||
* @{
|
||||
* @ingroup ble_sdk_lib
|
||||
* @brief Module for propagating Radio Notification events to the application.
|
||||
*/
|
||||
|
||||
#ifndef BLE_RADIO_NOTIFICATION_H__
|
||||
#define BLE_RADIO_NOTIFICATION_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Application radio notification event handler type. */
|
||||
typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active);
|
||||
|
||||
/**@brief Function for initializing the Radio Notification module.
|
||||
*
|
||||
* @param[in] irq_priority Interrupt priority for the Radio Notification interrupt handler.
|
||||
* @param[in] distance The time from an Active event until the radio is activated.
|
||||
* @param[in] evt_handler Handler to be executed when a radio notification event has been
|
||||
* received.
|
||||
*
|
||||
* @return NRF_SUCCESS on successful initialization, otherwise an error code.
|
||||
*/
|
||||
uint32_t ble_radio_notification_init(uint32_t irq_priority,
|
||||
uint8_t distance,
|
||||
ble_radio_notification_evt_handler_t evt_handler);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BLE_RADIO_NOTIFICATION_H__
|
||||
|
||||
/** @} */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue