Official Sheffield ARMBand micro:bit program

Files at this revision

API Documentation at this revision

Comitter:
MrBedfordVan
Date:
Mon Oct 17 12:41:20 2016 +0000
Commit message:
Official Sheffield ARMBand Micro:bit program

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/LICENSE Show annotated file Show diff for this revision Revisions of this file
microbit/README.md Show annotated file Show diff for this revision Revisions of this file
microbit/inc/MicroBit.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/AUTHORS Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/.gitignore Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/CONTRIBUTING.md Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/DOXYGEN_FRONTPAGE.md Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/LICENSE Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/README.md Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/apache-2.0.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble.doxyfile Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/BLE.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/BLEInstanceBase.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/BLEProtocol.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/CallChainOfFunctionPointersWithContext.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/CharacteristicDescriptorDiscovery.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/DiscoveredCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/DiscoveredCharacteristicDescriptor.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/DiscoveredService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/FunctionPointerWithContext.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/Gap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GapAdvertisingData.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GapAdvertisingParams.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GapEvents.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GapScanningParams.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattAttribute.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattCallbackParamTypes.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattClient.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattServer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattServerEvents.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/GattService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/SafeBool.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/SecurityManager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/ServiceDiscovery.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/UUID.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/blecommon.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/deprecate.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/BatteryService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/DFUService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/DeviceInformationService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/EddystoneConfigService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/EddystoneService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/EnvironmentalService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/HealthThermometerService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/HeartRateService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/LinkLossService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/UARTService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/URIBeaconConfigService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/ble/services/iBeacon.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/module.json Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/BLE.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/DiscoveredCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/GapScanningParams.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/services/DFUService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/services/UARTService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/BLE_API/source/services/URIBeaconConfigService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/LICENSE Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/README.md Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/ExternalEvents.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MESEvents.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitAccelerometerService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitBLEManager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitButtonService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitDFUService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitEventService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitIOPinService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitLEDService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitMagnetometerService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitTemperatureService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/bluetooth/MicroBitUARTService.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/ErrorNo.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/EventModel.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MemberFunctionCallback.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitCompat.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitComponent.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitConfig.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitDevice.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitFiber.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitFont.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitHeapAllocator.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitListener.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/MicroBitSystemTimer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/core/NotifyEvents.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/DynamicPwm.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitAccelerometer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitButton.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitCompass.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitCompassCalibrator.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitDisplay.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitI2C.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitIO.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitLightSensor.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitMatrixMaps.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitMessageBus.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitMultiButton.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitPin.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitRadio.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitRadioDatagram.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitRadioEvent.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitSerial.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitStorage.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/MicroBitThermometer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/drivers/TimedInterruptIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/platform/yotta_cfg_mappings.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/ManagedString.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/ManagedType.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/Matrix4.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/MicroBitCoordinateSystem.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/MicroBitEvent.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/MicroBitImage.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/PacketBuffer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/inc/types/RefCounted.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/AnalogIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/AnalogOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/BusIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/BusInOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/BusOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/CAN.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/CThunk.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/CallChain.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/CircularBuffer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/DigitalIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/DigitalInOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/DigitalOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/DirHandle.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Ethernet.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FileBase.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FileHandle.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FileLike.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FilePath.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FileSystemLike.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/FunctionPointer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/I2C.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/I2CSlave.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/InterruptIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/InterruptManager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/LocalFileSystem.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/LowPowerTicker.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/LowPowerTimeout.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/LowPowerTimer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/PortIn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/PortInOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/PortOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/PwmOut.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/RawSerial.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/SPI.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/SPISlave.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Serial.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/SerialBase.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Stream.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/crc16/crc16.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/scheduler/app_scheduler.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/util/app_error.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/util/app_util.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/s110_nrf51822_8_0_0/s110_nrf51822_8.0.0_softdevice.hex Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/s130_nrf51822_1_0_0/s130_nrf51_1.0.0_softdevice.hex Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/PeripheralNames.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/PortNames.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/PinNames.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/device.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_object.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/objects.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_config.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_master.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/.archive_files.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/board.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/cmsis_nvic.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/mbed.ar Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/nRF51822.sct Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/retarget.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/startup_nRF51822.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/sys.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/system_nrf51.o Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/cmsis.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/cmsis_nvic.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/compiler_abstraction.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_ca9.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_caFunc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_caInstr.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_ca_mmu.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm0.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm0plus.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm3.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm4.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm4_simd.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm7.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmFunc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmInstr.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmSimd.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf51.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf51_bitfields.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf_delay.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/system_nrf51.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Ticker.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Timeout.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Timer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/TimerEvent.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/Transaction.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/analogin_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/analogout_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/buffer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/can_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/can_helper.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/dma_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/ethernet_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/gpio_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/gpio_irq_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/i2c_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/lp_ticker_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/mbed.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/mbed_assert.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/mbed_debug.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/mbed_error.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/mbed_interface.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/pinmap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/platform.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/port_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/pwmout_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/rtc_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/rtc_time.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/semihost_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/serial_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/sleep_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/spi_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/ticker_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/toolchain.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/us_ticker_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/mbed-dev-bin/wait_api.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/module.json Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/LICENSE Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/apache-2.0.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/bootloader/s110_nrf51822_8.0.0_bootloader.hex Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/bootloader/s130_nrf51_1.0.0_bootloader.hex Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/bootloader/softdevice_nrf51822_licence_agreement.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/module.json Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/BSD-3clause-Nordic.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/LICENSE Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/README.md Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/module.json Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/script/copyright_header.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/script/pick_nrf51_files.py Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/script/replace_headers.py Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/script/required_files.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_radio_notification/ble_radio_notification.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_radio_notification/ble_radio_notification.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_services/ble_dfu/ble_dfu.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_services/ble_dfu/ble_dfu.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_advdata.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_advdata.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_params.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_params.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_state.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_state.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_date_time.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_gatt_db.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_sensor_location.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_srv_common.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_srv_common.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/config/device_manager_cnfg.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/device_manager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/device_manager_peripheral.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/id_manager.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/id_manager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data_storage.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data_storage.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_database.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_database.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_id.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_id.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_manager_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_buffer.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_buffer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_mutex.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_mutex.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/compiler_abstraction.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51_bitfields.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51_deprecated.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/ble_flash/ble_flash.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/ble_flash/ble_flash.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/delay/nrf_delay.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/delay/nrf_delay.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_ecb.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_ecb.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_gpio.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_gpiote.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_nvmc.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_nvmc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_temp.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_wdt.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/config/pstorage_platform.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/pstorage.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/pstorage.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_util.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_util.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_app_handler.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_app_handler.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_bank_internal.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_ble_svc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_init.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_init_template.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_transport.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/crc16/crc16.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/crc16/crc16.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/experimental_section_vars/section_vars.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds_config.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds_types_internal.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage_config.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage_nosd.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/hci/hci_mem_pool.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/hci/hci_mem_pool.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/scheduler/app_scheduler.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/scheduler/app_scheduler.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/timer/app_timer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_error.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_error.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util_platform.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util_platform.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/common.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nordic_common.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nrf_assert.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nrf_assert.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_common.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_errors.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_mapped_flags.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_mapped_flags.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_os.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_err.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gatt.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gattc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gatts.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_hci.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_l2cap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_ranges.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_types.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error_sdm.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error_soc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_mbr.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_sdm.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_soc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_svc.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/softdevice_assert.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/nrf51-sdk/source/supress-warnings.cmake Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/softdevice_nrf51822_licence_agreement.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_advertising.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_advertising.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_discovery.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_discovery.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_gap.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_gap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_security.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/btle_security.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/custom/custom_helper.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/btle/custom/custom_helper.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/ansi_escape.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/assertion.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/binary.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/ble_error.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/common.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/common/compiler.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xCharacteristicDescriptorDiscoverer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xCharacteristicDescriptorDiscoverer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xDiscoveredCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xDiscoveredCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGap.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGap.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGattClient.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGattClient.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGattServer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xGattServer.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xSecurityManager.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xServiceDiscovery.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xServiceDiscovery.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xn.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/nRF5xn.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/projectconfig.h Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/nRF51822/source/supress-warnings.cmake Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/CMakeLists.txt Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/asm/CortexContextSwitch.s Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/asm/CortexContextSwitch.s.armcc Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/asm/CortexContextSwitch.s.gcc Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitAccelerometerService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitBLEManager.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitButtonService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitDFUService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitEventService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitIOPinService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitLEDService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitMagnetometerService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitTemperatureService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/bluetooth/MicroBitUARTService.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MemberFunctionCallback.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitCompat.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitDevice.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitFiber.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitFont.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitHeapAllocator.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitListener.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/core/MicroBitSystemTimer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/DynamicPwm.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitAccelerometer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitButton.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitCompass.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitCompassCalibrator.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitI2C.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitIO.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitLightSensor.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitMessageBus.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitMultiButton.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitPin.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitRadio.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitRadioDatagram.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitRadioEvent.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitSerial.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitStorage.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/MicroBitThermometer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/drivers/TimedInterruptIn.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/ManagedString.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/Matrix4.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/MicroBitEvent.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/MicroBitImage.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/PacketBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/microbit-dal/source/types/RefCounted.cpp Show annotated file Show diff for this revision Revisions of this file
microbit/module.json Show annotated file Show diff for this revision Revisions of this file
microbit/source/MicroBit.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,19 @@
+/*
+The Spooky ARM Band Micro:bit display program
+*/
+
+#include "MicroBit.h"
+
+MicroBit uBit;
+
+int main()
+{
+    // Initialise the micro:bit runtime.
+    uBit.init();
+
+    while(1) {
+      uBit.display.scroll("ARMBand");
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/LICENSE	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/README.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+# microbit
+
+A collection of the commonly used components of the micro:bit runtime with a
+standard configuration, to provide an easy to use interface for programming the micro:bit in C/C++.
+
+## Overview
+
+The micro:bit runtime provides an easy to use environment for programming the BBC micro:bit in the C/C++ language, written by Lancaster University. It contains device drivers for all the hardware capabilities of the micro:bit, and also a suite of runtime mechanisms to make programming the micro:bit easier and more flexible. These range from control of the LED matrix display to peer-to-peer radio communication and secure Bluetooth Low Energy services. The micro:bit runtime is proudly built on the ARM mbed and Nordic nrf51 platforms.
+
+In addition to supporting development in C/C++, the runtime is also designed specifically to support higher level languages provided by our partners that target the micro:bit. It is currently used as a support library for all the languages on the BBC www.microbit.co.uk website, including Microsoft Block, Microsoft TouchDevelop, Code Kingdoms JavaScript and Micropython languages.
+
+## Links
+
+[micro:bit runtime docs](http://lancaster-university.github.io/microbit-docs/) | [microbit-dal](https://github.com/lancaster-university/microbit-dal) |  [samples](https://github.com/lancaster-university/microbit-samples)
+
+## Build Environments
+
+| Build Environment | Documentation |
+| ------------- |-------------|
+| ARM mbed online | http://lancaster-university.github.io/microbit-docs/online-toolchains/#mbed |
+| yotta  | http://lancaster-university.github.io/microbit-docs/offline-toolchains/#yotta |
+
+
+
+## Hello World!
+
+```cpp
+#include "MicroBit.h"
+
+MicroBit uBit;
+
+int main()
+{
+    uBit.init();
+
+    uBit.display.scroll("Hello world!");
+}
+```
+
+## BBC Community Guidelines
+
+[BBC Community Guidelines](https://www.microbit.co.uk/help#sect_cg)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/inc/MicroBit.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,658 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_H
+#define MICROBIT_H
+
+#include "mbed.h"
+
+#include "MicroBitConfig.h"
+#include "MicroBitHeapAllocator.h"
+#include "MicroBitDevice.h"
+#include "ErrorNo.h"
+#include "MicroBitSystemTimer.h"
+#include "Matrix4.h"
+#include "MicroBitCompat.h"
+#include "MicroBitComponent.h"
+#include "ManagedType.h"
+#include "ManagedString.h"
+#include "MicroBitImage.h"
+#include "MicroBitFont.h"
+#include "MicroBitEvent.h"
+#include "DynamicPwm.h"
+#include "MicroBitI2C.h"
+#include "NotifyEvents.h"
+
+#include "MicroBitButton.h"
+#include "MicroBitPin.h"
+#include "MicroBitCompass.h"
+#include "MicroBitCompassCalibrator.h"
+#include "MicroBitAccelerometer.h"
+#include "MicroBitThermometer.h"
+#include "MicroBitLightSensor.h"
+#include "MicroBitMultiButton.h"
+
+#include "MicroBitSerial.h"
+#include "MicroBitIO.h"
+#include "MicroBitMatrixMaps.h"
+#include "MicroBitDisplay.h"
+
+#include "MicroBitFiber.h"
+#include "MicroBitMessageBus.h"
+
+#include "MicroBitBLEManager.h"
+#include "MicroBitRadio.h"
+#include "MicroBitStorage.h"
+
+// MicroBit::flags values
+#define MICROBIT_INITIALIZED                    0x01
+
+/**
+  * Class definition for a MicroBit device.
+  *
+  * Represents the device as a whole, and includes member variables that represent various device drivers
+  * used to control aspects of the micro:bit.
+  */
+class MicroBit
+{
+    private:
+
+    /**
+      * A listener to perform actions as a result of Message Bus reflection.
+      *
+      * In some cases we want to perform lazy instantiation of components, such as
+      * the compass and the accelerometer, where we only want to add them to the idle
+      * fiber when someone has the intention of using these components.
+      */
+    void                        onListenerRegisteredEvent(MicroBitEvent evt);
+
+    uint8_t                     status;
+
+    public:
+
+    // Serial Interface
+    MicroBitSerial              serial;
+
+	// Reset Button
+	InterruptIn     		    resetButton;
+
+    // Persistent key value store
+    MicroBitStorage             storage;
+
+    // I2C Interface
+    MicroBitI2C                 i2c;
+
+    // Device level Message Bus abstraction
+    MicroBitMessageBus          messageBus;
+
+    // Member variables to represent each of the core components on the device.
+    MicroBitDisplay             display;
+    MicroBitButton              buttonA;
+    MicroBitButton              buttonB;
+    MicroBitMultiButton         buttonAB;
+    MicroBitAccelerometer       accelerometer;
+    MicroBitCompass             compass;
+    MicroBitCompassCalibrator   compassCalibrator;
+    MicroBitThermometer         thermometer;
+
+    //An object of available IO pins on the device
+    MicroBitIO                  io;
+
+    // Bluetooth related member variables.
+	MicroBitBLEManager		    bleManager;
+    MicroBitRadio               radio;
+    BLEDevice                   *ble;
+
+    /**
+      * Constructor.
+      *
+      * Create a representation of a MicroBit device, which includes member variables
+      * that represent various device drivers used to control aspects of the micro:bit.
+      */
+    MicroBit();
+
+    /**
+      * Post constructor initialisation method.
+      *
+      * This call will initialised the scheduler, memory allocator and Bluetooth stack.
+      *
+      * This is required as the Bluetooth stack can't be brought up in a
+      * static context i.e. in a constructor.
+      *
+      * @code
+      * uBit.init();
+      * @endcode
+      *
+      * @note This method must be called before user code utilises any functionality
+      *       contained by uBit.
+      */
+    void init();
+
+    /**
+      * Return the friendly name for this device.
+      *
+      * @return A ManagedString representing the friendly name of this device.
+      *
+      * @code
+      * ManagedString name = uBit.getName();
+      * @endcode
+      */
+    static ManagedString getName();
+
+    /**
+      * Return the serial number of this device.
+      *
+      * @return A ManagedString representing the serial number of this device.
+      *
+      * @code
+      * ManagedString serialNumber = uBit.getSerial();
+      * @endcode
+      */
+    static ManagedString getSerial();
+
+    /**
+      * Will reset the micro:bit when called.
+      *
+      * @code
+      * uBit.reset();
+      * @endcode
+      */
+    void reset();
+
+    /**
+      * Delay execution for the given amount of time.
+      *
+      * If the scheduler is running, this will deschedule the current fiber and perform
+      * a power efficient, concurrent sleep operation.
+      *
+      * If the scheduler is disabled or we're running in an interrupt context, this
+      * will revert to a busy wait.
+      *
+      * Alternatively: wait, wait_ms, wait_us can be used which will perform a blocking sleep
+      * operation.
+      *
+      * @param milliseconds the amount of time, in ms, to wait for. This number cannot be negative.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER milliseconds is less than zero.
+      *
+      * @code
+      * uBit.sleep(20); //sleep for 20ms
+      * @endcode
+      *
+      * @note This operation is currently limited by the rate of the system timer, therefore
+      *       the granularity of the sleep operation is limited to 6 ms unless the rate of
+      *       the system timer is modified.
+      */
+    void sleep(uint32_t milliseconds);
+
+    /**
+      * Seed the pseudo random number generator using the hardware random number generator.
+      *
+      * @code
+      * uBit.seedRandom();
+      * @endcode
+      */
+    void seedRandom();
+
+    /**
+      * Seed the pseudo random number generator using the given value.
+      *
+      * @param seed The 32-bit value to seed the generator with.
+      *
+      * @code
+      * uBit.seedRandom(0xBB5EED);
+      * @endcode
+      */
+    void seedRandom(uint32_t seed);
+
+
+    /**
+      * Generate a random number in the given range.
+      * We use a simple Galois LFSR random number generator here,
+      * as a Galois LFSR is sufficient for our applications, and much more lightweight
+      * than the hardware random number generator built int the processor, which takes
+      * a long time and uses a lot of energy.
+      *
+      * KIDS: You shouldn't use this is the real world to generate cryptographic keys though...
+      * have a think why not. :-)
+      *
+      * @param max the upper range to generate a number for. This number cannot be negative.
+      *
+      * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0.
+      *
+      * @code
+      * uBit.random(200); //a number between 0 and 199
+      * @endcode
+      */
+    int random(int max);
+
+    /**
+      * Determine the time since this MicroBit was last reset.
+      *
+      * @return The time since the last reset, in milliseconds.
+      *
+      * @note This will value overflow after 1.6 months.
+      */
+      //TODO: handle overflow case.
+    unsigned long systemTime();
+
+    /**
+      * Determine the version of the micro:bit runtime currently in use.
+      *
+      * @return A textual description of the version of the micro:bit runtime that
+      *         is currently running on this device.
+      */
+    const char *systemVersion();
+
+    /**
+      * Triggers a microbit panic where an loop will display a panic face
+      * and the status code, if provided.
+      *
+      * This loop will continue for panic_timeout iterations, defaults to 0 (infinite).
+      *
+      * panic_timeout can be configured via a call to microbit_panic_timeout.
+      *
+      * @param statusCode the status code of the associated error.
+      *
+      * @code
+      * microbit_panic_timeout(4);
+      *
+      * // will display loop for 4 iterations.
+      * uBit.panic(10);
+      * @endcode
+      */
+    void panic(int statusCode = 0);
+
+    /**
+      * Add a component to the array of system components. This component will then receive
+      * periodic callbacks, once every tick period in interrupt context.
+      *
+      * @param component The component to add.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the component array is full.
+      *
+      * @code
+      * // heap allocated - otherwise it will be paged out!
+      * MicroBitDisplay* display = new MicroBitDisplay();
+      *
+      * uBit.addSystemComponent(display);
+      * @endcode
+      *
+      * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_add_component().
+      */
+	int addSystemComponent(MicroBitComponent *component);
+
+    /**
+      * Remove a component from the array of system components. This component will no longer receive
+      * periodic callbacks.
+      *
+      * @param component The component to remove.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+      *
+      * @code
+      * // heap allocated - otherwise it will be paged out!
+      * MicroBitDisplay* display = new MicroBitDisplay();
+      *
+      * uBit.addSystemComponent(display);
+      *
+      * uBit.removeSystemComponent(display);
+      * @endcode
+      *
+      * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_remove_component().
+      */
+	int removeSystemComponent(MicroBitComponent *component);
+
+    /**
+      * Adds a component to the array of idle thread components, which are processed
+      * when the run queue is empty.
+      *
+      * The system timer will poll isIdleCallbackNeeded on each component to determine
+      * if the scheduler should schedule the idle_task imminently.
+      *
+      * @param component The component to add to the array.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * // heap allocated - otherwise it will be paged out!
+      * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
+      *
+      * fiber_add_idle_component(accelerometer);
+      * @endcode
+      *
+      * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_add_idle_component().
+      */
+	int addIdleComponent(MicroBitComponent *component);
+
+    /**
+      * Remove a component from the array of idle thread components
+      *
+      * @param component The component to remove from the idle component array.
+      *
+      * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * // heap allocated - otherwise it will be paged out!
+      * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
+      *
+      * uBit.addIdleComponent(accelerometer);
+      *
+      * uBit.removeIdleComponent(accelerometer);
+      * @endcode
+      *
+      * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_remove_idle_component().
+      */
+	int removeIdleComponent(MicroBitComponent *component);
+};
+
+/**
+  * Return the friendly name for this device.
+  *
+  * @return A ManagedString representing the friendly name of this device.
+  *
+  * @code
+  * ManagedString name = uBit.getName();
+  * @endcode
+  */
+inline ManagedString MicroBit::getName()
+{
+    return ManagedString(microbit_friendly_name());
+}
+
+/**
+  * Return the serial number of this device.
+  *
+  * @return A ManagedString representing the serial number of this device.
+  *
+  * @code
+  * ManagedString serialNumber = uBit.getSerial();
+  * @endcode
+  */
+inline ManagedString MicroBit::getSerial()
+{
+    // We take to 16 bit numbers here, as we want the full range of ID bits, but don't want negative numbers...
+    int n1 = microbit_serial_number() & 0xffff;
+    int n2 = (microbit_serial_number() >> 16) & 0xffff;
+
+    // Simply concat the two numbers.
+    ManagedString s1(n1);
+    ManagedString s2(n2);
+
+    return s1 + s2;
+}
+
+/**
+  * Will reset the micro:bit when called.
+  *
+  * @code
+  * uBit.reset();
+  * @endcode
+  */
+inline void MicroBit::reset()
+{
+    if(ble && ble->getGapState().connected) {
+
+        // We have a connected BLE peer. Disconnect the BLE session.
+        ble->gap().disconnect(Gap::REMOTE_USER_TERMINATED_CONNECTION);
+
+        // Wait a little while for the connection to drop.
+        wait_ms(100);
+    }
+
+    microbit_reset();
+}
+
+/**
+  * Delay execution for the given amount of time.
+  *
+  * If the scheduler is running, this will deschedule the current fiber and perform
+  * a power efficient, concurrent sleep operation.
+  *
+  * If the scheduler is disabled or we're running in an interrupt context, this
+  * will revert to a busy wait.
+  *
+  * Alternatively: wait, wait_ms, wait_us can be used which will perform a blocking sleep
+  * operation.
+  *
+  * @param milliseconds the amount of time, in ms, to wait for. This number cannot be negative.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER milliseconds is less than zero.
+  *
+  * @code
+  * uBit.sleep(20); //sleep for 20ms
+  * @endcode
+  *
+  * @note This operation is currently limited by the rate of the system timer, therefore
+  *       the granularity of the sleep operation is limited to 6 ms unless the rate of
+  *       the system timer is modified.
+  */
+inline void MicroBit::sleep(uint32_t milliseconds)
+{
+    fiber_sleep(milliseconds);
+}
+
+/**
+  * Generate a random number in the given range.
+  * We use a simple Galois LFSR random number generator here,
+  * as a Galois LFSR is sufficient for our applications, and much more lightweight
+  * than the hardware random number generator built int the processor, which takes
+  * a long time and uses a lot of energy.
+  *
+  * KIDS: You shouldn't use this is the real world to generate cryptographic keys though...
+  * have a think why not. :-)
+  *
+  * @param max the upper range to generate a number for. This number cannot be negative.
+  *
+  * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0.
+  *
+  * @code
+  * uBit.random(200); //a number between 0 and 199
+  * @endcode
+  */
+inline int MicroBit::random(int max)
+{
+    return microbit_random(max);
+}
+
+/**
+  * Seed the pseudo random number generator using the hardware random number generator.
+  *
+  * @code
+  * uBit.seedRandom();
+  * @endcode
+  */
+inline void MicroBit::seedRandom()
+{
+    microbit_seed_random();
+}
+
+
+/**
+  * Seed the pseudo random number generator using the given value.
+  *
+  * @param seed The 32-bit value to seed the generator with.
+  *
+  * @code
+  * uBit.seedRandom(0xBB5EED);
+  * @endcode
+  */
+inline void MicroBit::seedRandom(uint32_t seed)
+{
+    microbit_seed_random(seed);
+}
+
+
+/**
+  * Add a component to the array of system components. This component will then receive
+  * periodic callbacks, once every tick period in interrupt context.
+  *
+  * @param component The component to add.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the component array is full.
+  *
+  * @code
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitDisplay* display = new MicroBitDisplay();
+  *
+  * uBit.addSystemComponent(display);
+  * @endcode
+  *
+  * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_add_component().
+  */
+inline int MicroBit::addSystemComponent(MicroBitComponent *component)
+{
+	return system_timer_add_component(component);
+}
+
+/**
+  * Remove a component from the array of system components. This component will no longer receive
+  * periodic callbacks.
+  *
+  * @param component The component to remove.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  *
+  * @code
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitDisplay* display = new MicroBitDisplay();
+  *
+  * uBit.addSystemComponent(display);
+  *
+  * uBit.removeSystemComponent(display);
+  * @endcode
+  *
+  * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_remove_component().
+  */
+inline int MicroBit::removeSystemComponent(MicroBitComponent *component)
+{
+	return system_timer_remove_component(component);
+}
+
+/**
+  * Adds a component to the array of idle thread components, which are processed
+  * when the run queue is empty.
+  *
+  * The system timer will poll isIdleCallbackNeeded on each component to determine
+  * if the scheduler should schedule the idle_task imminently.
+  *
+  * @param component The component to add to the array.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
+  *
+  * fiber_add_idle_component(accelerometer);
+  * @endcode
+  *
+  * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_add_idle_component().
+  */
+inline int MicroBit::addIdleComponent(MicroBitComponent *component)
+{
+	return fiber_add_idle_component(component);
+}
+
+/**
+  * Remove a component from the array of idle thread components
+  *
+  * @param component The component to remove from the idle component array.
+  *
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c);
+  *
+  * uBit.addIdleComponent(accelerometer);
+  *
+  * uBit.removeIdleComponent(accelerometer);
+  * @endcode
+  *
+  * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_remove_idle_component().
+  */
+inline int MicroBit::removeIdleComponent(MicroBitComponent *component)
+{
+	return fiber_remove_idle_component(component);
+}
+
+
+/**
+  * Determine the time since this MicroBit was last reset.
+  *
+  * @return The time since the last reset, in milliseconds.
+  *
+  * @note This will value overflow after 1.6 months.
+  */
+inline unsigned long MicroBit::systemTime()
+{
+    return system_timer_current_time();
+}
+
+
+/**
+  * Determine the version of the micro:bit runtime currently in use.
+  *
+  * @return A textual description of the version of the micro:bit runtime that
+  *         is currently running on this device.
+  */
+inline const char *MicroBit::systemVersion()
+{
+    return microbit_dal_version();
+}
+
+/**
+  * Triggers a microbit panic where an loop will display a panic face
+  * and the status code, if provided.
+  *
+  * This loop will continue for panic_timeout iterations, defaults to 0 (infinite).
+  *
+  * panic_timeout can be configured via a call to microbit_panic_timeout.
+  *
+  * @param statusCode the status code of the associated error.
+  *
+  * @code
+  * microbit_panic_timeout(4);
+  *
+  * // will display loop for 4 iterations.
+  * uBit.panic(10);
+  * @endcode
+  */
+inline void MicroBit::panic(int statusCode)
+{
+    //show error and enter infinite while
+	microbit_panic(statusCode);
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/AUTHORS	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,9 @@
+Joe Finney (@finneyj)
+James Devine (@jamesadevine)
+Martin Woolley (@bluetooth-mdw)
+Michał Moskal (@mmoskal)
+Robert May (@remay)
+Jonathan Protzenko (@msprotz)
+James Sheppard (@jamessheppard)
+Damien George (@dpgeorge)
+Mathew Else (@matthewelse)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/.gitignore	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,2 @@
+# Ignore the generated Doxygen output
+apidoc/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/CONTRIBUTING.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,7 @@
+# Hello!
+We are an open source project of [ARM mbed](https://www.mbed.com). Contributions via [pull request](https://github.com/ARMmbed/ble/pulls), and [bug reports](https://github.com/ARMmbed/ble/issues) are welcome!
+
+Please submit your pull request to the `develop` branch of [this module](https://github.com/ARMmbed/ble/tree/develop). Commits to develop will be merge into the master branch at the time of the next release.
+
+# Contributor agreement
+For your pull request to be accepted, we will need you to agree to our [contributor agreement](https://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/DOXYGEN_FRONTPAGE.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,30 @@
+# BLE API {#mainpage}
+
+The BLE module within mbed OS offers a high abstraction level for using
+Bluetooth Low Energy on multiple platforms.
+
+This documentation describes the internal structure of the mbed
+[BLE API](https://github.com/armmbed/ble).
+
+For getting started with BLE on mbed, check our [introduction
+page](https://docs.mbed.com/docs/ble-intros/en/latest/).
+
+For mbed OS examples using BLE, check [this
+repository](https://github.com/armmbed/ble-examples). For mbed-classic
+examples, please refer to [code under mbed.org](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/).
+
+## Supported Services
+
+Currently supported reference services include:
+
+* [Battery](@ref BatteryService)
+* [Device Firmware Update (DFU)](@ref DFUService)
+* [Device Information](@ref DeviceInformationService)
+* [Health Thermometer](@ref HealthThermometerService)
+* [Heart Rate](@ref HeartRateService)
+* [UART](@ref UARTService)
+* [UriBeacon](@ref URIBeaconConfigService)
+* [iBeacon](@ref iBeacon)
+
+The [documentation](https://docs.mbed.com/docs/ble-intros/en/latest/AdvSamples/Overview/)
+contains an overview on how to create new, application-specific services.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/LICENSE	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,2 @@
+Unless specifically indicated otherwise in a file, files are licensed
+under the Apache 2.0 license, as can be found in: apache-2.0.txt
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/README.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,28 @@
+# mbed Bluetooth Low Energy Stack
+This is the Github repo for the `BLE_API` used by developer.mbed.org. Please see the [mbed BLE Homepage](https://developer.mbed.org/teams/Bluetooth-Low-Energy/) for all documentation, code examples and general help.
+
+# Supported Services
+Supported GATT services and constantly being added and can be found in the [ble/services/](https://github.com/ARMmbed/ble/tree/master/ble/services) folder.
+
+Currently supported services include:
+* Battery
+* Device Firmware Update (DFU)
+* Device Information
+* Eddystone Configuration Service
+* Health Thermometer
+* Heart Rate
+* Link Loss
+* UART
+* UriBeacon
+* iBeacon
+
+The [documentation](https://docs.mbed.com/docs/ble-intros/en/latest/AdvSamples/Overview/)
+contains an overview on how to create new, application-specific services.
+
+# Getting Started
+The mbed BLE API is meant to be used in projects on developer.mbed.org. Please see examples and sample project files there.
+A good starting point are these pages:
+* [mbed BLE Homepage](https://developer.mbed.org/teams/Bluetooth-Low-Energy/) for all things BLE
+* [mbed BLE Getting Started Guide](https://developer.mbed.org/forum/team-63-Bluetooth-Low-Energy-community/topic/5262/) a wonderful primer on using BLE with mbed
+* [mbed BLE doc](https://docs.mbed.com/docs/ble-intros/en/latest/) for an introduction to mbed BLE
+* [mbed BLE API page](https://docs.mbed.com/docs/ble-api/en/latest/api/index.html) for the Doxygen API documentation
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/apache-2.0.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble.doxyfile	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1919 @@
+# Doxyfile 1.8.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed
+# in front of the TAG it is preceding .
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "BLE API"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = v2
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = "An abstraction for using Bluetooth Low Energy."
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidoc/
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = h=C++
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields or simple typedef fields will be shown
+# inline in the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO (the default), structs, classes, and unions are shown on a separate
+# page (for HTML and Man pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can
+# be an expensive process and often the same symbol appear multiple times in
+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
+# small doxygen will become slower. If the cache is too large, memory is wasted.
+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
+# symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           = doxygen_warn.log
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.h *.cpp *.md
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = configs CONTRIBUTING.md README.md
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be ignored.
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = DOXYGEN_FRONTPAGE.md
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = .
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
+# pieces of code that will be used on startup of the MathJax code.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search
+# engine library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
+# of to a relative location where the documentation can be found.
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4 will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+# or other source files which should be copied to the LaTeX output directory.
+# Note that the files will be copied as-is; there are no commands or markers
+# available.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
+# that can be used to generate PDF.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it. If left blank docbook will be used as the default path.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             = TARGET_NRF51822
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
+# in the related pages index. If set to NO, only the current project's
+# pages will be listed.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# manageable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 200
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 1000
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/BLE.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1444 @@
+/* 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 __BLE_H__
+#define __BLE_H__
+
+#include "blecommon.h"
+#include "Gap.h"
+#include "GattServer.h"
+#include "GattClient.h"
+
+#include "ble/FunctionPointerWithContext.h"
+
+#ifdef YOTTA_CFG_MBED_OS
+#include "mbed-drivers/mbed_error.h"
+#else
+#include "mbed_error.h"
+#endif
+
+/* Forward declaration for the implementation class */
+class BLEInstanceBase;
+
+/**
+ * The base class used to abstract away BLE-capable radio transceivers or SOCs,
+ * so that the BLE API can work with any radio transparently.
+ */
+class BLE
+{
+public:
+    typedef unsigned InstanceID_t; /** The type returned by BLE::getInstanceID(). */
+
+    /**
+     * The context provided to init-completion-callbacks (see init() below).
+     *
+     * @param  ble
+     *             A reference to the BLE instance being initialized.
+     * @param  error
+     *             Captures the result of initialization. It is set to
+     *             BLE_ERROR_NONE if initialization completed successfully. Else
+     *             the error value is implementation specific.
+     */
+    struct InitializationCompleteCallbackContext {
+        BLE&        ble;   /* Reference to the BLE object that has been initialized */
+        ble_error_t error; /* Error status of the initialization. It is set to BLE_ERROR_NONE if initialization completed successfully. */
+    };
+
+    /**
+     * The signature for function-pointer like callbacks for initialization-completion.
+     *
+     * @note There are two versions of init(). In addition to the simple
+     *     function-pointer, init() can also take a <Object, member> tuple as its
+     *     callback target. In case of the latter, the following declaration doesn't apply.
+     */
+    typedef void (*InitializationCompleteCallback_t)(InitializationCompleteCallbackContext *context);
+
+    /**
+     * Initialize the BLE controller. This should be called before using
+     * anything else in the BLE_API.
+     *
+     * init() hands control to the underlying BLE module to accomplish
+     * initialization. This initialization may tacitly depend on other hardware
+     * setup (such as clocks or power-modes) that happens early on during
+     * system startup. It may not be safe to call init() from a global static
+     * context where ordering is compiler-specific and can't be guaranteed - it
+     * is safe to call BLE::init() from within main().
+     *
+     * @param  initCompleteCallback
+     *           A callback for when initialization completes for a BLE
+     *           instance. This is an optional parameter; if no callback is
+     *           set up the application can still determine the status of
+     *           initialization using BLE::hasInitialized() (see below).
+     *
+     * @return  BLE_ERROR_NONE if the initialization procedure was started
+     *     successfully.
+     *
+     * @note If init() returns BLE_ERROR_NONE, the underlying stack must invoke
+     *     the initialization completion callback at some point.
+     *
+     * @note In some cases, initialization is instantaneous (or blocking); if
+     *     so, it is acceptable for the stack-specific implementation of init()
+     *     to invoke the completion callback directly (within its own
+     *     context).
+     *
+     * @note Nearly all BLE APIs would return
+     *     BLE_ERROR_INITIALIZATION_INCOMPLETE if used on an instance before the
+     *     corresponding transport is initialized.
+     *
+     * @note There are two versions of init(). In addition to the simple
+     *     function-pointer, init() can also take an <Object, member> tuple as its
+     *     callback target.
+     */
+    ble_error_t init(InitializationCompleteCallback_t initCompleteCallback = NULL) {
+        FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(initCompleteCallback);
+        return initImplementation(callback);
+    }
+
+    /**
+     * An alternate declaration for init(). This one takes an <Object, member> tuple as its
+     * callback target.
+     */
+    template<typename T>
+    ble_error_t init(T *object, void (T::*initCompleteCallback)(InitializationCompleteCallbackContext *context)) {
+        FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(object, initCompleteCallback);
+        return initImplementation(callback);
+    }
+
+    /**
+     * @return true if initialization has completed for the underlying BLE
+     *     transport.
+     *
+     * The application can set up a callback to signal completion of
+     * initialization when using init(). Otherwise, this method can be used to
+     * poll the state of initialization.
+     */
+    bool hasInitialized(void) const;
+
+    /**
+     * Purge the BLE stack of GATT and GAP state. init() must be called
+     * afterwards to re-instate services and GAP state. This API offers a way to
+     * repopulate the GATT database with new services and characteristics.
+     */
+    ble_error_t shutdown(void);
+
+    /**
+     * This call allows the application to get the BLE stack version information.
+     *
+     * @return  A pointer to a const string representing the version.
+     *          Note: The string is owned by BLE_API.
+     */
+    const char *getVersion(void);
+
+    /*
+     * Accessors to GAP. Please refer to Gap.h. All GAP related functionality requires
+     * going through this accessor.
+     */
+    const Gap &gap() const;
+    Gap &gap();
+
+    /*
+     * Accessors to GATT Server. Please refer to GattServer.h. All GATTServer related
+     * functionality requires going through this accessor.
+     */
+    const GattServer& gattServer() const;
+    GattServer& gattServer();
+
+    /*
+     * Accessors to GATT Client. Please refer to GattClient.h. All GATTClient related
+     * functionality requires going through this accessor.
+     */
+    const GattClient& gattClient() const;
+    GattClient& gattClient();
+
+    /*
+     * Accessors to Security Manager. Please refer to SecurityManager.h. All
+     * SecurityManager related functionality requires going through this
+     * accessor.
+     */
+    const SecurityManager& securityManager() const;
+    SecurityManager& securityManager();
+
+    /**
+     * Yield control to the BLE stack or to other tasks waiting for events. This
+     * is a sleep function that will return when there is an application-specific
+     * interrupt, but the MCU might wake up several times before
+     * returning (to service the stack). This is not always interchangeable with
+     * WFE().
+     */
+    void waitForEvent(void);
+
+public:
+    static const InstanceID_t DEFAULT_INSTANCE = 0;
+#ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
+    static const InstanceID_t NUM_INSTANCES = 1;
+#else
+    static const InstanceID_t NUM_INSTANCES = YOTTA_CFG_BLE_INSTANCES_COUNT;
+#endif
+
+    /**
+     * Get a reference to the BLE singleton corresponding to a given interface.
+     * There is a static array of BLE singletons.
+     *
+     * @Note: Calling Instance() is preferred over constructing a BLE object
+     * directly, as it returns references to singletons.
+     *
+     * @param[in] id
+     *              Instance-ID. This should be less than NUM_INSTANCES
+     *              for the returned BLE singleton to be useful.
+     *
+     * @return a reference to a single object.
+     */
+    static BLE &Instance(InstanceID_t id = DEFAULT_INSTANCE);
+
+    /**
+     * Constructor for a handle to a BLE instance (the BLE stack). BLE handles
+     * are thin wrappers around a transport object (that is, ptr. to
+     * BLEInstanceBase).
+     *
+     * It is better to create BLE objects as singletons accessed through the
+     * Instance() method. If multiple BLE handles are constructed for the same
+     * interface (using this constructor), they will share the same underlying
+     * transport object.
+     */
+    BLE(InstanceID_t instanceID = DEFAULT_INSTANCE);
+
+    /**
+     * Fetch the ID of a BLE instance. Typically there would only be the DEFAULT_INSTANCE.
+     */
+    InstanceID_t getInstanceID(void) const {
+        return instanceID;
+    }
+
+    /*
+     * Deprecation alert!
+     * All of the following are deprecated and may be dropped in a future
+     * release. Documentation should refer to alternative APIs.
+     */
+
+    /* GAP specific APIs. */
+public:
+    /**
+     * Set the BTLE MAC address and type.
+     * @return BLE_ERROR_NONE on success.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAddress(...) should be replaced with
+     * ble.gap().setAddress(...).
+     */
+    ble_error_t setAddress(BLEProtocol::AddressType_t type, const BLEProtocol::AddressBytes_t address) {
+        return gap().setAddress(type, address);
+    }
+
+    /**
+     * Fetch the BTLE MAC address and type.
+     * @return BLE_ERROR_NONE on success.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getAddress(...) should be replaced with
+     * ble.gap().getAddress(...).
+     */
+    ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) {
+        return gap().getAddress(typeP, address);
+    }
+
+    /**
+     * Set the GAP advertising mode to use for this device.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAdvertisingType(...) should be replaced with
+     * ble.gap().setAdvertisingType(...).
+     */
+    void setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) {
+        gap().setAdvertisingType(advType);
+    }
+
+    /**
+     * @param[in] interval
+     *              Advertising interval in units of milliseconds. Advertising
+     *              is disabled if interval is 0. If interval is smaller than
+     *              the minimum supported value, then the minimum supported
+     *              value is used instead. This minimum value can be discovered
+     *              using getMinAdvertisingInterval().
+     *
+     *              This field must be set to 0 if connectionMode is equal
+     *              to ADV_CONNECTABLE_DIRECTED.
+     *
+     * @note: Decreasing this value allows central devices to detect a
+     * peripheral faster, at the expense of more power being used by the radio
+     * due to the higher data transmit rate.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAdvertisingInterval(...) should be replaced with
+     * ble.gap().setAdvertisingInterval(...).
+     *
+     * @note: [WARNING] This API previously used 0.625ms as the unit for its
+     * 'interval' argument. That required an explicit conversion from
+     * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is
+     * no longer required as the new units are milliseconds. Any application
+     * code depending on the old semantics needs to be updated accordingly.
+     */
+    void setAdvertisingInterval(uint16_t interval) {
+        gap().setAdvertisingInterval(interval);
+    }
+
+    /**
+     * @return Minimum Advertising interval in milliseconds.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getMinAdvertisingInterval(...) should be replaced with
+     * ble.gap().getMinAdvertisingInterval(...).
+     */
+    uint16_t getMinAdvertisingInterval(void) const {
+        return gap().getMinAdvertisingInterval();
+    }
+
+    /**
+     * @return Minimum Advertising interval in milliseconds for non-connectible mode.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getMinNonConnectableAdvertisingInterval(...) should be replaced with
+     * ble.gap().getMinNonConnectableAdvertisingInterval(...).
+     */
+    uint16_t getMinNonConnectableAdvertisingInterval(void) const {
+        return gap().getMinNonConnectableAdvertisingInterval();
+    }
+
+    /**
+     * @return Maximum Advertising interval in milliseconds.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getMaxAdvertisingInterval(...) should be replaced with
+     * ble.gap().getMaxAdvertisingInterval(...).
+     */
+    uint16_t getMaxAdvertisingInterval(void) const {
+        return gap().getMaxAdvertisingInterval();
+    }
+
+    /**
+     * @param[in] timeout
+     *              Advertising timeout (in seconds) between 0x1 and 0x3FFF (1
+     *              and 16383). Use 0 to disable the advertising timeout.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAdvertisingTimeout(...) should be replaced with
+     * ble.gap().setAdvertisingTimeout(...).
+     */
+    void setAdvertisingTimeout(uint16_t timeout) {
+        gap().setAdvertisingTimeout(timeout);
+    }
+
+    /**
+     * Set up a particular, user-constructed set of advertisement parameters for
+     * the underlying stack. It would be uncommon for this API to be used
+     * directly; there are other APIs to tweak advertisement parameters
+     * individually (see above).
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAdvertisingParams(...) should be replaced with
+     * ble.gap().setAdvertisingParams(...).
+     */
+    void setAdvertisingParams(const GapAdvertisingParams &advParams) {
+        gap().setAdvertisingParams(advParams);
+    }
+
+    /**
+     * @return  Read back advertising parameters. Useful for storing and
+     *          restoring parameters rapidly.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getAdvertisingParams(...) should be replaced with
+     * ble.gap().getAdvertisingParams(...).
+     */
+    const GapAdvertisingParams &getAdvertisingParams(void) const {
+        return gap().getAdvertisingParams();
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param[in] flags
+     *              The flags to add. Please refer to
+     *              GapAdvertisingData::Flags for valid flags. Multiple
+     *              flags may be specified in combination.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.accumulateAdvertisingPayload(flags) should be replaced with
+     * ble.gap().accumulateAdvertisingPayload(flags).
+     */
+    ble_error_t accumulateAdvertisingPayload(uint8_t flags) {
+        return gap().accumulateAdvertisingPayload(flags);
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param[in] app
+     *              The appearance of the peripheral.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.accumulateAdvertisingPayload(appearance) should be replaced with
+     * ble.gap().accumulateAdvertisingPayload(appearance).
+     */
+    ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
+        return gap().accumulateAdvertisingPayload(app);
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param[in] app
+     *              The max transmit power to be used by the controller. This
+     *              is only a hint.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.accumulateAdvertisingPayloadTxPower(txPower) should be replaced with
+     * ble.gap().accumulateAdvertisingPayloadTxPower(txPower).
+     */
+    ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) {
+        return gap().accumulateAdvertisingPayloadTxPower(power);
+    }
+
+    /**
+     * Accumulate a variable length byte-stream as an AD structure in the
+     * advertising payload. Please note that the payload is limited to 31 bytes.
+     * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
+     * advertising payload is too small.
+     *
+     * @param  type The type that describes the variable length data.
+     * @param  data Data bytes.
+     * @param  len  Data length.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.accumulateAdvertisingPayload(...) should be replaced with
+     * ble.gap().accumulateAdvertisingPayload(...).
+     */
+    ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
+        return gap().accumulateAdvertisingPayload(type, data, len);
+    }
+
+    /**
+     * Setup a particular, user-constructed advertisement payload for the
+     * underlying stack. It would be uncommon for this API to be used directly;
+     * there are other APIs to build an advertisement payload (see above).
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAdvertisingData(...) should be replaced with
+     * ble.gap().setAdvertisingPayload(...).
+     */
+    ble_error_t setAdvertisingData(const GapAdvertisingData &advData) {
+        return gap().setAdvertisingPayload(advData);
+    }
+
+    /**
+     * @return  Read back advertising data. Useful for storing and
+     *          restoring payload.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getAdvertisingData(...) should be replaced with
+     * ble.gap().getAdvertisingPayload()(...).
+     */
+    const GapAdvertisingData &getAdvertisingData(void) const {
+        return gap().getAdvertisingPayload();
+    }
+
+    /**
+     * Reset any advertising payload prepared from prior calls to
+     * accumulateAdvertisingPayload(). This automatically propagates the re-
+     * initialized advertising payload to the underlying stack.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.clearAdvertisingPayload(...) should be replaced with
+     * ble.gap().clearAdvertisingPayload(...).
+     */
+    void clearAdvertisingPayload(void) {
+        gap().clearAdvertisingPayload();
+    }
+
+    /**
+     * This API is *deprecated* and resolves to a no-operation. It is left here
+     * to allow older code to compile. Please avoid using this API in new code.
+     * This API will be dropped in a future release.
+     *
+     * Formerly, it would be used to dynamically reset the accumulated advertising
+     * payload and scanResponse; to do this, the application would clear and re-
+     * accumulate a new advertising payload (and scanResponse) before using this
+     * API. Updates to the underlying advertisement payload now happen
+     * implicitly.
+     */
+    ble_error_t setAdvertisingPayload(void) {
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * Accumulate a variable length byte-stream as an AD structure in the
+     * scanResponse payload.
+     *
+     * @param[in] type The type that describes the variable length data.
+     * @param[in] data Data bytes.
+     * @param[in] len  Data length.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.accumulateScanResponse(...) should be replaced with
+     * ble.gap().accumulateScanResponse(...).
+     */
+    ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
+        return gap().accumulateScanResponse(type, data, len);
+    }
+
+    /**
+     * Reset any scan response prepared from prior calls to
+     * accumulateScanResponse().
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.clearScanResponse(...) should be replaced with
+     * ble.gap().clearScanResponse(...).
+     */
+    void clearScanResponse(void) {
+        gap().clearScanResponse();
+    }
+
+    /**
+     * Start advertising.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.startAdvertising(...) should be replaced with
+     * ble.gap().startAdvertising(...).
+     */
+    ble_error_t startAdvertising(void) {
+        return gap().startAdvertising();
+    }
+
+    /**
+     * Stop advertising.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.stopAdvertising(...) should be replaced with
+     * ble.gap().stopAdvertising(...).
+     */
+    ble_error_t stopAdvertising(void) {
+        return gap().stopAdvertising();
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] interval
+     *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     * @param[in] window
+     *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     * @param[in] timeout
+     *              Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables timeout.
+     * @param[in] activeScanning
+     *              Set to True if active-scanning is required. This is used to fetch the
+     *              scan response from a peer if possible.
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @Note: The scan interval and window are recommendations to the BLE stack.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setScanParams(...) should be replaced with
+     * ble.gap().setScanParams(...).
+     */
+    ble_error_t setScanParams(uint16_t interval       = GapScanningParams::SCAN_INTERVAL_MAX,
+                              uint16_t window         = GapScanningParams::SCAN_WINDOW_MAX,
+                              uint16_t timeout        = 0,
+                              bool     activeScanning = false) {
+        return gap().setScanParams(interval, window, timeout, activeScanning);
+    }
+
+    /**
+     * Set up the scanInterval parameter for GAP scanning (observer mode).
+     * @param[in] interval
+     *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setScanInterval(interval) should be replaced with
+     * ble.gap().setScanInterval(interval).
+     */
+    ble_error_t setScanInterval(uint16_t interval) {
+        return gap().setScanInterval(interval);
+    }
+
+    /**
+     * Set up the scanWindow parameter for GAP scanning (observer mode).
+     * @param[in] window
+     *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setScanWindow(window) should be replaced with
+     * ble.gap().setScanWindow(window).
+     */
+    ble_error_t setScanWindow(uint16_t window) {
+        return gap().setScanWindow(window);
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] timeout
+     *              Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables timeout.
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @Note: The scan interval and window are recommendations to the BLE stack.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setScanTimeout(...) should be replaced with
+     * ble.gap().setScanTimeout(...).
+     */
+    ble_error_t setScanTimeout(uint16_t timeout) {
+        return gap().setScanTimeout(timeout);
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] activeScanning
+     *              Set to True if active-scanning is required. This is used to fetch the
+     *              scan response from a peer if possible.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setActiveScan(...) should be replaced with
+     * ble.gap().setActiveScanning(...).
+     */
+    void setActiveScan(bool activeScanning) {
+        gap().setActiveScanning(activeScanning);
+    }
+
+    /**
+     * Start scanning (Observer Procedure) based on the parameters currently in
+     * effect.
+     *
+     * @param[in] callback
+     *              The application-specific callback to be invoked upon
+     *              receiving every advertisement report. This can be passed in
+     *              as NULL, in which case scanning may not be enabled at all.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.startScan(callback) should be replaced with
+     * ble.gap().startScan(callback).
+     */
+    ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) {
+        return gap().startScan(callback);
+    }
+
+    /**
+     * Same as above, but this takes an (object, method) pair for a callback.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.startScan(callback) should be replaced with
+     * ble.gap().startScan(object, callback).
+     */
+    template<typename T>
+    ble_error_t startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params));
+
+    /**
+     * Stop scanning. The current scanning parameters remain in effect.
+     *
+     * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.stopScan() should be replaced with
+     * ble.gap().stopScan().
+     */
+    ble_error_t stopScan(void) {
+        return gap().stopScan();
+    }
+
+    /**
+     * Create a connection (GAP Link Establishment).
+     * @param peerAddr
+     *          48-bit address, LSB format.
+     * @param peerAddrType
+     *          Address type of the peer.
+     * @param connectionParams
+     *         Connection parameters.
+     * @param scanParams
+     *          Paramters to use while scanning for the peer.
+     * @return  BLE_ERROR_NONE if connection establishment procedure is started
+     *     successfully. The onConnection callback (if set) is invoked upon
+     *     a connection event.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.connect(...) should be replaced with
+     * ble.gap().connect(...).
+     */
+    ble_error_t connect(const BLEProtocol::AddressBytes_t  peerAddr,
+                        BLEProtocol::AddressType_t         peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC,
+                        const Gap::ConnectionParams_t     *connectionParams = NULL,
+                        const GapScanningParams           *scanParams = NULL) {
+        return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams);
+    }
+
+    /**
+     * This call initiates the disconnection procedure, and its completion is
+     * communicated to the application with an invocation of the
+     * onDisconnection callback.
+     *
+     * @param[in] connectionHandle
+     * @param[in] reason
+     *              The reason for disconnection; sent back to the peer.
+     */
+    ble_error_t disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) {
+        return gap().disconnect(connectionHandle, reason);
+    }
+
+    /**
+     * This call initiates the disconnection procedure, and its completion
+     * is communicated to the application with an invocation of the
+     * onDisconnection callback.
+     *
+     * @param  reason
+     *           The reason for disconnection; sent back to the peer.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.disconnect(reason) should be replaced with
+     * ble.gap().disconnect(reason).
+     *
+     * @note: This version of disconnect() doesn't take a connection handle. It
+     * works reliably only for stacks that are limited to a single
+     * connection. This API should be considered *deprecated* in favour of the
+     * alternative, which takes a connection handle. It will be dropped in the future.
+     */
+    ble_error_t disconnect(Gap::DisconnectionReason_t reason) {
+        return gap().disconnect(reason);
+    }
+
+    /**
+     * Returns the current GAP state of the device using a bitmask that
+     * describes whether the device is advertising or connected.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getGapState() should be replaced with
+     * ble.gap().getState().
+     */
+    Gap::GapState_t getGapState(void) const {
+        return gap().getState();
+    }
+
+    /**
+     * Get the GAP peripheral's preferred connection parameters. These are the
+     * defaults that the peripheral would like to have in a connection. The
+     * choice of the connection parameters is eventually up to the central.
+     *
+     * @param[out] params
+     *               The structure where the parameters will be stored. Memory
+     *               for this is owned by the caller.
+     *
+     * @return BLE_ERROR_NONE if the parameters were successfully filled into
+     * the given structure pointed to by params.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getPreferredConnectionParams() should be replaced with
+     * ble.gap().getPreferredConnectionParams().
+     */
+    ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params) {
+        return gap().getPreferredConnectionParams(params);
+    }
+
+    /**
+     * Set the GAP peripheral's preferred connection parameters. These are the
+     * defaults that the peripheral would like to have in a connection. The
+     * choice of the connection parameters is eventually up to the central.
+     *
+     * @param[in] params
+     *               The structure containing the desired parameters.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setPreferredConnectionParams() should be replaced with
+     * ble.gap().setPreferredConnectionParams().
+     */
+    ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params) {
+        return gap().setPreferredConnectionParams(params);
+    }
+
+    /**
+     * Update connection parameters while in the peripheral role.
+     * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for
+     *          the central to perform the procedure.
+     * @param[in] handle
+     *              Connection Handle
+     * @param[in] params
+     *              Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+     *              the parameters in the PPCP characteristic of the GAP service will be used instead.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.updateConnectionParams() should be replaced with
+     * ble.gap().updateConnectionParams().
+     */
+    ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) {
+        return gap().updateConnectionParams(handle, params);
+    }
+
+    /**
+     * Set the device name characteristic in the GAP service.
+     * @param[in] deviceName
+     *              The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setDeviceName() should be replaced with
+     * ble.gap().setDeviceName().
+     */
+    ble_error_t setDeviceName(const uint8_t *deviceName) {
+        return gap().setDeviceName(deviceName);
+    }
+
+    /**
+     * Get the value of the device name characteristic in the GAP service.
+     * @param[out]    deviceName
+     *                  Pointer to an empty buffer where the UTF-8 *non NULL-
+     *                  terminated* string will be placed. Set this
+     *                  value to NULL in order to obtain the deviceName-length
+     *                  from the 'length' parameter.
+     *
+     * @param[in/out] lengthP
+     *                  (on input) Length of the buffer pointed to by deviceName;
+     *                  (on output) the complete device name length (without the
+     *                     null terminator).
+     *
+     * @note If the device name is longer than the size of the supplied buffer,
+     *     length will return the complete device name length, and not the
+     *     number of bytes actually returned in deviceName. The application may
+     *     use this information to retry with a suitable buffer size.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getDeviceName() should be replaced with
+     * ble.gap().getDeviceName().
+     */
+    ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) {
+        return gap().getDeviceName(deviceName, lengthP);
+    }
+
+    /**
+     * Set the appearance characteristic in the GAP service.
+     * @param[in] appearance
+     *              The new value for the device-appearance.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setAppearance() should be replaced with
+     * ble.gap().setAppearance().
+     */
+    ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) {
+        return gap().setAppearance(appearance);
+    }
+
+    /**
+     * Get the appearance characteristic in the GAP service.
+     * @param[out] appearance
+     *               The new value for the device-appearance.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getAppearance() should be replaced with
+     * ble.gap().getAppearance().
+     */
+    ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) {
+        return gap().getAppearance(appearanceP);
+    }
+
+    /**
+     * Set the radio's transmit power.
+     * @param[in] txPower Radio transmit power in dBm.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.setTxPower() should be replaced with
+     * ble.gap().setTxPower().
+     */
+    ble_error_t setTxPower(int8_t txPower) {
+        return gap().setTxPower(txPower);
+    }
+
+    /**
+     * Query the underlying stack for permitted arguments for setTxPower().
+     *
+     * @param[out] valueArrayPP
+     *                 Out parameter to receive the immutable array of Tx values.
+     * @param[out] countP
+     *                 Out parameter to receive the array's size.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call to
+     * ble.getPermittedTxPowerValues() should be replaced with
+     * ble.gap().getPermittedTxPowerValues().
+     */
+    void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
+        gap().getPermittedTxPowerValues(valueArrayPP, countP);
+    }
+
+    /**
+     * Add a service declaration to the local server ATT table. Also add the
+     * characteristics contained within.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.addService() should be replaced with
+     * ble.gattServer().addService().
+     */
+    ble_error_t addService(GattService &service) {
+        return gattServer().addService(service);
+    }
+
+    /**
+     * Read the value of a characteristic from the local GattServer.
+     * @param[in]     attributeHandle
+     *                  Attribute handle for the value attribute of the characteristic.
+     * @param[out]    buffer
+     *                  A buffer to hold the value being read.
+     * @param[in/out] lengthP
+     *                  Length of the buffer being supplied. If the attribute
+     *                  value is longer than the size of the supplied buffer,
+     *                  this variable will return the total attribute value length
+     *                  (excluding offset). The application may use this
+     *                  information to allocate a suitable buffer size.
+     *
+     * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.readCharacteristicValue() should be replaced with
+     * ble.gattServer().read().
+     */
+    ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
+        return gattServer().read(attributeHandle, buffer, lengthP);
+    }
+
+    /**
+     * Read the value of a characteristic from the local GattServer.
+     * @param[in]     connectionHandle
+     *                  Connection Handle.
+     * @param[in]     attributeHandle
+     *                  Attribute handle for the value attribute of the characteristic.
+     * @param[out]    buffer
+     *                  A buffer to hold the value being read.
+     * @param[in/out] lengthP
+     *                  Length of the buffer being supplied. If the attribute
+     *                  value is longer than the size of the supplied buffer,
+     *                  this variable will return the total attribute value length
+     *                  (excluding offset). The application may use this
+     *                  information to allocate a suitable buffer size.
+     *
+     * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
+     *
+     * @note This API is a version of the above, with an additional connection handle
+     *     parameter to allow fetches for connection-specific multivalued
+     *     attributes (such as the CCCDs).
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.readCharacteristicValue() should be replaced with
+     * ble.gattServer().read().
+     */
+    ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
+        return gattServer().read(connectionHandle, attributeHandle, buffer, lengthP);
+    }
+
+    /**
+     * Update the value of a characteristic on the local GattServer.
+     *
+     * @param[in] attributeHandle
+     *              Handle for the value attribute of the characteristic.
+     * @param[in] value
+     *              A pointer to a buffer holding the new value.
+     * @param[in] size
+     *              Size of the new value (in bytes).
+     * @param[in] localOnly
+     *              Should this update be kept on the local
+     *              GattServer regardless of the state of the
+     *              notify/indicate flag in the CCCD for this
+     *              characteristic? If set to true, no notification
+     *              or indication is generated.
+     *
+     * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.updateCharacteristicValue() should be replaced with
+     * ble.gattServer().write().
+     */
+    ble_error_t updateCharacteristicValue(GattAttribute::Handle_t  attributeHandle,
+                                          const uint8_t           *value,
+                                          uint16_t                 size,
+                                          bool                     localOnly = false) {
+        return gattServer().write(attributeHandle, value, size, localOnly);
+    }
+
+    /**
+     * Update the value of a characteristic on the local GattServer. A version
+     * of the above, with a connection handle parameter to allow updates
+     * for connection-specific multivalued attributes (such as the CCCDs).
+     *
+     * @param[in] connectionHandle
+     *              Connection Handle.
+     * @param[in] attributeHandle
+     *              Handle for the value attribute of the Characteristic.
+     * @param[in] value
+     *              A pointer to a buffer holding the new value.
+     * @param[in] size
+     *              Size of the new value (in bytes).
+     * @param[in] localOnly
+     *              Should this update be kept on the local
+     *              GattServer regardless of the state of the
+     *              notify/indicate flag in the CCCD for this
+     *              Characteristic? If set to true, no notification
+     *              or indication is generated.
+     *
+     * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.updateCharacteristicValue() should be replaced with
+     * ble.gattServer().write().
+     */
+    ble_error_t updateCharacteristicValue(Gap::Handle_t            connectionHandle,
+                                          GattAttribute::Handle_t  attributeHandle,
+                                          const uint8_t           *value,
+                                          uint16_t                 size,
+                                          bool                     localOnly = false) {
+        return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly);
+    }
+
+    /**
+     * Enable the BLE stack's Security Manager. The Security Manager implements
+     * the cryptographic algorithms and protocol exchanges that allow two
+     * devices to securely exchange data and privately detect each other.
+     * Calling this API is a prerequisite for encryption and pairing (bonding).
+     *
+     * @param[in]  enableBonding Allow for bonding.
+     * @param[in]  requireMITM   Require protection against man-in-the-middle attacks.
+     * @param[in]  iocaps        To specify the I/O 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.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.initializeSecurity(...) should be replaced with
+     * ble.securityManager().init(...).
+     */
+    ble_error_t initializeSecurity(bool                                      enableBonding = true,
+                                   bool                                      requireMITM   = true,
+                                   SecurityManager::SecurityIOCapabilities_t iocaps        = SecurityManager::IO_CAPS_NONE,
+                                   const SecurityManager::Passkey_t          passkey       = NULL) {
+        return securityManager().init(enableBonding, requireMITM, iocaps, passkey);
+    }
+
+    /**
+     * Get the security status of a connection.
+     *
+     * @param[in]  connectionHandle   Handle to identify the connection.
+     * @param[out] securityStatusP    Security status.
+     *
+     * @return BLE_SUCCESS or appropriate error code indicating the reason of failure.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.getLinkSecurity(...) should be replaced with
+     * ble.securityManager().getLinkSecurity(...).
+     */
+    ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) {
+        return securityManager().getLinkSecurity(connectionHandle, securityStatusP);
+    }
+
+    /**
+     * Delete all peer device context and all related bonding information from
+     * the database within the security manager.
+     *
+     * @retval BLE_ERROR_NONE             On success; else returns an error code indicating the reason for the failure.
+     * @retval BLE_ERROR_INVALID_STATE    If the API is called without module initialization or
+     *                                    application registration.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.purgeAllBondingState() should be replaced with
+     * ble.securityManager().purgeAllBondingState().
+     */
+    ble_error_t purgeAllBondingState(void) {
+        return securityManager().purgeAllBondingState();
+    }
+
+    /**
+     * Set up a callback for timeout events. Refer to Gap::TimeoutSource_t for
+     * possible event types.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call
+     * to ble.onTimeout(callback) should be replaced with
+     * ble.gap().onTimeout(callback).
+     */
+    void onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) {
+        gap().onTimeout(timeoutCallback);
+    }
+
+    /**
+     * Set up a callback for connection events. Refer to Gap::ConnectionEventCallback_t.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call
+     * to ble.onConnection(callback) should be replaced with
+     * ble.gap().onConnection(callback).
+     */
+    void onConnection(Gap::ConnectionEventCallback_t connectionCallback) {
+        gap().onConnection(connectionCallback);
+    }
+
+    /**
+     * Append to a chain of callbacks to be invoked upon GAP disconnection.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call
+     * to ble.onDisconnection(callback) should be replaced with
+     * ble.gap().onDisconnection(callback).
+     */
+    void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) {
+        gap().onDisconnection(disconnectionCallback);
+    }
+
+    template<typename T>
+    void onDisconnection(T *tptr, void (T::*mptr)(const Gap::DisconnectionCallbackParams_t*)) {
+        gap().onDisconnection(tptr, mptr);
+    }
+
+    /**
+     * Radio Notification is a feature that enables ACTIVE and INACTIVE
+     * (nACTIVE) signals from the stack. These notify the application when the
+     * radio is in use. The signal is sent using software interrupt.
+     *
+     * The ACTIVE signal is sent before the radio event starts. The nACTIVE
+     * signal is sent at the end of the radio event. These signals can be used
+     * by the application programmer to synchronize application logic with radio
+     * activity. For example, the ACTIVE signal can be used to shut off external
+     * devices to manage peak current drawn during periods when the radio is on,
+     * or to trigger sensor data collection for transmission in the radio event.
+     *
+     * @param callback
+     *          The application handler to be invoked in response to a radio
+     *          ACTIVE/INACTIVE event.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from Gap directly. A former call
+     * to ble.onRadioNotification(...) should be replaced with
+     * ble.gap().onRadioNotification(...).
+     */
+    void onRadioNotification(void (*callback)(bool)) {
+        gap().onRadioNotification(callback);
+    }
+
+    /**
+     * Add a callback for the GATT event DATA_SENT (which is triggered when
+     * updates are sent out by GATT in the form of notifications).
+     *
+     * @Note: It is possible to chain together multiple onDataSent callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onDataSent(...) should be replaced with
+     * ble.gattServer().onDataSent(...).
+     */
+    void onDataSent(void (*callback)(unsigned count)) {
+        gattServer().onDataSent(callback);
+    }
+    template <typename T> void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)) {
+        gattServer().onDataSent(objPtr, memberPtr);
+    }
+
+    /**
+     * Set up a callback for when an attribute has its value updated by or at the
+     * connected peer. For a peripheral, this callback is triggered when the local
+     * GATT server has an attribute updated by a write command from the peer.
+     * For a Central, this callback is triggered when a response is received for
+     * a write request.
+     *
+     * @Note: It is possible to chain together multiple onDataWritten callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics. Many services, such as DFU and UART, add their own
+     * onDataWritten callbacks behind the scenes to trap interesting events.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onDataWritten(...) should be replaced with
+     * ble.gattServer().onDataWritten(...).
+     */
+    void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) {
+        gattServer().onDataWritten(callback);
+    }
+    template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
+        gattServer().onDataWritten(objPtr, memberPtr);
+    }
+
+    /**
+     * Set up a callback to be invoked on the peripheral when an attribute is
+     * being read by a remote client.
+     *
+     * @Note: This functionality may not be available on all underlying stacks.
+     * You could use GattCharacteristic::setReadAuthorizationCallback() as an
+     * alternative.
+     *
+     * @Note: It is possible to chain together multiple onDataRead callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics. Services may add their own onDataRead callbacks
+     * behind the scenes to trap interesting events.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
+     *         else BLE_ERROR_NONE.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onDataRead(...) should be replaced with
+     * ble.gattServer().onDataRead(...).
+     */
+    ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) {
+        return gattServer().onDataRead(callback);
+    }
+    template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
+        return gattServer().onDataRead(objPtr, memberPtr);
+    }
+
+    /**
+     * Set up a callback for when notifications or indications are enabled for a
+     * characteristic on the local GattServer.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onUpdatesEnabled(callback) should be replaced with
+     * ble.gattServer().onUpdatesEnabled(callback).
+     */
+    void onUpdatesEnabled(GattServer::EventCallback_t callback) {
+        gattServer().onUpdatesEnabled(callback);
+    }
+
+    /**
+     * Set up a callback for when notifications or indications are disabled for a
+     * characteristic on the local GattServer.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onUpdatesEnabled(callback) should be replaced with
+     * ble.gattServer().onUpdatesEnabled(callback).
+     */
+    void onUpdatesDisabled(GattServer::EventCallback_t callback) {
+        gattServer().onUpdatesDisabled(callback);
+    }
+
+    /**
+     * Set up a callback for when the GATT server receives a response for an
+     * indication event sent previously.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from GattServer directly. A former call
+     * to ble.onConfirmationReceived(callback) should be replaced with
+     * ble.gattServer().onConfirmationReceived(callback).
+     */
+    void onConfirmationReceived(GattServer::EventCallback_t callback) {
+        gattServer().onConfirmationReceived(callback);
+    }
+
+    /**
+     * Set up a callback for when the security setup procedure (key generation
+     * and exchange) for a link has started. This will be skipped for bonded
+     * devices. The callback is passed in parameters received from the peer's
+     * security request: bool allowBonding, bool requireMITM, and
+     * SecurityIOCapabilities_t.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.onSecuritySetupInitiated(callback) should be replaced with
+     * ble.securityManager().onSecuritySetupInitiated(callback).
+     */
+    void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback) {
+        securityManager().onSecuritySetupInitiated(callback);
+    }
+
+    /**
+     * Set up a callback for when the security setup procedure (key generation
+     * and exchange) for a link has completed. This will be skipped for bonded
+     * devices. The callback is passed in the success/failure status of the
+     * security setup procedure.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.onSecuritySetupCompleted(callback) should be replaced with
+     * ble.securityManager().onSecuritySetupCompleted(callback).
+     */
+    void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback) {
+        securityManager().onSecuritySetupCompleted(callback);
+    }
+
+    /**
+     * Set up a callback for when a link with the peer is secured. For bonded
+     * devices, subsequent reconnections with a bonded peer will result only in
+     * this callback when the link is secured, and setup procedures will not
+     * occur unless the bonding information is either lost or deleted on either
+     * or both sides. The callback is passed in a SecurityManager::SecurityMode_t according
+     * to the level of security in effect for the secured link.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.onLinkSecured(callback) should be replaced with
+     * ble.securityManager().onLinkSecured(callback).
+     */
+    void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback) {
+        securityManager().onLinkSecured(callback);
+    }
+
+    /**
+     * Set up a callback for successful bonding, meaning that link-specific security
+     * context is stored persistently for a peer device.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.onSecurityContextStored(callback) should be replaced with
+     * ble.securityManager().onSecurityContextStored(callback).
+     */
+    void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback) {
+        securityManager().onSecurityContextStored(callback);
+    }
+
+    /**
+     * Set up a callback for when the passkey needs to be displayed on a
+     * peripheral with DISPLAY capability. This happens when security is
+     * configured to prevent Man-In-The-Middle attacks, and the peers need to exchange
+     * a passkey (or PIN) to authenticate the connection
+     * attempt.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * You should use the parallel API from SecurityManager directly. A former
+     * call to ble.onPasskeyDisplay(callback) should be replaced with
+     * ble.securityManager().onPasskeyDisplay(callback).
+     */
+    void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback) {
+        return securityManager().onPasskeyDisplay(callback);
+    }
+
+private:
+    /**
+     * Implementation of init() [internal to BLE_API].
+     *
+     * The implementation is separated into a private method because it isn't
+     * suitable to be included in the header.
+     */
+    ble_error_t initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback);
+
+private:
+    BLE(const BLE&);
+    BLE &operator=(const BLE &);
+
+private:
+    InstanceID_t     instanceID;
+    BLEInstanceBase *transport; /* The device-specific backend */
+};
+
+typedef BLE BLEDevice; /* DEPRECATED. This type alias is retained for the sake of compatibility with older
+                        * code. Will be dropped at some point soon.*/
+
+#endif // ifndef __BLE_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/BLEInstanceBase.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,60 @@
+/* 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 __BLE_DEVICE_INSTANCE_BASE__
+#define __BLE_DEVICE_INSTANCE_BASE__
+
+#include "Gap.h"
+#include "ble/SecurityManager.h"
+#include "ble/BLE.h"
+
+/* Forward declarations. */
+class GattServer;
+class GattClient;
+
+/**
+ *  The interface for the transport object to be created by the target library's
+ *  createBLEInstance().
+ */
+class BLEInstanceBase
+{
+public:
+    virtual ble_error_t            init(BLE::InstanceID_t instanceID,
+                                        FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> initCallback) = 0;
+    virtual bool                   hasInitialized(void) const = 0;
+    virtual ble_error_t            shutdown(void)             = 0;
+    virtual const char *           getVersion(void)           = 0;
+    virtual Gap&                   getGap()                   = 0;
+    virtual const Gap&             getGap() const             = 0;
+    virtual GattServer&            getGattServer()            = 0;
+    virtual const GattServer&      getGattServer() const      = 0;
+    virtual GattClient&            getGattClient()            = 0;
+    virtual SecurityManager&       getSecurityManager()       = 0;
+    virtual const SecurityManager& getSecurityManager() const = 0;
+    virtual void                   waitForEvent(void)         = 0;
+};
+
+/**
+ * BLE uses composition to hide an interface object encapsulating the
+ * backend transport.
+ *
+ * The following API is used to create the singleton interface object. An
+ * implementation for this function must be provided by the device-specific
+ * library, otherwise there will be a linker error.
+ */
+extern BLEInstanceBase *createBLEInstance(void);
+
+#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/BLEProtocol.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,69 @@
+/* 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 __BLE_PROTOCOL_H__
+#define __BLE_PROTOCOL_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <algorithm>
+
+/**
+ * A common namespace for types and constants used everywhere in BLE API.
+ */
+namespace BLEProtocol {
+    /**<
+     * A simple container for the enumeration of address-types for Protocol addresses.
+     *
+     * Adding a struct to encapsulate the contained enumeration prevents
+     * polluting the BLEProtocol namespace with the enumerated values. It also
+     * allows type-aliases for the enumeration while retaining the enumerated
+     * values. i.e. doing:
+     *       typedef AddressType AliasedType;
+     *
+     * would allow the use of AliasedType::PUBLIC in code.
+     */
+    struct AddressType {
+        /**< Address-types for Protocol addresses. */
+        enum Type {
+            PUBLIC = 0,
+            RANDOM_STATIC,
+            RANDOM_PRIVATE_RESOLVABLE,
+            RANDOM_PRIVATE_NON_RESOLVABLE
+        };
+    };
+    typedef AddressType::Type AddressType_t;  /**< Alias for AddressType::Type */
+
+    static const size_t ADDR_LEN = 6;         /**< Length (in octets) of the BLE MAC address. */
+    typedef uint8_t AddressBytes_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */
+
+    /**
+     * BLE address. It contains an address-type (@ref AddressType_t) and bytes (@ref AddressBytes_t).
+     */
+    struct Address_t {
+        AddressType_t  type;    /**< @ref AddressType_t */
+        AddressBytes_t address; /**< @ref AddressBytes_t */
+
+        Address_t(AddressType_t typeIn, const AddressBytes_t& addressIn) : type(typeIn) {
+            std::copy(addressIn, addressIn + ADDR_LEN, address);
+        }
+
+        Address_t() : type(), address() {
+        }
+    };
+};
+
+#endif /* __BLE_PROTOCOL_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/CallChainOfFunctionPointersWithContext.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,238 @@
+/* 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_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
+#define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
+
+#include <string.h>
+#include "FunctionPointerWithContext.h"
+#include "SafeBool.h"
+
+
+/** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in
+ * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code,
+ * but can be used for other purposes.
+ *
+ * Example:
+ * @code
+ *
+ * CallChainOfFunctionPointersWithContext<void *> chain;
+ *
+ * void first(void *context) {
+ *     printf("'first' function.\n");
+ * }
+ *
+ * void second(void *context) {
+ *     printf("'second' function.\n");
+ * }
+ *
+ * class Test {
+ * public:
+ *     void f(void *context) {
+ *         printf("A::f (class member).\n");
+ *     }
+ * };
+ *
+ * int main() {
+ *     Test test;
+ *
+ *     chain.add(second);
+ *     chain.add_front(first);
+ *     chain.add(&test, &Test::f);
+ *     chain.call();
+ * }
+ * @endcode
+ */
+
+template <typename ContextType>
+class CallChainOfFunctionPointersWithContext : public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > {
+public:
+    typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
+
+public:
+    /** Create an empty chain.
+     *
+     *  @param size (optional) Initial size of the chain.
+     */
+    CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
+        /* empty */
+    }
+
+    virtual ~CallChainOfFunctionPointersWithContext() {
+        clear();
+    }
+
+    /** Add a function at the front of the chain.
+     *
+     *  @param function A pointer to a void function.
+     *
+     *  @returns
+     *  The function object created for 'function'.
+     */
+    pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
+        return common_add(new FunctionPointerWithContext<ContextType>(function));
+    }
+
+    /** Add a function at the front of the chain.
+     *
+     *  @param tptr Pointer to the object to call the member function on.
+     *  @param mptr Pointer to the member function to be called.
+     *
+     *  @returns
+     *  The function object created for 'tptr' and 'mptr'.
+     */
+    template<typename T>
+    pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
+        return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
+    }
+
+    /** Add a function at the front of the chain.
+     *
+     *  @param func The FunctionPointerWithContext to add.
+     */
+    pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType>& func) {
+        return common_add(new FunctionPointerWithContext<ContextType>(func));
+    }
+
+    /** 
+     * Detach a function pointer from a callchain
+     * 
+     * @oaram toDetach FunctionPointerWithContext to detach from this callchain
+     * 
+     * @return true if a function pointer has been detached and false otherwise
+     */ 
+    bool detach(const FunctionPointerWithContext<ContextType>& toDetach) { 
+        pFunctionPointerWithContext_t current = chainHead;
+        pFunctionPointerWithContext_t previous = NULL;
+
+        while (current) {
+            if(*current == toDetach) { 
+                if(previous == NULL) {
+                    if(currentCalled == current) { 
+                        currentCalled = NULL;
+                    }
+                    chainHead = current->getNext();
+                } else {
+                    if(currentCalled == current) { 
+                        currentCalled = previous;
+                    }
+                    previous->chainAsNext(current->getNext());
+                }
+                delete current;
+                return true;
+            }
+
+            previous = current;
+            current = current->getNext();
+        }
+
+        return false;
+    }
+
+    /** Clear the call chain (remove all functions in the chain).
+     */
+    void clear(void) {
+        pFunctionPointerWithContext_t fptr = chainHead;
+        while (fptr) {
+            pFunctionPointerWithContext_t deadPtr = fptr;
+            fptr = deadPtr->getNext();
+            delete deadPtr;
+        }
+
+        chainHead = NULL;
+    }
+
+    bool hasCallbacksAttached(void) const {
+        return (chainHead != NULL);
+    }
+
+    /** Call all the functions in the chain in sequence
+     */
+    void call(ContextType context) {
+        ((const CallChainOfFunctionPointersWithContext*) this)->call(context);
+    }
+
+    /**
+     * @brief same as above but const 
+     */
+    void call(ContextType context) const {
+        currentCalled = chainHead;
+
+        while(currentCalled) { 
+            currentCalled->call(context);
+            // if this was the head and the call removed the head
+            if(currentCalled == NULL) { 
+                currentCalled = chainHead;
+            } else {
+                currentCalled = currentCalled->getNext();
+            }
+        }
+    }
+
+    /**
+     * @brief same as above but with function call operator
+     * \code
+     * 
+     * void first(bool);
+     * void second(bool);
+     * 
+     * CallChainOfFunctionPointerWithContext<bool> foo;
+     * 
+     * foo.attach(first);
+     * foo.attach(second);
+     * 
+     * // call the callchain like a function
+     * foo(true);
+     * 
+     * \endcode
+     */
+    void operator()(ContextType context) const {
+        call(context);
+    }
+
+    /**
+     * @brief bool conversion operation
+     */
+    bool toBool() const {
+        return chainHead != NULL;
+    }
+
+private:
+    pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
+        if (chainHead == NULL) {
+            chainHead = pf;
+        } else {
+            pf->chainAsNext(chainHead);
+            chainHead = pf;
+        }
+
+        return chainHead;
+    }
+
+private:
+    pFunctionPointerWithContext_t chainHead;
+    // iterator during a function call, this has to be mutable because the call function is const.
+    // Note: mutable is the correct behaviour here, the iterator never leak outside the object.
+    // So the object can still be seen as logically const even if it change its internal state
+    mutable pFunctionPointerWithContext_t currentCalled;
+
+
+    /* Disallow copy constructor and assignment operators. */
+private:
+    CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
+    CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/CharacteristicDescriptorDiscovery.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,99 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+#define __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+
+#include "FunctionPointerWithContext.h"
+
+class DiscoveredCharacteristic;                         // forward declaration
+class DiscoveredCharacteristicDescriptor;               // forward declaration
+
+/**
+ * @brief Contain all definitions of callbacks and callbacks parameters types
+ * related to characteristic descriptor discovery.
+ *
+ * @details This class act like a namespace for characteristic descriptor discovery
+ * types. It act like ServiceDiscovery by providing callbacks and callbacks
+ * parameters types related to the characteristic descriptor discovery process but
+ * contrary to ServiceDiscovery class, it does not force the porter to use a
+ * specific interface for the characteristic descriptor discovery process.
+ */
+class CharacteristicDescriptorDiscovery {
+public:
+    /**
+     * @brief Parameter type of CharacteristicDescriptorDiscovery::DiscoveryCallback_t.
+     * @detail Every time a characteristic descriptor has been discovered, the callback
+     * registered for the discovery operation through GattClient::discoverCharacteristicDescriptors
+     * or DiscoveredCharacteristic::discoverDescriptors will be called with this parameter.
+     *
+     */
+    struct DiscoveryCallbackParams_t {
+        /**
+         * The characteristic owning the DiscoveredCharacteristicDescriptor
+         */
+        const DiscoveredCharacteristic& characteristic;
+
+        /**
+         * The characteristic descriptor discovered
+         */
+        const DiscoveredCharacteristicDescriptor& descriptor;
+    };
+
+    /**
+     * @brief Parameter type of CharacteristicDescriptorDiscovery::TerminationCallback_t.
+     * @details Once a characteristic descriptor discovery process terminate, the termination
+     * callback registered for the discovery operation through
+     * GattClient::discoverCharacteristicDescriptors or DiscoveredCharacteristic::discoverDescriptors
+     * will be called with this parameter.
+     */
+    struct TerminationCallbackParams_t {
+        /**
+         * The characteristic for which the descriptors has been discovered
+         */
+        const DiscoveredCharacteristic& characteristic;
+
+        /**
+         * status of the discovery operation
+         */
+        ble_error_t status;
+    };
+
+    /**
+     * @brief Callback type for when a matching characteristic descriptor is found during
+     * characteristic descriptor discovery.
+     *
+     * @param param A pointer to a DiscoveryCallbackParams_t object which will remain
+     * valid for the lifetime of the callback. Memory for this object is owned by
+     * the BLE_API eventing framework. The application can safely make a persistent
+     * shallow-copy of this object in order to work with the service beyond the
+     * callback.
+     */
+    typedef FunctionPointerWithContext<const DiscoveryCallbackParams_t*> DiscoveryCallback_t;
+
+    /**
+     * @brief Callback type for when characteristic descriptor discovery terminates.
+     *
+     * @param param A pointer to a TerminationCallbackParams_t object which will remain
+     * valid for the lifetime of the callback. Memory for this object is owned by
+     * the BLE_API eventing framework. The application can safely make a persistent
+     * shallow-copy of this object in order to work with the service beyond the
+     * callback.
+     */
+    typedef FunctionPointerWithContext<const TerminationCallbackParams_t*> TerminationCallback_t;
+};
+
+#endif // ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/DiscoveredCharacteristic.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,329 @@
+/* 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 __DISCOVERED_CHARACTERISTIC_H__
+#define __DISCOVERED_CHARACTERISTIC_H__
+
+#include "UUID.h"
+#include "Gap.h"
+#include "GattAttribute.h"
+#include "GattClient.h"
+#include "CharacteristicDescriptorDiscovery.h"
+#include "ble/DiscoveredCharacteristicDescriptor.h"
+
+/**
+ * @brief Representation of a characteristic discovered during a GattClient
+ * discovery procedure (see GattClient::launchServiceDiscovery ).
+ *
+ * @detail Provide detailed informations about a discovered characteristic like:
+ *     - Its UUID (see #getUUID).
+ *     - The most important handles of the characteristic definition
+ *       (see #getDeclHandle, #getValueHandle, #getLastHandle )
+ *     - Its properties (see #getProperties).
+ * This class also provide functions to operate on the characteristic:
+ *     - Read the characteristic value (see #read)
+ *     - Writing a characteristic value (see #write or #writeWoResponse)
+ *     - Discover descriptors inside the characteristic definition. These descriptors
+ *       extends the characteristic. More information about descriptor usage is
+ *       available in DiscoveredCharacteristicDescriptor class.
+ */
+class DiscoveredCharacteristic {
+public:
+    struct Properties_t {
+        uint8_t _broadcast       :1; /**< Broadcasting the value permitted. */
+        uint8_t _read            :1; /**< Reading the value permitted. */
+        uint8_t _writeWoResp     :1; /**< Writing the value with Write Command permitted. */
+        uint8_t _write           :1; /**< Writing the value with Write Request permitted. */
+        uint8_t _notify          :1; /**< Notifications of the value permitted. */
+        uint8_t _indicate        :1; /**< Indications of the value permitted. */
+        uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */
+
+    public:
+        bool broadcast(void)       const {return _broadcast;      }
+        bool read(void)            const {return _read;           }
+        bool writeWoResp(void)     const {return _writeWoResp;    }
+        bool write(void)           const {return _write;          }
+        bool notify(void)          const {return _notify;         }
+        bool indicate(void)        const {return _indicate;       }
+        bool authSignedWrite(void) const {return _authSignedWrite;}
+
+        /**
+         * @brief "Equal to" operator for DiscoveredCharacteristic::Properties_t
+         *
+         * @param lhs[in] The left hand side of the equality expression
+         * @param rhs[in] The right hand side of the equality expression
+         *
+         * @return true if operands are equals, false otherwise.
+         */
+        friend bool operator==(Properties_t lhs, Properties_t rhs) {
+            return lhs._broadcast == rhs._broadcast &&
+                   lhs._read == rhs._read &&
+                   lhs._writeWoResp == rhs._writeWoResp &&
+                   lhs._write == rhs._write &&
+                   lhs._notify == rhs._notify &&
+                   lhs._indicate == rhs._indicate &&
+                   lhs._authSignedWrite == rhs._authSignedWrite;
+        }
+
+        /**
+         * @brief "Not equal to" operator for DiscoveredCharacteristic::Properties_t
+         *
+         * @param lhs The right hand side of the expression
+         * @param rhs The left hand side of the expression
+         *
+         * @return true if operands are not equals, false otherwise.
+         */
+        friend bool operator!=(Properties_t lhs, Properties_t rhs) {
+            return !(lhs == rhs);
+        }
+
+    private:
+        operator uint8_t()  const; /* Disallow implicit conversion into an integer. */
+        operator unsigned() const; /* Disallow implicit conversion into an integer. */
+    };
+
+    /**
+     * Initiate (or continue) a read for the value attribute, optionally at a
+     * given offset. If the characteristic or descriptor to be read is longer
+     * than ATT_MTU - 1, this function must be called multiple times with
+     * appropriate offset to read the complete value.
+     *
+     * @param offset[in] The position - in the characteristic value bytes stream - where
+     * the read operation begin.
+     *
+     * @return BLE_ERROR_NONE if a read has been initiated, or
+     *         BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
+     *         BLE_STACK_BUSY if some client procedure is already in progress, or
+     *         BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
+     */
+    ble_error_t read(uint16_t offset = 0) const;
+
+    /**
+     * @brief Same as #read(uint16_t) const but allow the user to register a callback
+     * which will be fired once the read is done.
+     *
+     * @param offset[in] The position - in the characteristic value bytes stream - where
+     * the read operation begin.
+     * @param onRead[in] Continuation of the read operation
+     */
+    ble_error_t read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const;
+
+    /**
+     * Perform a write without response procedure.
+     *
+     * @param[in]  length
+     *           The amount of data being written.
+     * @param[in]  value
+     *           The bytes being written.
+     *
+     * @note   It is important to note that a write without response will generate
+     *         an onDataSent() callback when the packet has been transmitted. There
+     *         will be a BLE-stack specific limit to the number of pending
+     *         writeWoResponse operations; the user may want to use the onDataSent()
+     *         callback for flow-control.
+     *
+     * @retval BLE_ERROR_NONE Successfully started the Write procedure, or
+     *         BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
+     *         BLE_STACK_BUSY if some client procedure is already in progress, or
+     *         BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or
+     *         BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
+     */
+    ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const;
+
+    /**
+     * Initiate a GATT Characteristic Descriptor Discovery procedure for descriptors within this characteristic.
+     *
+     * @param[in] onDescriptorDiscovered This callback will be called every time a descriptor is discovered
+     * @param[in] onTermination This callback will be called when the discovery process is over.
+     *
+     * @return BLE_ERROR_NONE if descriptor discovery is launched successfully; else an appropriate error.
+     */
+    ble_error_t discoverDescriptors(const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& onDescriptorDiscovered,
+                                    const CharacteristicDescriptorDiscovery::TerminationCallback_t& onTermination) const;
+
+    /**
+     * Perform a write procedure.
+     *
+     * @param[in]  length
+     *           The amount of data being written.
+     * @param[in]  value
+     *           The bytes being written.
+     *
+     * @note   It is important to note that a write will generate
+     *         an onDataWritten() callback when the peer acknowledges the request.
+     *
+     * @retval BLE_ERROR_NONE Successfully started the Write procedure, or
+     *         BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
+     *         BLE_STACK_BUSY if some client procedure is already in progress, or
+     *         BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or
+     *         BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties.
+     */
+    ble_error_t write(uint16_t length, const uint8_t *value) const;
+
+    /**
+     * Same as #write(uint16_t, const uint8_t *) const but register a callback
+     * which will be called once the data has been written.
+     *
+     * @param[in] length The amount of bytes to write.
+     * @param[in] value The bytes to write.
+     * @param[in] onRead Continuation callback for the write operation
+     */
+    ble_error_t write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onWrite) const;
+
+    void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
+        uuid.setupLong(longUUID, order);
+    }
+
+public:
+    /**
+     * @brief Get the UUID of the discovered characteristic
+     * @return the UUID of this characteristic
+     */
+    const UUID& getUUID(void) const {
+        return uuid;
+    }
+
+    /**
+     * @brief Get the properties of this characteristic
+     * @return the set of properties of this characteristic
+     */
+    const Properties_t& getProperties(void) const {
+        return props;
+    }
+
+    /**
+     * @brief Get the declaration handle of this characteristic.
+     * @detail The declaration handle is the first handle of a characteristic
+     * definition. The value accessible at this handle contains the following
+     * informations:
+     *    - The characteristics properties (see Properties_t). This value can
+     *      be accessed by using #getProperties .
+     *    - The characteristic value attribute handle. This field can be accessed
+     *      by using #getValueHandle .
+     *    - The characteristic UUID, this value can be accessed by using the
+     *      function #getUUID .
+     * @return the declaration handle of this characteristic.
+     */
+    GattAttribute::Handle_t getDeclHandle(void) const {
+        return declHandle;
+    }
+
+    /**
+     * @brief Return the handle used to access the value of this characteristic.
+     * @details This handle is the one provided in the characteristic declaration
+     * value. Usually, it is equal to #getDeclHandle() + 1. But it is not always
+     * the case. Anyway, users are allowed to use #getDeclHandle() + 1 to access
+     * the value of a characteristic.
+     * @return The handle to access the value of this characteristic.
+     */
+    GattAttribute::Handle_t getValueHandle(void) const {
+        return valueHandle;
+    }
+
+    /**
+     * @brief Return the last handle of the characteristic definition.
+     * @details A Characteristic definition can contain a lot of handles:
+     *     - one for the declaration (see #getDeclHandle)
+     *     - one for the value (see #getValueHandle)
+     *     - zero of more for the characteristic descriptors.
+     * This handle is the last handle of the characteristic definition.
+     * @return The last handle of this characteristic definition.
+     */
+    GattAttribute::Handle_t getLastHandle(void) const {
+        return lastHandle;
+    }
+
+    /**
+     * @brief Return the GattClient which can operate on this characteristic.
+     * @return The GattClient which can operate on this characteristic.
+     */
+    GattClient* getGattClient() {
+        return gattc;
+    }
+
+    /**
+     * @brief Return the GattClient which can operate on this characteristic.
+     * @return The GattClient which can operate on this characteristic.
+     */
+    const GattClient* getGattClient() const {
+        return gattc;
+    }
+
+    /**
+     * @brief Return the connection handle to the GattServer which contain
+     * this characteristic.
+     * @return the connection handle to the GattServer which contain
+     * this characteristic.
+     */
+    Gap::Handle_t getConnectionHandle() const {
+        return connHandle;
+    }
+
+    /**
+     * @brief "Equal to" operator for DiscoveredCharacteristic
+     *
+     * @param lhs[in] The left hand side of the equality expression
+     * @param rhs[in] The right hand side of the equality expression
+     *
+     * @return true if operands are equals, false otherwise.
+     */
+    friend bool operator==(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) {
+        return lhs.gattc == rhs.gattc &&
+               lhs.uuid == rhs.uuid &&
+               lhs.props == rhs.props &&
+               lhs.declHandle == rhs.declHandle &&
+               lhs.valueHandle == rhs.valueHandle &&
+               lhs.lastHandle == rhs.lastHandle &&
+               lhs.connHandle == rhs.connHandle;
+    }
+
+    /**
+     * @brief "Not equal to" operator for DiscoveredCharacteristic
+     *
+     * @param lhs[in] The right hand side of the expression
+     * @param rhs[in] The left hand side of the expression
+     *
+     * @return true if operands are not equals, false otherwise.
+     */
+    friend bool operator !=(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) {
+        return !(lhs == rhs);
+    }
+
+public:
+    DiscoveredCharacteristic() : gattc(NULL),
+                                 uuid(UUID::ShortUUIDBytes_t(0)),
+                                 props(),
+                                 declHandle(GattAttribute::INVALID_HANDLE),
+                                 valueHandle(GattAttribute::INVALID_HANDLE),
+                                 lastHandle(GattAttribute::INVALID_HANDLE),
+                                 connHandle() {
+        /* empty */
+    }
+
+protected:
+    GattClient              *gattc;
+
+protected:
+    UUID                     uuid;
+    Properties_t             props;
+    GattAttribute::Handle_t  declHandle;
+    GattAttribute::Handle_t  valueHandle;
+    GattAttribute::Handle_t  lastHandle;
+
+    Gap::Handle_t            connHandle;
+};
+
+#endif /*__DISCOVERED_CHARACTERISTIC_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/DiscoveredCharacteristicDescriptor.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,111 @@
+/* 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 __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
+#define __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
+
+#include "UUID.h"
+#include "Gap.h"
+#include "GattAttribute.h"
+#include "GattClient.h"
+#include "CharacteristicDescriptorDiscovery.h"
+
+/**
+ * @brief Representation of a descriptor discovered during a GattClient
+ * discovery procedure (see GattClient::discoverCharacteristicDescriptors or
+ * DiscoveredCharacteristic::discoverDescriptors ).
+ *
+ * @detail Provide detailed informations about a discovered characteristic descriptor
+ * like:
+ *     - Its UUID (see #getUUID).
+ *     - Its handle (see #getAttributeHandle)
+ * Basic read (see GattClient::read) and write (see GattClient::write) procedure from
+ * GattClient can be used access the value of the descriptor.
+ *
+ * @todo read member function
+ * @todo write member function
+ * @todo enumeration of standard descriptors
+ */
+class DiscoveredCharacteristicDescriptor {
+
+public:
+
+    /**
+     * @brief construct a new instance of a DiscoveredCharacteristicDescriptor
+     *
+     * @param client The client from where the descriptor has been discovered
+     * @param connectionHandle The connection handle on which the descriptor has
+     * been discovered
+     * @param attributeHandle The handle of the attribute containing this descriptor
+     * @param uuid The UUID of the descriptor
+     */
+    DiscoveredCharacteristicDescriptor(
+        GattClient* client, Gap::Handle_t connectionHandle,  GattAttribute::Handle_t attributeHandle, const UUID& uuid) :
+        _client(client), _connectionHandle(connectionHandle), _uuid(uuid), _gattHandle(attributeHandle) {
+
+    }
+
+    /**
+     * @brief Return the GattClient which can operate on this descriptor.
+     * @return The GattClient which can operate on this descriptor.
+     */
+    GattClient* getGattClient() {
+        return _client;
+    }
+
+    /**
+     * @brief Return the GattClient which can operate on this descriptor.
+     * @return The GattClient which can operate on this descriptor.
+     */
+    const GattClient* getGattClient() const {
+        return _client;
+    }
+
+    /**
+     * @brief Return the connection handle to the GattServer which contain
+     * this descriptor.
+     * @return the connection handle to the GattServer which contain
+     * this descriptor.
+     */
+    Gap::Handle_t getConnectionHandle() const {
+        return _connectionHandle;
+    }
+
+    /**
+     * @brief Return the UUID of this descriptor
+     * @return the UUID of this descriptor
+     */
+    const UUID& getUUID(void) const {
+        return _uuid;
+    }
+
+    /**
+     * @brief Return the attribute handle to use to access to this descriptor
+     * on the gatt server.
+     * @return The attribute handle of the descriptor
+     */
+    GattAttribute::Handle_t getAttributeHandle() const {
+        return _gattHandle;
+    }
+
+private:
+    GattClient  *_client;
+    Gap::Handle_t _connectionHandle;
+    UUID _uuid;
+    GattAttribute::Handle_t _gattHandle;
+};
+
+#endif /*__DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/DiscoveredService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,71 @@
+/* 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 __DISCOVERED_SERVICE_H__
+#define __DISCOVERED_SERVICE_H__
+
+#include "UUID.h"
+#include "GattAttribute.h"
+
+/**@brief Type for holding information about the service and the characteristics found during
+ *        the discovery process.
+ */
+class DiscoveredService {
+public:
+     void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) {
+         uuid        = uuidIn;
+         startHandle = startHandleIn;
+         endHandle   = endHandleIn;
+     }
+
+     void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) {
+         startHandle = startHandleIn;
+         endHandle   = endHandleIn;
+     }
+
+    void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
+         uuid.setupLong(longUUID, order);
+    }
+
+public:
+    const UUID &getUUID(void) const {
+        return uuid;
+    }
+
+    const GattAttribute::Handle_t& getStartHandle(void) const {
+        return startHandle;
+    }
+    const GattAttribute::Handle_t& getEndHandle(void) const {
+        return endHandle;
+    }
+
+public:
+    DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)),
+                          startHandle(GattAttribute::INVALID_HANDLE),
+                          endHandle(GattAttribute::INVALID_HANDLE) {
+        /* empty */
+    }
+
+private:
+    DiscoveredService(const DiscoveredService &);
+
+private:
+    UUID                    uuid;        /**< UUID of the service.  */
+    GattAttribute::Handle_t startHandle; /**< Service Handle Range. */
+    GattAttribute::Handle_t endHandle;   /**< Service Handle Range. */
+};
+
+#endif /*__DISCOVERED_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/FunctionPointerWithContext.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,212 @@
+/* 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_FUNCTIONPOINTER_WITH_CONTEXT_H
+#define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
+
+#include <string.h>
+#include "SafeBool.h"
+
+/** A class for storing and calling a pointer to a static or member void function
+ *  that takes a context.
+ */
+template <typename ContextType>
+class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > {
+public:
+    typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
+    typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t;
+    typedef void (*pvoidfcontext_t)(ContextType context);
+
+    /** Create a FunctionPointerWithContext, attaching a static function.
+     *
+     *  @param function The void static function to attach (default is none).
+     */
+    FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
+        _memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
+        attach(function);
+    }
+
+    /** Create a FunctionPointerWithContext, attaching a member function.
+     *
+     *  @param object The object pointer to invoke the member function on (the "this" pointer).
+     *  @param function The address of the void member function to attach.
+     */
+    template<typename T>
+    FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
+        _memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
+        attach(object, member);
+    }
+
+    FunctionPointerWithContext(const FunctionPointerWithContext& that) : 
+        _memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) {
+    }
+
+    FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) {
+        _memberFunctionAndPointer = that._memberFunctionAndPointer;
+        _caller = that._caller; 
+        _next = NULL;
+        return *this;
+    }
+
+    /** Attach a static function.
+     *
+     *  @param function The void static function to attach (default is none).
+     */
+    void attach(void (*function)(ContextType context) = NULL) {
+        _function = function;
+        _caller = functioncaller;
+    }
+
+    /** Attach a member function.
+     *
+     *  @param object The object pointer to invoke the member function on (the "this" pointer).
+     *  @param function The address of the void member function to attach.
+     */
+    template<typename T>
+    void attach(T *object, void (T::*member)(ContextType context)) {
+        _memberFunctionAndPointer._object = static_cast<void *>(object);
+        memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member));
+        _caller = &FunctionPointerWithContext::membercaller<T>;
+    }
+
+    /** Call the attached static or member function; if there are chained
+     *  FunctionPointers their callbacks are invoked as well.
+     *  @Note: All chained callbacks stack up, so hopefully there won't be too
+     *  many FunctionPointers in a chain. */
+    void call(ContextType context) const {
+        _caller(this, context);
+    }
+
+    /**
+     * @brief Same as above
+     */
+    void operator()(ContextType context) const {
+        call(context);
+    }
+
+    /** Same as above, workaround for mbed os FunctionPointer implementation. */
+    void call(ContextType context) {
+        ((const FunctionPointerWithContext*)  this)->call(context);
+    }
+
+    typedef void (FunctionPointerWithContext::*bool_type)() const;
+
+    /** 
+     * implementation of safe bool operator
+     */
+    bool toBool() const {
+        return (_function || _memberFunctionAndPointer._object);
+    }
+
+    /**
+     * Set up an external FunctionPointer as a next in the chain of related
+     * callbacks. Invoking call() on the head FunctionPointer will invoke all
+     * chained callbacks.
+     *
+     * Refer to 'CallChain' as an alternative.
+     */
+    void chainAsNext(pFunctionPointerWithContext_t next) {
+        _next = next;
+    }
+
+    pFunctionPointerWithContext_t getNext(void) const {
+        return _next;
+    }
+
+    pvoidfcontext_t get_function() const {
+        return (pvoidfcontext_t)_function;
+    }
+
+    friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) {
+        return rhs._caller == lhs._caller &&
+               memcmp(
+                   &rhs._memberFunctionAndPointer, 
+                   &lhs._memberFunctionAndPointer, 
+                   sizeof(rhs._memberFunctionAndPointer)
+               ) == 0;
+    }
+
+private:
+    template<typename T>
+    static void membercaller(cpFunctionPointerWithContext_t self, ContextType context) {
+        if (self->_memberFunctionAndPointer._object) {
+            T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
+            void (T::*m)(ContextType);
+            memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m));
+            (o->*m)(context);
+        }
+    }
+
+    static void functioncaller(cpFunctionPointerWithContext_t self, ContextType context) {
+        if (self->_function) {
+            self->_function(context);
+        }
+    }
+
+    struct MemberFunctionAndPtr {
+        /*
+         * Forward declaration of a class and a member function to this class.
+         * Because the compiler doesn't know anything about the forwarded member
+         * function, it will always use the biggest size and the biggest alignment
+         * that a member function can take for objects of type UndefinedMemberFunction.
+         */
+        class UndefinedClass;
+        typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType);
+
+        void* _object;
+        union {
+            char _memberFunction[sizeof(UndefinedMemberFunction)];
+            UndefinedMemberFunction _alignment;
+        };
+    };
+
+    union {
+        pvoidfcontext_t _function;                      /**< Static function pointer - NULL if none attached */
+        /**
+         * object this pointer and pointer to member -
+         * _memberFunctionAndPointer._object will be NULL if none attached
+         */
+        mutable MemberFunctionAndPtr _memberFunctionAndPointer;
+    };
+
+    void (*_caller)(const FunctionPointerWithContext*, ContextType);
+
+    pFunctionPointerWithContext_t _next;                /**< Optional link to make a chain out of functionPointers. This
+                                                         *   allows chaining function pointers without requiring
+                                                         *   external memory to manage the chain. Refer to
+                                                         *   'CallChain' as an alternative. */
+};
+
+/**
+ * @brief Create a new FunctionPointerWithContext which bind an instance and a  
+ * a member function together.
+ * @details This little helper is a just here to eliminate the need to write the
+ * FunctionPointerWithContext type each time you want to create one by kicking 
+ * automatic type deduction of function templates. With this function, it is easy 
+ * to write only one entry point for functions which expect a FunctionPointer 
+ * in parameters.
+ * 
+ * @param object to bound with member function
+ * @param member The member function called
+ * @return a new FunctionPointerWithContext
+ */
+template<typename T, typename ContextType>
+FunctionPointerWithContext<ContextType> makeFunctionPointer(T *object, void (T::*member)(ContextType context)) 
+{
+    return FunctionPointerWithContext<ContextType>(object, member);
+}
+
+#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/Gap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1401 @@
+/* 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 __GAP_H__
+#define __GAP_H__
+
+#include "ble/BLEProtocol.h"
+#include "GapAdvertisingData.h"
+#include "GapAdvertisingParams.h"
+#include "GapScanningParams.h"
+#include "GapEvents.h"
+#include "CallChainOfFunctionPointersWithContext.h"
+#include "FunctionPointerWithContext.h"
+#include "deprecate.h"
+
+/* Forward declarations for classes that will only be used for pointers or references in the following. */
+class GapAdvertisingParams;
+class GapScanningParams;
+class GapAdvertisingData;
+
+class Gap {
+    /*
+     * DEPRECATION ALERT: all of the APIs in this `public` block are deprecated.
+     * They have been relocated to the class BLEProtocol.
+     */
+public:
+    /**
+     * Address-type for BLEProtocol addresses.
+     *
+     * @note: deprecated. Use BLEProtocol::AddressType_t instead.
+     */
+    typedef BLEProtocol::AddressType_t AddressType_t;
+
+    /**
+     * Address-type for BLEProtocol addresses.
+     * @note: deprecated. Use BLEProtocol::AddressType_t instead.
+     */
+    typedef BLEProtocol::AddressType_t addr_type_t;
+
+    /**
+     * Address-type for BLEProtocol addresses.
+     * \deprecated: Use BLEProtocol::AddressType_t instead.
+     *
+     * DEPRECATION ALERT: The following constants have been left in their
+     * deprecated state to transparenly support existing applications which may
+     * have used Gap::ADDR_TYPE_*.
+     */
+    enum DeprecatedAddressType_t {
+        ADDR_TYPE_PUBLIC                        = BLEProtocol::AddressType::PUBLIC,
+        ADDR_TYPE_RANDOM_STATIC                 = BLEProtocol::AddressType::RANDOM_STATIC,
+        ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE     = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE,
+        ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
+    };
+
+    static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; /**< Length (in octets) of the BLE MAC address. */
+    typedef BLEProtocol::AddressBytes_t Address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::AddressBytes_t instead. */
+    typedef BLEProtocol::AddressBytes_t address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::AddressBytes_t instead. */
+
+public:
+    enum TimeoutSource_t {
+        TIMEOUT_SRC_ADVERTISING      = 0x00, /**< Advertising timeout. */
+        TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */
+        TIMEOUT_SRC_SCAN             = 0x02, /**< Scanning timeout. */
+        TIMEOUT_SRC_CONN             = 0x03, /**< Connection timeout. */
+    };
+
+    /**
+     * Enumeration for disconnection reasons. The values for these reasons are
+     * derived from Nordic's implementation, but the reasons are meant to be
+     * independent of the transport. If you are returned a reason that is not
+     * covered by this enumeration, please refer to the underlying
+     * transport library.
+     */
+    enum DisconnectionReason_t {
+        CONNECTION_TIMEOUT                          = 0x08,
+        REMOTE_USER_TERMINATED_CONNECTION           = 0x13,
+        REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,  /**< Remote device terminated connection due to low resources.*/
+        REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF     = 0x15,  /**< Remote device terminated connection due to power off. */
+        LOCAL_HOST_TERMINATED_CONNECTION            = 0x16,
+        CONN_INTERVAL_UNACCEPTABLE                  = 0x3B,
+    };
+
+    /**
+     * Enumeration for whitelist advertising policy filter modes. The possible
+     * filter modes were obtained from the Bluetooth Core Specification
+     * 4.2 (Vol. 6), Part B, Section 4.3.2.
+     *
+     * @experimental
+     */
+    enum AdvertisingPolicyMode_t {
+        ADV_POLICY_IGNORE_WHITELIST = 0,
+        ADV_POLICY_FILTER_SCAN_REQS = 1,
+        ADV_POLICY_FILTER_CONN_REQS = 2,
+        ADV_POLICY_FILTER_ALL_REQS  = 3,
+    };
+
+    /**
+     * Enumeration for whitelist scanning policy filter modes. The possible
+     * filter modes were obtained from the Bluetooth Core Specification
+     * 4.2 (Vol. 6), Part B, Section 4.3.3.
+     *
+     * @experimental
+     */
+    enum ScanningPolicyMode_t {
+        SCAN_POLICY_IGNORE_WHITELIST = 0,
+        SCAN_POLICY_FILTER_ALL_ADV   = 1,
+    };
+
+    /**
+     * Enumeration for the whitelist initiator policy fiter modes. The possible
+     * filter modes were obtained from the Bluetooth Core Specification
+     * 4.2 (vol. 6), Part B, Section 4.4.4.
+     *
+     * @experimental
+     */
+    enum InitiatorPolicyMode_t {
+        INIT_POLICY_IGNORE_WHITELIST = 0,
+        INIT_POLICY_FILTER_ALL_ADV   = 1,
+    };
+
+    /**
+     * Representation of a Bluetooth Low Enery Whitelist containing addresses.
+     *
+     * @experimental
+     */
+    struct Whitelist_t {
+        BLEProtocol::Address_t *addresses;
+        uint8_t                 size;
+        uint8_t                 capacity;
+        uint8_t                 bonds;
+    };
+
+
+    /* Describes the current state of the device (more than one bit can be set). */
+    struct GapState_t {
+        unsigned advertising : 1; /**< Peripheral is currently advertising. */
+        unsigned connected   : 1; /**< Peripheral is connected to a central. */
+    };
+
+    typedef uint16_t Handle_t; /* Type for connection handle. */
+
+    typedef struct {
+        uint16_t minConnectionInterval;        /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+        uint16_t maxConnectionInterval;        /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+        uint16_t slaveLatency;                 /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+        uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+    } ConnectionParams_t;
+
+    enum Role_t {
+        PERIPHERAL  = 0x1, /**< Peripheral Role. */
+        CENTRAL     = 0x2, /**< Central Role.    */
+    };
+
+    struct AdvertisementCallbackParams_t {
+        BLEProtocol::AddressBytes_t              peerAddr;
+        int8_t                                   rssi;
+        bool                                     isScanResponse;
+        GapAdvertisingParams::AdvertisingType_t  type;
+        uint8_t                                  advertisingDataLen;
+        const uint8_t                           *advertisingData;
+    };
+    typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t;
+
+    struct ConnectionCallbackParams_t {
+        Handle_t                    handle;
+        Role_t                      role;
+        BLEProtocol::AddressType_t  peerAddrType;
+        BLEProtocol::AddressBytes_t peerAddr;
+        BLEProtocol::AddressType_t  ownAddrType;
+        BLEProtocol::AddressBytes_t ownAddr;
+        const ConnectionParams_t   *connectionParams;
+
+        ConnectionCallbackParams_t(Handle_t                    handleIn,
+                                   Role_t                      roleIn,
+                                   BLEProtocol::AddressType_t  peerAddrTypeIn,
+                                   const uint8_t              *peerAddrIn,
+                                   BLEProtocol::AddressType_t  ownAddrTypeIn,
+                                   const uint8_t              *ownAddrIn,
+                                   const ConnectionParams_t   *connectionParamsIn) :
+            handle(handleIn),
+            role(roleIn),
+            peerAddrType(peerAddrTypeIn),
+            peerAddr(),
+            ownAddrType(ownAddrTypeIn),
+            ownAddr(),
+            connectionParams(connectionParamsIn) {
+            memcpy(peerAddr, peerAddrIn, ADDR_LEN);
+            memcpy(ownAddr, ownAddrIn, ADDR_LEN);
+        }
+    };
+
+    struct DisconnectionCallbackParams_t {
+        Handle_t              handle;
+        DisconnectionReason_t reason;
+
+        DisconnectionCallbackParams_t(Handle_t              handleIn,
+                                      DisconnectionReason_t reasonIn) :
+            handle(handleIn),
+            reason(reasonIn)
+        {}
+    };
+
+    static const uint16_t UNIT_1_25_MS  = 1250; /**< Number of microseconds in 1.25 milliseconds. */
+    static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) {
+        return (durationInMillis * 1000) / UNIT_1_25_MS;
+    }
+
+    typedef FunctionPointerWithContext<TimeoutSource_t> TimeoutEventCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<TimeoutSource_t> TimeoutEventCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const ConnectionCallbackParams_t *> ConnectionEventCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallbackChain_t;
+
+    typedef FunctionPointerWithContext<bool> RadioNotificationEventCallback_t;
+
+    typedef FunctionPointerWithContext<const Gap *> GapShutdownCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const Gap *> GapShutdownCallbackChain_t;
+
+    /*
+     * The following functions are meant to be overridden in the platform-specific sub-class.
+     */
+public:
+    /**
+     * Set the BTLE MAC address and type. Please note that the address format is
+     * least significant byte first (LSB). Please refer to BLEProtocol::AddressBytes_t.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t setAddress(BLEProtocol::AddressType_t type, const BLEProtocol::AddressBytes_t address) {
+        /* avoid compiler warnings about unused variables */
+        (void)type;
+        (void)address;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Fetch the BTLE MAC address and type.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)typeP;
+        (void)address;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * @return Minimum Advertising interval in milliseconds for connectable
+     *      undirected and connectable directed event types.
+     */
+    virtual uint16_t getMinAdvertisingInterval(void) const {
+        return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * @return Minimum Advertising interval in milliseconds for scannable
+     *      undirected and non-connectable undirected event types.
+     */
+    virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {
+        return 0; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * @return Maximum Advertising interval in milliseconds.
+     */
+    virtual uint16_t getMaxAdvertisingInterval(void) const {
+        return 0xFFFF; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    virtual ble_error_t stopAdvertising(void) {
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Stop scanning. The current scanning parameters remain in effect.
+     *
+     * @retval BLE_ERROR_NONE if successfully stopped scanning procedure.
+     */
+    virtual ble_error_t stopScan() {
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Create a connection (GAP Link Establishment).
+     *
+     * @param peerAddr
+     *          48-bit address, LSB format.
+     * @param peerAddrType
+     *          Address type of the peer.
+     * @param connectionParams
+     *         Connection parameters.
+     * @param scanParams
+     *          Paramters to be used while scanning for the peer.
+     * @return  BLE_ERROR_NONE if connection establishment procedure is started
+     *     successfully. The connectionCallChain (if set) will be invoked upon
+     *     a connection event.
+     */
+    virtual ble_error_t connect(const BLEProtocol::AddressBytes_t  peerAddr,
+                                BLEProtocol::AddressType_t         peerAddrType,
+                                const ConnectionParams_t          *connectionParams,
+                                const GapScanningParams           *scanParams) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)peerAddr;
+        (void)peerAddrType;
+        (void)connectionParams;
+        (void)scanParams;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Create a connection (GAP Link Establishment).
+     *
+     * \deprecated: This funtion overloads Gap::connect(const BLEProtocol::Address_t  peerAddr,
+                                                        BLEProtocol::AddressType_t    peerAddrType,
+                                                        const ConnectionParams_t     *connectionParams,
+                                                        const GapScanningParams      *scanParams)
+     *      to maintain backward compatibility for change from Gap::AddressType_t to BLEProtocol::AddressType_t
+     */
+    ble_error_t connect(const BLEProtocol::AddressBytes_t  peerAddr,
+                        DeprecatedAddressType_t            peerAddrType,
+                        const ConnectionParams_t          *connectionParams,
+                        const GapScanningParams           *scanParams)
+    __deprecated_message("Gap::DeprecatedAddressType_t is deprecated, use BLEProtocol::AddressType_t instead") {
+        return connect(peerAddr, (BLEProtocol::AddressType_t) peerAddrType, connectionParams, scanParams);
+    }
+
+    /**
+     * This call initiates the disconnection procedure, and its completion will
+     * be communicated to the application with an invocation of the
+     * disconnectionCallback.
+     *
+     * @param  reason
+     *           The reason for disconnection; to be sent back to the peer.
+     */
+    virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) {
+        /* avoid compiler warnings about unused variables */
+        (void)connectionHandle;
+        (void)reason;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * This call initiates the disconnection procedure, and its completion will
+     * be communicated to the application with an invocation of the
+     * disconnectionCallback.
+     *
+     * @param  reason
+     *           The reason for disconnection; to be sent back to the peer.
+     *
+     * @note: This version of disconnect() doesn't take a connection handle. It
+     * works reliably only for stacks that are limited to a single
+     * connection. This API should be considered *deprecated* in favour of the
+     * alternative, which takes a connection handle. It will be dropped in the future.
+     */
+    virtual ble_error_t disconnect(DisconnectionReason_t reason) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)reason;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Get the GAP peripheral preferred connection parameters. These are the
+     * defaults that the peripheral would like to have in a connection. The
+     * choice of the connection parameters is eventually up to the central.
+     *
+     * @param[out] params
+     *               The structure where the parameters will be stored. Memory
+     *               for this is owned by the caller.
+     *
+     * @return BLE_ERROR_NONE if the parameters were successfully filled into
+     * the given structure pointed to by params.
+     */
+    virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)params;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Set the GAP peripheral preferred connection parameters. These are the
+     * defaults that the peripheral would like to have in a connection. The
+     * choice of the connection parameters is eventually up to the central.
+     *
+     * @param[in] params
+     *               The structure containing the desired parameters.
+     */
+    virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)params;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Update connection parameters.
+     * In the central role this will initiate a Link Layer connection parameter update procedure.
+     * In the peripheral role, this will send the corresponding L2CAP request and wait for
+     * the central to perform the procedure.
+     *
+     * @param[in] handle
+     *              Connection Handle.
+     * @param[in] params
+     *              Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+     *              the parameters in the PPCP characteristic of the GAP service will be used instead.
+     */
+    virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) {
+        /* avoid compiler warnings about unused variables */
+        (void)handle;
+        (void)params;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Set the device name characteristic in the GAP service.
+     * @param[in] deviceName
+     *              The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
+     */
+    virtual ble_error_t setDeviceName(const uint8_t *deviceName) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)deviceName;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Get the value of the device name characteristic in the GAP service.
+     * @param[out]    deviceName
+     *                  Pointer to an empty buffer where the UTF-8 *non NULL-
+     *                  terminated* string will be placed. Set this
+     *                  value to NULL in order to obtain the deviceName-length
+     *                  from the 'length' parameter.
+     *
+     * @param[in/out] lengthP
+     *                  (on input) Length of the buffer pointed to by deviceName;
+     *                  (on output) the complete device name length (without the
+     *                     null terminator).
+     *
+     * @note If the device name is longer than the size of the supplied buffer,
+     *     length will return the complete device name length, and not the
+     *     number of bytes actually returned in deviceName. The application may
+     *     use this information to retry with a suitable buffer size.
+     */
+    virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) {
+        /* avoid compiler warnings about unused variables */
+        (void)deviceName;
+        (void)lengthP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Set the appearance characteristic in the GAP service.
+     * @param[in] appearance
+     *              The new value for the device-appearance.
+     */
+    virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)appearance;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Get the appearance characteristic in the GAP service.
+     * @param[out] appearance
+     *               The new value for the device-appearance.
+     */
+    virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)appearanceP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Set the radio's transmit power.
+     * @param[in] txPower Radio transmit power in dBm.
+     */
+    virtual ble_error_t setTxPower(int8_t txPower) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)txPower;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Query the underlying stack for permitted arguments for setTxPower().
+     *
+     * @param[out] valueArrayPP
+     *                 Out parameter to receive the immutable array of Tx values.
+     * @param[out] countP
+     *                 Out parameter to receive the array's size.
+     */
+    virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)valueArrayPP;
+        (void)countP;
+
+        *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * @return Maximum size of the whitelist.
+     *
+     * @experimental
+     */
+    virtual uint8_t getMaxWhitelistSize(void) const
+    {
+        return 0;
+    }
+
+    /**
+     * Get the internal whitelist to be used by the Link Layer when scanning,
+     * advertising or initiating a connection depending on the filter policies.
+     *
+     * @param[in/out]   whitelist
+     *                  (on input) whitelist.capacity contains the maximum number
+     *                  of addresses to be returned.
+     *                  (on output) The populated whitelist with copies of the
+     *                  addresses in the implementation's whitelist.
+     *
+     * @return BLE_ERROR_NONE if the implementation's whitelist was successfully
+     *         copied into the supplied reference.
+     *
+     * @experimental
+     */
+    virtual ble_error_t getWhitelist(Whitelist_t &whitelist) const
+    {
+        (void) whitelist;
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Set the internal whitelist to be used by the Link Layer when scanning,
+     * advertising or initiating a connection depending on the filter policies.
+     *
+     * @param[in]     whitelist
+     *                  A reference to a whitelist containing the addresses to
+     *                  be added to the internal whitelist.
+     *
+     * @return BLE_ERROR_NONE if the implementation's whitelist was successfully
+     *         populated with the addresses in the given whitelist.
+     *
+     * @note The whitelist must not contain addresses of type @ref
+     *       BLEProtocol::AddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE, this
+     *       this will result in a @ref BLE_ERROR_INVALID_PARAM since the
+     *       remote peer might change its private address at any time and it
+     *       is not possible to resolve it.
+     * @note If the input whitelist is larger than @ref getMaxWhitelistSize()
+     *       the @ref BLE_ERROR_PARAM_OUT_OF_RANGE is returned.
+     *
+     * @experimental
+     */
+    virtual ble_error_t setWhitelist(const Whitelist_t &whitelist)
+    {
+        (void) whitelist;
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Set the advertising policy filter mode to be used in the next call
+     * to startAdvertising().
+     *
+     * @param[in] mode
+     *              The new advertising policy filter mode.
+     *
+     * @return BLE_ERROR_NONE if the specified policy filter mode was set
+     *         successfully.
+     *
+     * @experimental
+     */
+    virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode)
+    {
+        (void) mode;
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Set the scan policy filter mode to be used in the next call
+     * to startScan().
+     *
+     * @param[in] mode
+     *              The new scan policy filter mode.
+     *
+     * @return BLE_ERROR_NONE if the specified policy filter mode was set
+     *         successfully.
+     *
+     * @experimental
+     */
+    virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode)
+    {
+        (void) mode;
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Set the initiator policy filter mode to be used.
+     *
+     * @param[in] mode
+     *              The new initiator policy filter mode.
+     *
+     * @return BLE_ERROR_NONE if the specified policy filter mode was set
+     *         successfully.
+     *
+     * @experimental
+     */
+    virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode)
+    {
+        (void) mode;
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Get the advertising policy filter mode that will be used in the next
+     * call to startAdvertising().
+     *
+     * @return The set advertising policy filter mode.
+     *
+     * @experimental
+     */
+    virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const
+    {
+        return ADV_POLICY_IGNORE_WHITELIST;
+    }
+
+    /**
+     * Get the scan policy filter mode that will be used in the next
+     * call to startScan().
+     *
+     * @return The set scan policy filter mode.
+     *
+     * @experimental
+     */
+    virtual ScanningPolicyMode_t getScanningPolicyMode(void) const
+    {
+        return SCAN_POLICY_IGNORE_WHITELIST;
+    }
+
+    /**
+     * Get the initiator policy filter mode that will be used.
+     *
+     * @return The set scan policy filter mode.
+     *
+     * @experimental
+     */
+    virtual InitiatorPolicyMode_t getInitiatorPolicyMode(void) const
+    {
+        return INIT_POLICY_IGNORE_WHITELIST;
+    }
+
+
+protected:
+    /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */
+    virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
+        (void)scanningParams;
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /*
+     * APIs with non-virtual implementations.
+     */
+public:
+    /**
+     * Returns the current GAP state of the device using a bitmask that
+     * describes whether the device is advertising or connected.
+     */
+    GapState_t getState(void) const {
+        return state;
+    }
+
+    /**
+     * Set the GAP advertising mode to use for this device.
+     */
+    void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) {
+        _advParams.setAdvertisingType(advType);
+    }
+
+    /**
+     * @param[in] interval
+     *              Advertising interval in units of milliseconds. Advertising
+     *              is disabled if interval is 0. If interval is smaller than
+     *              the minimum supported value, then the minimum supported
+     *              value is used instead. This minimum value can be discovered
+     *              using getMinAdvertisingInterval().
+     *
+     *              This field must be set to 0 if connectionMode is equal
+     *              to ADV_CONNECTABLE_DIRECTED.
+     *
+     * @note: Decreasing this value will allow central devices to detect a
+     * peripheral faster, at the expense of more power being used by the radio
+     * due to the higher data transmit rate.
+     *
+     * @Note: [WARNING] This API previously used 0.625ms as the unit for its
+     * 'interval' argument. That required an explicit conversion from
+     * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is
+     * no longer required as the new units are milliseconds. Any application
+     * code depending on the old semantics needs to be updated accordingly.
+     */
+    void setAdvertisingInterval(uint16_t interval) {
+        if (interval == 0) {
+            stopAdvertising();
+        } else if (interval < getMinAdvertisingInterval()) {
+            interval = getMinAdvertisingInterval();
+        }
+        _advParams.setInterval(interval);
+    }
+
+    /**
+     * @param[in] timeout
+     *              Advertising timeout (in seconds) between 0x1 and 0x3FFF (1
+     *              and 16383). Use 0 to disable the advertising timeout.
+     */
+    void setAdvertisingTimeout(uint16_t timeout) {
+        _advParams.setTimeout(timeout);
+    }
+
+    /**
+     * Start advertising.
+     */
+    ble_error_t startAdvertising(void) {
+        setAdvertisingData(); /* Update the underlying stack. */
+        return startAdvertising(_advParams);
+    }
+
+    /**
+     * Reset any advertising payload prepared from prior calls to
+     * accumulateAdvertisingPayload(). This automatically propagates the re-
+     * initialized advertising payload to the underlying stack.
+     */
+    void clearAdvertisingPayload(void) {
+        _advPayload.clear();
+        setAdvertisingData();
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param[in] flags
+     *              The flags to be added. Please refer to
+     *              GapAdvertisingData::Flags for valid flags. Multiple
+     *              flags may be specified in combination.
+     */
+    ble_error_t accumulateAdvertisingPayload(uint8_t flags) {
+        ble_error_t rc;
+        if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param  app
+     *         The appearance of the peripheral.
+     */
+    ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
+        setAppearance(app);
+
+        ble_error_t rc;
+        if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Accumulate an AD structure in the advertising payload. Please note that
+     * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
+     * as an additional 31 bytes if the advertising payload is too
+     * small.
+     *
+     * @param  power
+     *         The max transmit power to be used by the controller (in dBm).
+     */
+    ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) {
+        ble_error_t rc;
+        if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Accumulate a variable length byte-stream as an AD structure in the
+     * advertising payload. Please note that the payload is limited to 31 bytes.
+     * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
+     * advertising payload is too small.
+     *
+     * @param  type The type describing the variable length data.
+     * @param  data Data bytes.
+     * @param  len  Length of data.
+     *
+     * @return BLE_ERROR_NONE if the advertisement payload was updated based on
+     *         matching AD type; otherwise, an appropriate error.
+     *
+     * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
+     *       supplied value is appended to the values previously added to the
+     *       payload.
+     */
+    ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
+        if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
+            setDeviceName(data);
+        }
+
+        ble_error_t rc;
+        if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Update a particular ADV field in the advertising payload (based on
+     * matching type).
+     *
+     * @param[in] type  The ADV type field describing the variable length data.
+     * @param[in] data  Data bytes.
+     * @param[in] len   Length of data.
+     *
+     * @note: If advertisements are enabled, then the update will take effect immediately.
+     *
+     * @return BLE_ERROR_NONE if the advertisement payload was updated based on
+     *         matching AD type; otherwise, an appropriate error.
+     */
+    ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
+        if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
+            setDeviceName(data);
+        }
+
+        ble_error_t rc;
+        if ((rc = _advPayload.updateData(type, data, len)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Set up a particular, user-constructed advertisement payload for the
+     * underlying stack. It would be uncommon for this API to be used directly;
+     * there are other APIs to build an advertisement payload (see above).
+     */
+    ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) {
+        _advPayload = payload;
+        return setAdvertisingData();
+    }
+
+    /**
+     * @return  Read back advertising data. Useful for storing and
+     *          restoring payload.
+     */
+    const GapAdvertisingData &getAdvertisingPayload(void) const {
+        return _advPayload;
+    }
+
+    /**
+     * Accumulate a variable length byte-stream as an AD structure in the
+     * scanResponse payload.
+     *
+     * @param[in] type The type describing the variable length data.
+     * @param[in] data Data bytes.
+     * @param[in] len  Length of data.
+     */
+    ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
+        ble_error_t rc;
+        if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        return setAdvertisingData();
+    }
+
+    /**
+     * Reset any scan response prepared from prior calls to
+     * accumulateScanResponse().
+     *
+     * Note: This should be followed by a call to setAdvertisingPayload() or
+     * startAdvertising() before the update takes effect.
+     */
+    void clearScanResponse(void) {
+        _scanResponse.clear();
+        setAdvertisingData();
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] interval
+     *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     * @param[in] window
+     *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     * @param[in] timeout
+     *              Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout.
+     * @param[in] activeScanning
+     *              Set to True if active-scanning is required. This is used to fetch the
+     *              scan response from a peer if possible.
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * @Note: The scan interval and window are recommendations to the BLE stack.
+     */
+    ble_error_t setScanParams(uint16_t interval       = GapScanningParams::SCAN_INTERVAL_MAX,
+                              uint16_t window         = GapScanningParams::SCAN_WINDOW_MAX,
+                              uint16_t timeout        = 0,
+                              bool     activeScanning = false) {
+        ble_error_t rc;
+        if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
+            ((rc = _scanningParams.setWindow(window))     == BLE_ERROR_NONE) &&
+            ((rc = _scanningParams.setTimeout(timeout))   == BLE_ERROR_NONE)) {
+            _scanningParams.setActiveScanning(activeScanning);
+            return BLE_ERROR_NONE;
+        }
+
+        return rc;
+    }
+
+    /**
+     * Set up the scanInterval parameter for GAP scanning (observer mode).
+     * @param[in] interval
+     *              Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     */
+    ble_error_t setScanInterval(uint16_t interval) {
+        return _scanningParams.setInterval(interval);
+    }
+
+    /**
+     * Set up the scanWindow parameter for GAP scanning (observer mode).
+     * @param[in] window
+     *              Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s].
+     *
+     * The scanning window divided by the interval determines the duty cycle for
+     * scanning. For example, if the interval is 100ms and the window is 10ms,
+     * then the controller will scan for 10 percent of the time. It is possible
+     * to have the interval and window set to the same value. In this case,
+     * scanning is continuous, with a change of scanning frequency once every
+     * interval.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * If scanning is already active, the updated value of scanWindow will be
+     * propagated to the underlying BLE stack.
+     */
+    ble_error_t setScanWindow(uint16_t window) {
+        ble_error_t rc;
+        if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        /* If scanning is already active, propagate the new setting to the stack. */
+        if (scanningActive) {
+            return startRadioScan(_scanningParams);
+        }
+
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] timeout
+     *              Scan timeout (in seconds) between 0x0001 and 0xFFFF; 0x0000 disables the timeout.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * If scanning is already active, the updated value of scanTimeout will be
+     * propagated to the underlying BLE stack.
+     */
+    ble_error_t setScanTimeout(uint16_t timeout) {
+        ble_error_t rc;
+        if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) {
+            return rc;
+        }
+
+        /* If scanning is already active, propagate the new settings to the stack. */
+        if (scanningActive) {
+            return startRadioScan(_scanningParams);
+        }
+
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * Set up parameters for GAP scanning (observer mode).
+     * @param[in] activeScanning
+     *              Set to True if active-scanning is required. This is used to fetch the
+     *              scan response from a peer if possible.
+     *
+     * Once the scanning parameters have been configured, scanning can be
+     * enabled by using startScan().
+     *
+     * If scanning is already in progress, then active-scanning will be enabled
+     * for the underlying BLE stack.
+     */
+    ble_error_t setActiveScanning(bool activeScanning) {
+        _scanningParams.setActiveScanning(activeScanning);
+
+        /* If scanning is already active, propagate the new settings to the stack. */
+        if (scanningActive) {
+            return startRadioScan(_scanningParams);
+        }
+
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * Start scanning (Observer Procedure) based on the parameters currently in
+     * effect.
+     *
+     * @param[in] callback
+     *              The application-specific callback to be invoked upon
+     *              receiving every advertisement report. This can be passed in
+     *              as NULL, in which case scanning may not be enabled at all.
+     */
+    ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) {
+        ble_error_t err = BLE_ERROR_NONE;
+        if (callback) {
+            if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
+                scanningActive = true;
+                onAdvertisementReport.attach(callback);
+            }
+        }
+
+        return err;
+    }
+
+    /**
+     * Same as above, but this takes an (object, method) pair for a callback.
+     */
+    template<typename T>
+    ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) {
+        ble_error_t err = BLE_ERROR_NONE;
+        if (object && callbackMember) {
+            if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
+                scanningActive = true;
+                onAdvertisementReport.attach(object, callbackMember);
+            }
+        }
+
+        return err;
+    }
+
+    /**
+     * Initialize radio-notification events to be generated from the stack.
+     * This API doesn't need to be called directly.
+     *
+     * Radio Notification is a feature that enables ACTIVE and INACTIVE
+     * (nACTIVE) signals from the stack that notify the application when the
+     * radio is in use.
+     *
+     * The ACTIVE signal is sent before the radio event starts. The nACTIVE
+     * signal is sent at the end of the radio event. These signals can be used
+     * by the application programmer to synchronize application logic with radio
+     * activity. For example, the ACTIVE signal can be used to shut off external
+     * devices, to manage peak current drawn during periods when the radio is on,
+     * or to trigger sensor data collection for transmission in the Radio Event.
+     *
+     * @return BLE_ERROR_NONE on successful initialization, otherwise an error code.
+     */
+    virtual ble_error_t initRadioNotification(void) {
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+private:
+    ble_error_t setAdvertisingData(void) {
+        return setAdvertisingData(_advPayload, _scanResponse);
+    }
+
+private:
+    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) = 0;
+    virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0;
+
+public:
+    /**
+     * Accessors to read back currently active advertising params.
+     */
+    GapAdvertisingParams &getAdvertisingParams(void) {
+        return _advParams;
+    }
+    const GapAdvertisingParams &getAdvertisingParams(void) const {
+        return _advParams;
+    }
+
+    /**
+     * Set up a particular, user-constructed set of advertisement parameters for
+     * the underlying stack. It would be uncommon for this API to be used
+     * directly; there are other APIs to tweak advertisement parameters
+     * individually.
+     */
+    void setAdvertisingParams(const GapAdvertisingParams &newParams) {
+        _advParams = newParams;
+    }
+
+    /* Event callback handlers. */
+public:
+    /**
+     * Set up a callback for timeout events. Refer to TimeoutSource_t for
+     * possible event types.
+     * @note It is possible to unregister callbacks using onTimeout().detach(callback)
+     */
+    void onTimeout(TimeoutEventCallback_t callback) {
+        timeoutCallbackChain.add(callback);
+    }
+
+    /**
+     * @brief provide access to the callchain of timeout event callbacks
+     * It is possible to register callbacks using onTimeout().add(callback);
+     * It is possible to unregister callbacks using onTimeout().detach(callback)
+     * @return The timeout event callbacks chain
+     */
+    TimeoutEventCallbackChain_t& onTimeout() {
+        return timeoutCallbackChain;
+    }
+
+    /**
+     * Append to a chain of callbacks to be invoked upon GAP connection.
+     * @note It is possible to unregister callbacks using onConnection().detach(callback)
+     */
+    void onConnection(ConnectionEventCallback_t callback) {connectionCallChain.add(callback);}
+
+    template<typename T>
+    void onConnection(T *tptr, void (T::*mptr)(const ConnectionCallbackParams_t*)) {connectionCallChain.add(tptr, mptr);}
+
+    /**
+     * @brief provide access to the callchain of connection event callbacks
+     * It is possible to register callbacks using onConnection().add(callback);
+     * It is possible to unregister callbacks using onConnection().detach(callback)
+     * @return The connection event callbacks chain
+     */
+    ConnectionEventCallbackChain_t& onConnection() {
+        return connectionCallChain;
+    }
+
+    /**
+     * Append to a chain of callbacks to be invoked upon GAP disconnection.
+     * @note It is possible to unregister callbacks using onDisconnection().detach(callback)
+     */
+    void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallChain.add(callback);}
+
+    template<typename T>
+    void onDisconnection(T *tptr, void (T::*mptr)(const DisconnectionCallbackParams_t*)) {disconnectionCallChain.add(tptr, mptr);}
+
+    /**
+     * @brief provide access to the callchain of disconnection event callbacks
+     * It is possible to register callbacks using onDisconnection().add(callback);
+     * It is possible to unregister callbacks using onDisconnection().detach(callback)
+     * @return The disconnection event callbacks chain
+     */
+    DisconnectionEventCallbackChain_t& onDisconnection() {
+        return disconnectionCallChain;
+    }
+
+    /**
+     * Set the application callback for radio-notification events.
+     *
+     * Radio Notification is a feature that enables ACTIVE and INACTIVE
+     * (nACTIVE) signals from the stack that notify the application when the
+     * radio is in use.
+     *
+     * The ACTIVE signal is sent before the radio event starts. The nACTIVE
+     * signal is sent at the end of the radio event. These signals can be used
+     * by the application programmer to synchronize application logic with radio
+     * activity. For example, the ACTIVE signal can be used to shut off external
+     * devices, to manage peak current drawn during periods when the radio is on,
+     * or to trigger sensor data collection for transmission in the Radio Event.
+     *
+     * @param callback
+     *          The application handler to be invoked in response to a radio
+     *          ACTIVE/INACTIVE event.
+     *
+     * Or in the other version:
+     *
+     * @param tptr
+     *          Pointer to the object of a class defining the member callback
+     *          function (mptr).
+     * @param mptr
+     *          The member callback (within the context of an object) to be
+     *          invoked in response to a radio ACTIVE/INACTIVE event.
+     */
+    void onRadioNotification(void (*callback)(bool param)) {
+        radioNotificationCallback.attach(callback);
+    }
+    template <typename T>
+    void onRadioNotification(T *tptr, void (T::*mptr)(bool)) {
+        radioNotificationCallback.attach(tptr, mptr);
+    }
+
+    /**
+     * Setup a callback to be invoked to notify the user application that the
+     * Gap instance is about to shutdown (possibly as a result of a call
+     * to BLE::shutdown()).
+     *
+     * @Note: It is possible to chain together multiple onShutdown callbacks
+     * (potentially from different modules of an application) to be notified
+     * before the Gap instance is shutdown.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onShutdown().detach(callback)
+     */
+    void onShutdown(const GapShutdownCallback_t& callback) {
+        shutdownCallChain.add(callback);
+    }
+    template <typename T>
+    void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
+        shutdownCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of shutdown event callbacks
+     * It is possible to register callbacks using onShutdown().add(callback);
+     * It is possible to unregister callbacks using onShutdown().detach(callback)
+     * @return The shutdown event callbacks chain
+     */
+    GapShutdownCallbackChain_t& onShutdown() {
+        return shutdownCallChain;
+    }
+
+public:
+    /**
+     * Notify all registered onShutdown callbacks that the Gap instance is
+     * about to be shutdown and clear all Gap state of the
+     * associated object.
+     *
+     * This function is meant to be overridden in the platform-specific
+     * sub-class. Nevertheless, the sub-class is only expected to reset its
+     * state and not the data held in Gap members. This shall be achieved by a
+     * call to Gap::reset() from the sub-class' reset() implementation.
+     *
+     * @return BLE_ERROR_NONE on success.
+     *
+     * @note: Currently a call to reset() does not reset the advertising and
+     * scan parameters to default values.
+     */
+    virtual ble_error_t reset(void) {
+        /* Notify that the instance is about to shutdown */
+        shutdownCallChain.call(this);
+        shutdownCallChain.clear();
+
+        /* Clear Gap state */
+        state.advertising = 0;
+        state.connected   = 0;
+
+        /* Clear scanning state */
+        scanningActive = false;
+
+        /* Clear advertising and scanning data */
+        _advPayload.clear();
+        _scanResponse.clear();
+
+        /* Clear callbacks */
+        timeoutCallbackChain.clear();
+        connectionCallChain.clear();
+        disconnectionCallChain.clear();
+        radioNotificationCallback = NULL;
+        onAdvertisementReport     = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+protected:
+    Gap() :
+        _advParams(),
+        _advPayload(),
+        _scanningParams(),
+        _scanResponse(),
+        state(),
+        scanningActive(false),
+        timeoutCallbackChain(),
+        radioNotificationCallback(),
+        onAdvertisementReport(),
+        connectionCallChain(),
+        disconnectionCallChain() {
+        _advPayload.clear();
+        _scanResponse.clear();
+    }
+
+    /* Entry points for the underlying stack to report events back to the user. */
+public:
+    void processConnectionEvent(Handle_t                           handle,
+                                Role_t                             role,
+                                BLEProtocol::AddressType_t         peerAddrType,
+                                const BLEProtocol::AddressBytes_t  peerAddr,
+                                BLEProtocol::AddressType_t         ownAddrType,
+                                const BLEProtocol::AddressBytes_t  ownAddr,
+                                const ConnectionParams_t          *connectionParams) {
+        state.connected = 1;
+        ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams);
+        connectionCallChain.call(&callbackParams);
+    }
+
+    void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) {
+        state.connected = 0;
+        DisconnectionCallbackParams_t callbackParams(handle, reason);
+        disconnectionCallChain.call(&callbackParams);
+    }
+
+    void processAdvertisementReport(const BLEProtocol::AddressBytes_t        peerAddr,
+                                    int8_t                                   rssi,
+                                    bool                                     isScanResponse,
+                                    GapAdvertisingParams::AdvertisingType_t  type,
+                                    uint8_t                                  advertisingDataLen,
+                                    const uint8_t                           *advertisingData) {
+        AdvertisementCallbackParams_t params;
+        memcpy(params.peerAddr, peerAddr, ADDR_LEN);
+        params.rssi               = rssi;
+        params.isScanResponse     = isScanResponse;
+        params.type               = type;
+        params.advertisingDataLen = advertisingDataLen;
+        params.advertisingData    = advertisingData;
+        onAdvertisementReport.call(&params);
+    }
+
+    void processTimeoutEvent(TimeoutSource_t source) {
+        if (timeoutCallbackChain) {
+            timeoutCallbackChain(source);
+        }
+    }
+
+protected:
+    GapAdvertisingParams             _advParams;
+    GapAdvertisingData               _advPayload;
+    GapScanningParams                _scanningParams;
+    GapAdvertisingData               _scanResponse;
+
+    GapState_t                       state;
+    bool                             scanningActive;
+
+protected:
+    TimeoutEventCallbackChain_t       timeoutCallbackChain;
+    RadioNotificationEventCallback_t  radioNotificationCallback;
+    AdvertisementReportCallback_t     onAdvertisementReport;
+    ConnectionEventCallbackChain_t    connectionCallChain;
+    DisconnectionEventCallbackChain_t disconnectionCallChain;
+
+private:
+    GapShutdownCallbackChain_t shutdownCallChain;
+
+private:
+    /* Disallow copy and assignment. */
+    Gap(const Gap &);
+    Gap& operator=(const Gap &);
+};
+
+#endif // ifndef __GAP_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GapAdvertisingData.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,498 @@
+/* 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 __GAP_ADVERTISING_DATA_H__
+#define __GAP_ADVERTISING_DATA_H__
+
+#include <stdint.h>
+#include <string.h>
+
+#include "blecommon.h"
+
+#define GAP_ADVERTISING_DATA_MAX_PAYLOAD        (31)
+
+/**************************************************************************/
+/*!
+    \brief
+    This class provides several helper functions to generate properly
+    formatted GAP Advertising and Scan Response data payloads.
+
+    \note
+    See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18
+    for further information on Advertising and Scan Response data.
+
+    \par Advertising and Scan Response Payloads
+    Advertising data and Scan Response data are organized around a set of
+    data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core
+    Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
+
+    \par
+    Each AD type has its own standardized assigned number, as defined
+    by the Bluetooth SIG:
+    https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
+
+    \par
+    For convenience, all appropriate AD types are encapsulated
+    in GapAdvertisingData::DataType.
+
+    \par
+    Before the AD Types and their payload (if any) can be inserted into
+    the Advertising or Scan Response frames, they need to be formatted as
+    follows:
+
+    \li \c Record length (1 byte).
+    \li \c AD Type (1 byte).
+    \li \c AD payload (optional; only present if record length > 1).
+
+    \par
+    This class takes care of properly formatting the payload, performs
+    some basic checks on the payload length, and tries to avoid common
+    errors like adding an exclusive AD field twice in the Advertising
+    or Scan Response payload.
+
+    \par EXAMPLE
+
+    \code
+
+    // ToDo
+
+    \endcode
+*/
+/**************************************************************************/
+class GapAdvertisingData
+{
+public:
+    /**********************************************************************/
+    /*!
+        \brief
+        A list of Advertising Data types commonly used by peripherals.
+        These AD types are used to describe the capabilities of the
+        peripheral, and are inserted inside the advertising or scan
+        response payloads.
+
+        \par Source
+        \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
+        \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
+    */
+    /**********************************************************************/
+    enum DataType_t {
+        FLAGS                              = 0x01, /**< \ref *Flags */
+        INCOMPLETE_LIST_16BIT_SERVICE_IDS  = 0x02, /**< Incomplete list of 16-bit Service IDs */
+        COMPLETE_LIST_16BIT_SERVICE_IDS    = 0x03, /**< Complete list of 16-bit Service IDs */
+        INCOMPLETE_LIST_32BIT_SERVICE_IDS  = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
+        COMPLETE_LIST_32BIT_SERVICE_IDS    = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
+        INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */
+        COMPLETE_LIST_128BIT_SERVICE_IDS   = 0x07, /**< Complete list of 128-bit Service IDs */
+        SHORTENED_LOCAL_NAME               = 0x08, /**< Shortened Local Name */
+        COMPLETE_LOCAL_NAME                = 0x09, /**< Complete Local Name */
+        TX_POWER_LEVEL                     = 0x0A, /**< TX Power Level (in dBm) */
+        DEVICE_ID                          = 0x10, /**< Device ID */
+        SLAVE_CONNECTION_INTERVAL_RANGE    = 0x12, /**< Slave Connection Interval Range */
+        LIST_128BIT_SOLICITATION_IDS       = 0x15, /**< List of 128 bit service UUIDs the device is looking for */
+        SERVICE_DATA                       = 0x16, /**< Service Data */
+        APPEARANCE                         = 0x19, /**< \ref Appearance */
+        ADVERTISING_INTERVAL               = 0x1A, /**< Advertising Interval */
+        MANUFACTURER_SPECIFIC_DATA         = 0xFF  /**< Manufacturer Specific Data */
+    };
+    typedef enum DataType_t DataType; /* Deprecated type alias. This may be dropped in a future release. */
+
+    /**********************************************************************/
+    /*!
+        \brief
+        A list of values for the FLAGS AD Type.
+
+        \note
+        You can use more than one value in the FLAGS AD Type (ex.
+        LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED).
+
+        \par Source
+        \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1
+    */
+    /**********************************************************************/
+    enum Flags_t {
+        LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time. */
+        LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment. */
+        BREDR_NOT_SUPPORTED     = 0x04, /**< Peripheral device is LE only. */
+        SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only. */
+        SIMULTANEOUS_LE_BREDR_H = 0x10  /**< Not relevant - central mode only. */
+    };
+    typedef enum Flags_t Flags; /* Deprecated type alias. This may be dropped in a future release. */
+
+    /**********************************************************************/
+    /*!
+        \brief
+        A list of values for the APPEARANCE AD Type, which describes the
+        physical shape or appearance of the device.
+
+        \par Source
+        \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12
+        \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2
+        \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+    */
+    /**********************************************************************/
+    enum Appearance_t {
+        UNKNOWN                                        = 0,     /**< Unknown or unspecified appearance type. */
+        GENERIC_PHONE                                  = 64,    /**< Generic Phone. */
+        GENERIC_COMPUTER                               = 128,   /**< Generic Computer. */
+        GENERIC_WATCH                                  = 192,   /**< Generic Watch. */
+        WATCH_SPORTS_WATCH                             = 193,   /**< Sports Watch. */
+        GENERIC_CLOCK                                  = 256,   /**< Generic Clock. */
+        GENERIC_DISPLAY                                = 320,   /**< Generic Display. */
+        GENERIC_REMOTE_CONTROL                         = 384,   /**< Generic Remote Control. */
+        GENERIC_EYE_GLASSES                            = 448,   /**< Generic Eye Glasses. */
+        GENERIC_TAG                                    = 512,   /**< Generic Tag. */
+        GENERIC_KEYRING                                = 576,   /**< Generic Keyring. */
+        GENERIC_MEDIA_PLAYER                           = 640,   /**< Generic Media Player. */
+        GENERIC_BARCODE_SCANNER                        = 704,   /**< Generic Barcode Scanner. */
+        GENERIC_THERMOMETER                            = 768,   /**< Generic Thermometer. */
+        THERMOMETER_EAR                                = 769,   /**< Ear Thermometer. */
+        GENERIC_HEART_RATE_SENSOR                      = 832,   /**< Generic Heart Rate Sensor. */
+        HEART_RATE_SENSOR_HEART_RATE_BELT              = 833,   /**< Belt Heart Rate Sensor. */
+        GENERIC_BLOOD_PRESSURE                         = 896,   /**< Generic Blood Pressure. */
+        BLOOD_PRESSURE_ARM                             = 897,   /**< Arm Blood Pressure. */
+        BLOOD_PRESSURE_WRIST                           = 898,   /**< Wrist Blood Pressure. */
+        HUMAN_INTERFACE_DEVICE_HID                     = 960,   /**< Human Interface Device (HID). */
+        KEYBOARD                                       = 961,   /**< Keyboard. */
+        MOUSE                                          = 962,   /**< Mouse. */
+        JOYSTICK                                       = 963,   /**< Joystick. */
+        GAMEPAD                                        = 964,   /**< Gamepad. */
+        DIGITIZER_TABLET                               = 965,   /**< Digitizer Tablet. */
+        CARD_READER                                    = 966,   /**< Card Reader. */
+        DIGITAL_PEN                                    = 967,   /**< Digital Pen. */
+        BARCODE_SCANNER                                = 968,   /**< Barcode Scanner. */
+        GENERIC_GLUCOSE_METER                          = 1024,  /**< Generic Glucose Meter. */
+        GENERIC_RUNNING_WALKING_SENSOR                 = 1088,  /**< Generic Running/Walking Sensor. */
+        RUNNING_WALKING_SENSOR_IN_SHOE                 = 1089,  /**< In Shoe Running/Walking Sensor. */
+        RUNNING_WALKING_SENSOR_ON_SHOE                 = 1090,  /**< On Shoe Running/Walking Sensor. */
+        RUNNING_WALKING_SENSOR_ON_HIP                  = 1091,  /**< On Hip Running/Walking Sensor. */
+        GENERIC_CYCLING                                = 1152,  /**< Generic Cycling. */
+        CYCLING_CYCLING_COMPUTER                       = 1153,  /**< Cycling Computer. */
+        CYCLING_SPEED_SENSOR                           = 1154,  /**< Cycling Speed Sensor. */
+        CYCLING_CADENCE_SENSOR                         = 1155,  /**< Cycling Cadence Sensor. */
+        CYCLING_POWER_SENSOR                           = 1156,  /**< Cycling Power Sensor. */
+        CYCLING_SPEED_AND_CADENCE_SENSOR               = 1157,  /**< Cycling Speed and Cadence Sensor. */
+        PULSE_OXIMETER_GENERIC                         = 3136,  /**< Generic Pulse Oximeter. */
+        PULSE_OXIMETER_FINGERTIP                       = 3137,  /**< Fingertip Pulse Oximeter. */
+        PULSE_OXIMETER_WRIST_WORN                      = 3138,  /**< Wrist Worn Pulse Oximeter. */
+        GENERIC_WEIGHT_SCALE                           = 3200,  /**< Generic Weight Scale. */
+        OUTDOOR_GENERIC                                = 5184,  /**< Generic Outdoor. */
+        OUTDOOR_LOCATION_DISPLAY_DEVICE                = 5185,  /**< Outdoor Location Display Device. */
+        OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186,  /**< Outdoor Location and Navigation Display Device. */
+        OUTDOOR_LOCATION_POD                           = 5187,  /**< Outdoor Location Pod. */
+        OUTDOOR_LOCATION_AND_NAVIGATION_POD            = 5188   /**< Outdoor Location and Navigation Pod. */
+    };
+    typedef enum Appearance_t Appearance; /* Deprecated type alias. This may be dropped in a future release. */
+
+    GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) {
+        /* empty */
+    }
+
+    /**
+     * Adds advertising data based on the specified AD type (see DataType).
+     * If the supplied AD type is already present in the advertising
+     * payload, then the value is updated.
+     *
+     * @param[in] advDataType  The Advertising 'DataType' to add.
+     * @param[in] payload      Pointer to the payload contents.
+     * @param[in] len          Size of the payload in bytes.
+     *
+     * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
+     *         advertising buffer to overflow. BLE_ERROR_NONE is returned
+     *         on success.
+     *
+     * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
+     *       COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
+     *       supplied value is appended to the values previously added to the
+     *       payload.
+     */
+    ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
+    {
+        // find field
+        uint8_t* field = findField(advDataType);
+
+        if (field) {
+            // Field type already exist, either add to field or replace
+            return addField(advDataType, payload, len, field);
+        } else {
+            // field doesn't exists, insert new
+            return appendField(advDataType, payload, len);
+        }
+    }
+
+    /**
+     * Update a particular ADV field in the advertising payload (based on
+     * matching type).
+     *
+     * @param[in] advDataType  The Advertising 'DataType' to add.
+     * @param[in] payload      Pointer to the payload contents.
+     * @param[in] len          Size of the payload in bytes.
+     *
+     * @return BLE_ERROR_UNSPECIFIED if the specified field is not found,
+     *         BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
+     *         advertising buffer to overflow. BLE_ERROR_NONE is returned
+     *         on success.
+     */
+    ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
+    {
+        // find field
+        uint8_t* field = findField(advDataType);
+
+        if (field) {
+            // Field type already exist, replace field contents
+            return updateField(advDataType, payload, len, field);
+        } else {
+            // field doesn't exists, return an error
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    /**
+     * Helper function to add APPEARANCE data to the advertising payload.
+     *
+     * @param  appearance
+     *           The APPEARANCE value to add.
+     *
+     * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
+     * advertising buffer to overflow, else BLE_ERROR_NONE.
+     */
+    ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) {
+        _appearance = appearance;
+        return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2);
+    }
+
+    /**
+     * Helper function to add FLAGS data to the advertising payload.
+     * @param  flags
+     *           LE_LIMITED_DISCOVERABLE
+     *             The peripheral is discoverable for a limited period of time.
+     *           LE_GENERAL_DISCOVERABLE
+     *             The peripheral is permanently discoverable.
+     *           BREDR_NOT_SUPPORTED
+     *             This peripheral is a Bluetooth Low Energy only device (no EDR support).
+     *
+     * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
+     * advertising buffer to overflow, else BLE_ERROR_NONE.
+     */
+    ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) {
+        return addData(GapAdvertisingData::FLAGS, &flags, 1);
+    }
+
+    /**
+     * Helper function to add TX_POWER_LEVEL data to the advertising payload.
+     *
+     * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
+     * advertising buffer to overflow, else BLE_ERROR_NONE.
+     */
+    ble_error_t addTxPower(int8_t txPower) {
+        /* To Do: Basic error checking to make sure txPower is in range. */
+        return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1);
+    }
+
+    /**
+     * Clears the payload and resets the payload length counter.
+     */
+    void        clear(void) {
+        memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
+        _payloadLen = 0;
+    }
+
+    /**
+     * Returns a pointer to the current payload.
+     */
+    const uint8_t *getPayload(void) const {
+        return _payload;
+    }
+
+    /**
+     * Returns the current payload length (0..31 bytes).
+     */
+    uint8_t     getPayloadLen(void) const {
+        return _payloadLen;
+    }
+
+    /**
+     * Returns the 16-bit appearance value for this device.
+     */
+    uint16_t    getAppearance(void) const {
+        return (uint16_t)_appearance;
+    }
+
+    /**
+     * Search advertisement data for field.
+     * Returns pointer to the first element in the field if found, NULL otherwise.
+     * Where the first element is the length of the field.
+     */
+    const uint8_t* findField(DataType_t type) const {
+        return findField(type);
+    }
+
+private:
+    /**
+     * Append advertising data based on the specified AD type (see DataType)
+     */
+    ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len)
+    {
+        /* Make sure we don't exceed the 31 byte payload limit */
+        if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+            return BLE_ERROR_BUFFER_OVERFLOW;
+        }
+
+        /* Field length. */
+        memset(&_payload[_payloadLen], len + 1, 1);
+        _payloadLen++;
+
+        /* Field ID. */
+        memset(&_payload[_payloadLen], (uint8_t)advDataType, 1);
+        _payloadLen++;
+
+        /* Payload. */
+        memcpy(&_payload[_payloadLen], payload, len);
+        _payloadLen += len;
+
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * Search advertisement data for field.
+     * Returns pointer to the first element in the field if found, NULL otherwise.
+     * Where the first element is the length of the field.
+     */
+    uint8_t* findField(DataType_t type) {
+        // scan through advertisement data
+        for (uint8_t idx = 0; idx < _payloadLen; ) {
+            uint8_t fieldType = _payload[idx + 1];
+
+            if (fieldType == type) {
+                return &_payload[idx];
+            }
+
+            // advance to next field
+            idx += _payload[idx] + 1;
+        }
+
+        // field not found
+        return NULL;
+    }
+
+    /**
+     * Given the a pointer to a field in the advertising payload it replaces
+     * the existing data in the field with the supplied data.
+     *
+     * When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
+     * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
+     * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
+     * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
+     * supplied value is appended to the values previously added to the
+     * payload.
+     *
+     * Returns BLE_ERROR_NONE on success.
+     */
+    ble_error_t addField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
+    {
+        ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
+
+        switch(advDataType) {
+            // These fields will have the new data appended if there is sufficient space
+            case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
+            case COMPLETE_LIST_16BIT_SERVICE_IDS:
+            case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
+            case COMPLETE_LIST_32BIT_SERVICE_IDS:
+            case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
+            case COMPLETE_LIST_128BIT_SERVICE_IDS:
+            case LIST_128BIT_SOLICITATION_IDS: {
+                // check if data fits
+                if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+                    // make room for new field by moving the remainder of the
+                    // advertisement payload "to the right" starting after the
+                    // TYPE field.
+                    uint8_t* end = &_payload[_payloadLen];
+
+                    while (&field[1] < end) {
+                        end[len] = *end;
+                        end--;
+                    }
+
+                    // insert new data
+                    for (uint8_t idx = 0; idx < len; idx++) {
+                        field[2 + idx] = payload[idx];
+                    }
+
+                    // increment lengths
+                    field[0] += len;
+                    _payloadLen += len;
+
+                    result = BLE_ERROR_NONE;
+                }
+
+                break;
+            }
+            //  These fields will be overwritten with the new value
+            default: {
+                result = updateField(advDataType, payload, len, field);
+
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Given the a pointer to a field in the advertising payload it replaces
+     * the existing data in the field with the supplied data.
+     * Returns BLE_ERROR_NONE on success.
+     */
+    ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
+    {
+        ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
+        uint8_t dataLength = field[0] - 1;
+
+        // new data has same length, do in-order replacement
+        if (len == dataLength) {
+            for (uint8_t idx = 0; idx < dataLength; idx++) {
+                field[2 + idx] = payload[idx];
+            }
+
+            result = BLE_ERROR_NONE;
+        } else {
+            // check if data fits
+            if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+
+                // remove old field
+                while ((field + dataLength + 2) < &_payload[_payloadLen]) {
+                    *field = field[dataLength + 2];
+                    field++;
+                }
+
+                // reduce length
+                _payloadLen -= dataLength + 2;
+
+                // add new field
+                result = appendField(advDataType, payload, len);
+            }
+        }
+
+        return result;
+    }
+
+    uint8_t  _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
+    uint8_t  _payloadLen;
+    uint16_t _appearance;
+};
+
+#endif // ifndef __GAP_ADVERTISING_DATA_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GapAdvertisingParams.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,120 @@
+/* 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 __GAP_ADVERTISING_PARAMS_H__
+#define __GAP_ADVERTISING_PARAMS_H__
+
+/**
+ *  This class provides a wrapper for the core advertising parameters,
+ *  including the advertising type (Connectable Undirected,
+ *  Non Connectable Undirected and so on), as well as the advertising and
+ *  timeout intervals.
+ */
+class GapAdvertisingParams {
+public:
+    static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN        = 0x0020;
+    static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0;
+    static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX        = 0x4000;
+    static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX         = 0x3FFF;
+
+    /*!
+     * Encapsulates the peripheral advertising modes, which determine how
+     * the device appears to other central devices in hearing range.
+     */
+    enum AdvertisingType_t {
+        ADV_CONNECTABLE_UNDIRECTED,     /**< Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1 */
+        ADV_CONNECTABLE_DIRECTED,       /**< Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2 */
+        ADV_SCANNABLE_UNDIRECTED,       /**< Include support for Scan Response payloads, see Vol 6, Part B, Section 2.3.1.4 */
+        ADV_NON_CONNECTABLE_UNDIRECTED  /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3 */
+    };
+    typedef enum AdvertisingType_t AdvertisingType; /* Deprecated type alias. */
+
+public:
+    GapAdvertisingParams(AdvertisingType_t advType  = ADV_CONNECTABLE_UNDIRECTED,
+                         uint16_t          interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON,
+                         uint16_t          timeout  = 0) : _advType(advType), _interval(interval), _timeout(timeout) {
+        /* Interval checks. */
+        if (_advType == ADV_CONNECTABLE_DIRECTED) {
+            /* Interval must be 0 in directed connectable mode. */
+            _interval = 0;
+        } else if (_advType == ADV_NON_CONNECTABLE_UNDIRECTED) {
+            /* Min interval is slightly larger than in other modes. */
+            if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) {
+                _interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON;
+            }
+            if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) {
+                _interval = GAP_ADV_PARAMS_INTERVAL_MAX;
+            }
+        } else {
+            /* Stay within interval limits. */
+            if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN) {
+                _interval = GAP_ADV_PARAMS_INTERVAL_MIN;
+            }
+            if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) {
+                _interval = GAP_ADV_PARAMS_INTERVAL_MAX;
+            }
+        }
+
+        /* Timeout checks. */
+        if (timeout) {
+            /* Stay within timeout limits. */
+            if (_timeout > GAP_ADV_PARAMS_TIMEOUT_MAX) {
+                _timeout = GAP_ADV_PARAMS_TIMEOUT_MAX;
+            }
+        }
+    }
+
+    static const uint16_t UNIT_0_625_MS = 625;  /**< Number of microseconds in 0.625 milliseconds. */
+    static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) {
+        return (durationInMillis * 1000) / UNIT_0_625_MS;
+    }
+    static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) {
+        return (gapUnits * UNIT_0_625_MS) / 1000;
+    }
+
+    AdvertisingType_t getAdvertisingType(void) const {
+        return _advType;
+    }
+
+    /**
+     * @return the advertisement interval (in milliseconds).
+     */
+    uint16_t getInterval(void) const {
+        return ADVERTISEMENT_DURATION_UNITS_TO_MS(_interval);
+    }
+
+    /**
+     * @return the advertisement interval in advertisement duration units (0.625ms units).
+     */
+    uint16_t getIntervalInADVUnits(void) const {
+        return _interval;
+    }
+
+    uint16_t getTimeout(void) const {
+        return _timeout;
+    }
+
+    void setAdvertisingType(AdvertisingType_t newAdvType) {_advType = newAdvType;  }
+    void setInterval(uint16_t newInterval)                {_interval = MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newInterval);}
+    void setTimeout(uint16_t newTimeout)                  {_timeout = newTimeout;  }
+
+private:
+    AdvertisingType_t _advType;
+    uint16_t          _interval; /* In ADV duration units (i.e. 0.625ms). */
+    uint16_t          _timeout;  /* In seconds. */
+};
+
+#endif // ifndef __GAP_ADVERTISING_PARAMS_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GapEvents.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,46 @@
+/* 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 __GAP_EVENTS_H__
+#define __GAP_EVENTS_H__
+
+#include "blecommon.h"
+
+/**************************************************************************/
+/*!
+    \brief
+    The base class used to abstract away the callback events that can be
+    triggered with the GAP.
+*/
+/**************************************************************************/
+class GapEvents
+{
+public:
+    /******************************************************************/
+    /*!
+        \brief
+        Identifies GAP events generated by the radio HW when an event
+        callback occurs.
+    */
+    /******************************************************************/
+    typedef enum gapEvent_e {
+        GAP_EVENT_TIMEOUT      = 1, /**< Advertising timed out before a connection could be established. */
+        GAP_EVENT_CONNECTED    = 2, /**< A connection was established with a central device. */
+        GAP_EVENT_DISCONNECTED = 3  /**< A connection was closed or lost with a central device. */
+    } gapEvent_t;
+};
+
+#endif // ifndef __GAP_EVENTS_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GapScanningParams.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,68 @@
+/* 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 __GAP_SCANNING_PARAMS_H__
+#define __GAP_SCANNING_PARAMS_H__
+
+class GapScanningParams {
+public:
+    static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625us units - 2.5ms. */
+    static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625us units - 10.24s. */
+    static const unsigned SCAN_WINDOW_MIN   = 0x0004; /**< Minimum Scan window in 625us units - 2.5ms. */
+    static const unsigned SCAN_WINDOW_MAX   = 0x4000; /**< Maximum Scan window in 625us units - 10.24s. */
+    static const unsigned SCAN_TIMEOUT_MIN  = 0x0001; /**< Minimum Scan timeout in seconds. */
+    static const unsigned SCAN_TIMEOUT_MAX  = 0xFFFF; /**< Maximum Scan timeout in seconds. */
+
+public:
+    GapScanningParams(uint16_t interval       = SCAN_INTERVAL_MAX,
+                      uint16_t window         = SCAN_WINDOW_MAX,
+                      uint16_t timeout        = 0,
+                      bool     activeScanning = false);
+
+    static const uint16_t UNIT_0_625_MS = 625;  /**< Number of microseconds in 0.625 milliseconds. */
+    static uint16_t MSEC_TO_SCAN_DURATION_UNITS(uint32_t durationInMillis) {
+        return (durationInMillis * 1000) / UNIT_0_625_MS;
+    }
+
+    ble_error_t setInterval(uint16_t newIntervalInMS);
+
+    ble_error_t setWindow(uint16_t newWindowInMS);
+
+    ble_error_t setTimeout(uint16_t newTimeout);
+
+    void        setActiveScanning(bool activeScanning);
+
+public:
+    /* @Note: The following return durations in units of 0.625ms */
+    uint16_t getInterval(void) const {return _interval;}
+    uint16_t getWindow(void)   const {return _window;  }
+
+    uint16_t getTimeout(void)  const {return _timeout; }
+    bool     getActiveScanning(void) const {return _activeScanning;}
+
+private:
+    uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms and 10.24s). */
+    uint16_t _window;   /**< Scan window in units of 625us (between 2.5ms and 10.24s). */
+    uint16_t _timeout;  /**< Scan timeout between 0x0001 and 0xFFFF in seconds; 0x0000 disables timeout. */
+    bool     _activeScanning; /**< Obtain the peer device's advertising data and (if possible) scanResponse. */
+
+private:
+    /* Disallow copy constructor. */
+    GapScanningParams(const GapScanningParams &);
+    GapScanningParams& operator =(const GapScanningParams &in);
+};
+
+#endif // ifndef __GAP_SCANNING_PARAMS_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattAttribute.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,81 @@
+/* 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 __GATT_ATTRIBUTE_H__
+#define __GATT_ATTRIBUTE_H__
+
+#include "UUID.h"
+
+class GattAttribute {
+public:
+    typedef uint16_t Handle_t;
+    static const Handle_t INVALID_HANDLE = 0x0000;
+
+public:
+    /**
+     *  @brief  Creates a new GattAttribute using the specified
+     *          UUID, value length, and inital value.
+     *
+     *  @param[in]  uuid
+     *              The UUID to use for this attribute.
+     *  @param[in]  valuePtr
+     *              The memory holding the initial value.
+     *  @param[in]  len
+     *              The length in bytes of this attribute's value.
+     *  @param[in]  maxLen
+     *              The max length in bytes of this attribute's value.
+     *  @param[in]  hasVariableLen
+     *              Whether the attribute's value length changes overtime.
+     *
+     *  @section EXAMPLE
+     *
+     *  @code
+     *
+     *  // UUID = 0x2A19, Min length 2, Max len = 2
+     *  GattAttribute attr = GattAttribute(0x2A19, &someValue, 2, 2);
+     *
+     *  @endcode
+     */
+    GattAttribute(const UUID &uuid, uint8_t *valuePtr = NULL, uint16_t len = 0, uint16_t maxLen = 0, bool hasVariableLen = true) :
+        _uuid(uuid), _valuePtr(valuePtr), _lenMax(maxLen), _len(len), _hasVariableLen(hasVariableLen), _handle() {
+        /* Empty */
+    }
+
+public:
+    Handle_t    getHandle(void)         const {return _handle;        }
+    const UUID &getUUID(void)           const {return _uuid;          }
+    uint16_t    getLength(void)         const {return _len;           }
+    uint16_t    getMaxLength(void)      const {return _lenMax;        }
+    uint16_t   *getLengthPtr(void)            {return &_len;          }
+    void        setHandle(Handle_t id)        {_handle = id;          }
+    uint8_t    *getValuePtr(void)             {return _valuePtr;      }
+    bool        hasVariableLength(void) const {return _hasVariableLen;}
+
+private:
+    UUID      _uuid;           /* Characteristic UUID. */
+    uint8_t  *_valuePtr;
+    uint16_t  _lenMax;         /* Maximum length of the value. */
+    uint16_t  _len;            /* Current length of the value. */
+    bool      _hasVariableLen;
+    Handle_t  _handle;
+
+private:
+    /* Disallow copy and assignment. */
+    GattAttribute(const GattAttribute &);
+    GattAttribute& operator=(const GattAttribute &);
+};
+
+#endif // ifndef __GATT_ATTRIBUTE_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattCallbackParamTypes.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,97 @@
+/* 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 __GATT_CALLBACK_PARAM_TYPES_H__
+#define __GATT_CALLBACK_PARAM_TYPES_H__
+
+struct GattWriteCallbackParams {
+    enum WriteOp_t {
+        OP_INVALID               = 0x00,  /**< Invalid operation. */
+        OP_WRITE_REQ             = 0x01,  /**< Write request. */
+        OP_WRITE_CMD             = 0x02,  /**< Write command. */
+        OP_SIGN_WRITE_CMD        = 0x03,  /**< Signed write command. */
+        OP_PREP_WRITE_REQ        = 0x04,  /**< Prepare write request. */
+        OP_EXEC_WRITE_REQ_CANCEL = 0x05,  /**< Execute write request: cancel all prepared writes. */
+        OP_EXEC_WRITE_REQ_NOW    = 0x06,  /**< Execute write request: immediately execute all prepared writes. */
+    };
+
+    Gap::Handle_t            connHandle;
+    GattAttribute::Handle_t  handle;
+    WriteOp_t                writeOp; /**< Type of write operation. */
+    uint16_t                 offset;  /**< Offset for the write operation. */
+    uint16_t                 len;
+    const uint8_t           *data;    /* @note: Data might not persist beyond the callback; make a local copy if needed. */
+};
+
+struct GattReadCallbackParams {
+    Gap::Handle_t            connHandle;
+    GattAttribute::Handle_t  handle;
+    uint16_t                 offset;  /**< Offset for the read operation. */
+    uint16_t                 len;
+    const uint8_t           *data;    /* @note: Data might not persist beyond the callback; make a local copy if needed. */
+};
+
+struct GattSysAttrMissingCallbackParams {
+    Gap::Handle_t            connHandle;
+};
+
+enum GattAuthCallbackReply_t {
+    AUTH_CALLBACK_REPLY_SUCCESS                       = 0x00,    /**< Success. */
+    AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE         = 0x0101,  /**< ATT Error: Invalid attribute handle. */
+    AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED     = 0x0102,  /**< ATT Error: Read not permitted. */
+    AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED    = 0x0103,  /**< ATT Error: Write not permitted. */
+    AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION   = 0x0105,  /**< ATT Error: Authenticated link required. */
+    AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET         = 0x0107,  /**< ATT Error: The specified offset was past the end of the attribute. */
+    AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION    = 0x0108,  /**< ATT Error: Used in ATT as "insufficient authorization". */
+    AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL     = 0x0109,  /**< ATT Error: Used in ATT as "prepare queue full". */
+    AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND    = 0x010A,  /**< ATT Error: Used in ATT as "attribute not found". */
+    AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG     = 0x010B,  /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
+    AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D,  /**< ATT Error: Invalid value size. */
+    AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES        = 0x0111,  /**< ATT Error: Encrypted link required. */
+};
+
+struct GattWriteAuthCallbackParams {
+    Gap::Handle_t            connHandle;
+    GattAttribute::Handle_t  handle;
+    uint16_t                 offset; /**< Offset for the write operation. */
+    uint16_t                 len;    /**< Length of the incoming data. */
+    const uint8_t           *data;   /**< Incoming data, variable length. */
+    GattAuthCallbackReply_t  authorizationReply; /* This is the out parameter that the callback 
+                                                  * needs to set to AUTH_CALLBACK_REPLY_SUCCESS 
+                                                  * for the request to proceed. */
+};
+
+struct GattReadAuthCallbackParams {
+    Gap::Handle_t            connHandle;
+    GattAttribute::Handle_t  handle;
+    uint16_t                 offset; /**< Offset for the read operation. */
+    uint16_t                 len;    /**< Optional: new length of the outgoing data. */
+    uint8_t                 *data;   /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */
+    GattAuthCallbackReply_t  authorizationReply; /* This is the out parameter that the callback
+                                                  * needs to set to AUTH_CALLBACK_REPLY_SUCCESS
+                                                  * for the request to proceed. */
+};
+
+/* For encapsulating handle-value update events (notifications or indications) generated at the remote server. */
+struct GattHVXCallbackParams {
+  Gap::Handle_t            connHandle;
+  GattAttribute::Handle_t  handle; /**< Attribute Handle to which the HVx operation applies. */
+  HVXType_t                type;   /**< Indication or Notification, see @ref HVXType_t. */
+  uint16_t                 len;    /**< Attribute data length. */
+  const uint8_t           *data;   /**< Attribute data, variable length. */
+};
+
+#endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattCharacteristic.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,547 @@
+/* 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 __GATT_CHARACTERISTIC_H__
+#define __GATT_CHARACTERISTIC_H__
+
+#include "Gap.h"
+#include "SecurityManager.h"
+#include "GattAttribute.h"
+#include "GattCallbackParamTypes.h"
+#include "FunctionPointerWithContext.h"
+
+class GattCharacteristic {
+public:
+    enum {
+        UUID_BATTERY_LEVEL_STATE_CHAR                     = 0x2A1B,
+        UUID_BATTERY_POWER_STATE_CHAR                     = 0x2A1A,
+        UUID_REMOVABLE_CHAR                               = 0x2A3A,
+        UUID_SERVICE_REQUIRED_CHAR                        = 0x2A3B,
+        UUID_ALERT_CATEGORY_ID_CHAR                       = 0x2A43,
+        UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR              = 0x2A42,
+        UUID_ALERT_LEVEL_CHAR                             = 0x2A06,
+        UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR        = 0x2A44,
+        UUID_ALERT_STATUS_CHAR                            = 0x2A3F,
+        UUID_BATTERY_LEVEL_CHAR                           = 0x2A19,
+        UUID_BLOOD_PRESSURE_FEATURE_CHAR                  = 0x2A49,
+        UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR              = 0x2A35,
+        UUID_BODY_SENSOR_LOCATION_CHAR                    = 0x2A38,
+        UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR              = 0x2A22,
+        UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR             = 0x2A32,
+        UUID_BOOT_MOUSE_INPUT_REPORT_CHAR                 = 0x2A33,
+        UUID_CURRENT_TIME_CHAR                            = 0x2A2B,
+        UUID_DATE_TIME_CHAR                               = 0x2A08,
+        UUID_DAY_DATE_TIME_CHAR                           = 0x2A0A,
+        UUID_DAY_OF_WEEK_CHAR                             = 0x2A09,
+        UUID_DST_OFFSET_CHAR                              = 0x2A0D,
+        UUID_EXACT_TIME_256_CHAR                          = 0x2A0C,
+        UUID_FIRMWARE_REVISION_STRING_CHAR                = 0x2A26,
+        UUID_GLUCOSE_FEATURE_CHAR                         = 0x2A51,
+        UUID_GLUCOSE_MEASUREMENT_CHAR                     = 0x2A18,
+        UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR             = 0x2A34,
+        UUID_HARDWARE_REVISION_STRING_CHAR                = 0x2A27,
+        UUID_HEART_RATE_CONTROL_POINT_CHAR                = 0x2A39,
+        UUID_HEART_RATE_MEASUREMENT_CHAR                  = 0x2A37,
+        UUID_HID_CONTROL_POINT_CHAR                       = 0x2A4C,
+        UUID_HID_INFORMATION_CHAR                         = 0x2A4A,
+        UUID_HUMIDITY_CHAR                                = 0x2A6F,
+        UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR = 0x2A2A,
+        UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR              = 0x2A36,
+        UUID_INTERMEDIATE_TEMPERATURE_CHAR                = 0x2A1E,
+        UUID_LOCAL_TIME_INFORMATION_CHAR                  = 0x2A0F,
+        UUID_MANUFACTURER_NAME_STRING_CHAR                = 0x2A29,
+        UUID_MEASUREMENT_INTERVAL_CHAR                    = 0x2A21,
+        UUID_MODEL_NUMBER_STRING_CHAR                     = 0x2A24,
+        UUID_UNREAD_ALERT_CHAR                            = 0x2A45,
+        UUID_NEW_ALERT_CHAR                               = 0x2A46,
+        UUID_PNP_ID_CHAR                                  = 0x2A50,
+        UUID_PRESSURE_CHAR                                = 0x2A6D,
+        UUID_PROTOCOL_MODE_CHAR                           = 0x2A4E,
+        UUID_RECORD_ACCESS_CONTROL_POINT_CHAR             = 0x2A52,
+        UUID_REFERENCE_TIME_INFORMATION_CHAR              = 0x2A14,
+        UUID_REPORT_CHAR                                  = 0x2A4D,
+        UUID_REPORT_MAP_CHAR                              = 0x2A4B,
+        UUID_RINGER_CONTROL_POINT_CHAR                    = 0x2A40,
+        UUID_RINGER_SETTING_CHAR                          = 0x2A41,
+        UUID_SCAN_INTERVAL_WINDOW_CHAR                    = 0x2A4F,
+        UUID_SCAN_REFRESH_CHAR                            = 0x2A31,
+        UUID_SERIAL_NUMBER_STRING_CHAR                    = 0x2A25,
+        UUID_SOFTWARE_REVISION_STRING_CHAR                = 0x2A28,
+        UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR            = 0x2A47,
+        UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR         = 0x2A48,
+        UUID_SYSTEM_ID_CHAR                               = 0x2A23,
+        UUID_TEMPERATURE_CHAR                             = 0x2A6E,
+        UUID_TEMPERATURE_MEASUREMENT_CHAR                 = 0x2A1C,
+        UUID_TEMPERATURE_TYPE_CHAR                        = 0x2A1D,
+        UUID_TIME_ACCURACY_CHAR                           = 0x2A12,
+        UUID_TIME_SOURCE_CHAR                             = 0x2A13,
+        UUID_TIME_UPDATE_CONTROL_POINT_CHAR               = 0x2A16,
+        UUID_TIME_UPDATE_STATE_CHAR                       = 0x2A17,
+        UUID_TIME_WITH_DST_CHAR                           = 0x2A11,
+        UUID_TIME_ZONE_CHAR                               = 0x2A0E,
+        UUID_TX_POWER_LEVEL_CHAR                          = 0x2A07,
+        UUID_CSC_FEATURE_CHAR                             = 0x2A5C,
+        UUID_CSC_MEASUREMENT_CHAR                         = 0x2A5B,
+        UUID_RSC_FEATURE_CHAR                             = 0x2A54,
+        UUID_RSC_MEASUREMENT_CHAR                         = 0x2A53
+    };
+
+    /**************************************************************************/
+    /*!
+        \brief  Standard GATT characteristic presentation format unit types.
+                These unit types are used to describe what the raw numeric
+                data in a characteristic actually represents.
+
+        \note   See https://developer.bluetooth.org/gatt/units/Pages/default.aspx
+    */
+    /**************************************************************************/
+    enum {
+        BLE_GATT_UNIT_NONE                                                   = 0x2700,      /**< No specified unit type. */
+        BLE_GATT_UNIT_LENGTH_METRE                                           = 0x2701,      /**< Length, metre. */
+        BLE_GATT_UNIT_MASS_KILOGRAM                                          = 0x2702,      /**< Mass, kilogram. */
+        BLE_GATT_UNIT_TIME_SECOND                                            = 0x2703,      /**< Time, second. */
+        BLE_GATT_UNIT_ELECTRIC_CURRENT_AMPERE                                = 0x2704,      /**< Electric current, ampere. */
+        BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_KELVIN                       = 0x2705,      /**< Thermodynamic temperature, kelvin. */
+        BLE_GATT_UNIT_AMOUNT_OF_SUBSTANCE_MOLE                               = 0x2706,      /**< Amount of substance, mole. */
+        BLE_GATT_UNIT_LUMINOUS_INTENSITY_CANDELA                             = 0x2707,      /**< Luminous intensity, candela. */
+        BLE_GATT_UNIT_AREA_SQUARE_METRES                                     = 0x2710,      /**< Area, square metres. */
+        BLE_GATT_UNIT_VOLUME_CUBIC_METRES                                    = 0x2711,      /**< Volume, cubic metres. */
+        BLE_GATT_UNIT_VELOCITY_METRES_PER_SECOND                             = 0x2712,      /**< Velocity, metres per second. */
+        BLE_GATT_UNIT_ACCELERATION_METRES_PER_SECOND_SQUARED                 = 0x2713,      /**< Acceleration, metres per second squared. */
+        BLE_GATT_UNIT_WAVENUMBER_RECIPROCAL_METRE                            = 0x2714,      /**< Wave number reciprocal, metre. */
+        BLE_GATT_UNIT_DENSITY_KILOGRAM_PER_CUBIC_METRE                       = 0x2715,      /**< Density, kilogram per cubic metre. */
+        BLE_GATT_UNIT_SURFACE_DENSITY_KILOGRAM_PER_SQUARE_METRE              = 0x2716,      /**<  */
+        BLE_GATT_UNIT_SPECIFIC_VOLUME_CUBIC_METRE_PER_KILOGRAM               = 0x2717,      /**<  */
+        BLE_GATT_UNIT_CURRENT_DENSITY_AMPERE_PER_SQUARE_METRE                = 0x2718,      /**<  */
+        BLE_GATT_UNIT_MAGNETIC_FIELD_STRENGTH_AMPERE_PER_METRE               = 0x2719,      /**< Magnetic field strength, ampere per metre. */
+        BLE_GATT_UNIT_AMOUNT_CONCENTRATION_MOLE_PER_CUBIC_METRE              = 0x271A,      /**<  */
+        BLE_GATT_UNIT_MASS_CONCENTRATION_KILOGRAM_PER_CUBIC_METRE            = 0x271B,      /**<  */
+        BLE_GATT_UNIT_LUMINANCE_CANDELA_PER_SQUARE_METRE                     = 0x271C,      /**<  */
+        BLE_GATT_UNIT_REFRACTIVE_INDEX                                       = 0x271D,      /**<  */
+        BLE_GATT_UNIT_RELATIVE_PERMEABILITY                                  = 0x271E,      /**<  */
+        BLE_GATT_UNIT_PLANE_ANGLE_RADIAN                                     = 0x2720,      /**<  */
+        BLE_GATT_UNIT_SOLID_ANGLE_STERADIAN                                  = 0x2721,      /**<  */
+        BLE_GATT_UNIT_FREQUENCY_HERTZ                                        = 0x2722,      /**< Frequency, hertz. */
+        BLE_GATT_UNIT_FORCE_NEWTON                                           = 0x2723,      /**< Force, newton. */
+        BLE_GATT_UNIT_PRESSURE_PASCAL                                        = 0x2724,      /**< Pressure, pascal. */
+        BLE_GATT_UNIT_ENERGY_JOULE                                           = 0x2725,      /**< Energy, joule. */
+        BLE_GATT_UNIT_POWER_WATT                                             = 0x2726,      /**< Power, watt. */
+        BLE_GATT_UNIT_ELECTRIC_CHARGE_COULOMB                                = 0x2727,      /**< Electrical charge, coulomb. */
+        BLE_GATT_UNIT_ELECTRIC_POTENTIAL_DIFFERENCE_VOLT                     = 0x2728,      /**< Electrical potential difference, voltage. */
+        BLE_GATT_UNIT_CAPACITANCE_FARAD                                      = 0x2729,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_RESISTANCE_OHM                                = 0x272A,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_CONDUCTANCE_SIEMENS                           = 0x272B,      /**<  */
+        BLE_GATT_UNIT_MAGNETIC_FLEX_WEBER                                    = 0x272C,      /**<  */
+        BLE_GATT_UNIT_MAGNETIC_FLEX_DENSITY_TESLA                            = 0x272D,      /**<  */
+        BLE_GATT_UNIT_INDUCTANCE_HENRY                                       = 0x272E,      /**<  */
+        BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_CELSIUS               = 0x272F,      /**<  */
+        BLE_GATT_UNIT_LUMINOUS_FLUX_LUMEN                                    = 0x2730,      /**<  */
+        BLE_GATT_UNIT_ILLUMINANCE_LUX                                        = 0x2731,      /**<  */
+        BLE_GATT_UNIT_ACTIVITY_REFERRED_TO_A_RADIONUCLIDE_BECQUEREL          = 0x2732,      /**<  */
+        BLE_GATT_UNIT_ABSORBED_DOSE_GRAY                                     = 0x2733,      /**<  */
+        BLE_GATT_UNIT_DOSE_EQUIVALENT_SIEVERT                                = 0x2734,      /**<  */
+        BLE_GATT_UNIT_CATALYTIC_ACTIVITY_KATAL                               = 0x2735,      /**<  */
+        BLE_GATT_UNIT_DYNAMIC_VISCOSITY_PASCAL_SECOND                        = 0x2740,      /**<  */
+        BLE_GATT_UNIT_MOMENT_OF_FORCE_NEWTON_METRE                           = 0x2741,      /**<  */
+        BLE_GATT_UNIT_SURFACE_TENSION_NEWTON_PER_METRE                       = 0x2742,      /**<  */
+        BLE_GATT_UNIT_ANGULAR_VELOCITY_RADIAN_PER_SECOND                     = 0x2743,      /**<  */
+        BLE_GATT_UNIT_ANGULAR_ACCELERATION_RADIAN_PER_SECOND_SQUARED         = 0x2744,      /**<  */
+        BLE_GATT_UNIT_HEAT_FLUX_DENSITY_WATT_PER_SQUARE_METRE                = 0x2745,      /**<  */
+        BLE_GATT_UNIT_HEAT_CAPACITY_JOULE_PER_KELVIN                         = 0x2746,      /**<  */
+        BLE_GATT_UNIT_SPECIFIC_HEAT_CAPACITY_JOULE_PER_KILOGRAM_KELVIN       = 0x2747,      /**<  */
+        BLE_GATT_UNIT_SPECIFIC_ENERGY_JOULE_PER_KILOGRAM                     = 0x2748,      /**<  */
+        BLE_GATT_UNIT_THERMAL_CONDUCTIVITY_WATT_PER_METRE_KELVIN             = 0x2749,      /**<  */
+        BLE_GATT_UNIT_ENERGY_DENSITY_JOULE_PER_CUBIC_METRE                   = 0x274A,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_FIELD_STRENGTH_VOLT_PER_METRE                 = 0x274B,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_CHARGE_DENSITY_COULOMB_PER_CUBIC_METRE        = 0x274C,      /**<  */
+        BLE_GATT_UNIT_SURFACE_CHARGE_DENSITY_COULOMB_PER_SQUARE_METRE        = 0x274D,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_FLUX_DENSITY_COULOMB_PER_SQUARE_METRE         = 0x274E,      /**<  */
+        BLE_GATT_UNIT_PERMITTIVITY_FARAD_PER_METRE                           = 0x274F,      /**<  */
+        BLE_GATT_UNIT_PERMEABILITY_HENRY_PER_METRE                           = 0x2750,      /**<  */
+        BLE_GATT_UNIT_MOLAR_ENERGY_JOULE_PER_MOLE                            = 0x2751,      /**<  */
+        BLE_GATT_UNIT_MOLAR_ENTROPY_JOULE_PER_MOLE_KELVIN                    = 0x2752,      /**<  */
+        BLE_GATT_UNIT_EXPOSURE_COULOMB_PER_KILOGRAM                          = 0x2753,      /**<  */
+        BLE_GATT_UNIT_ABSORBED_DOSE_RATE_GRAY_PER_SECOND                     = 0x2754,      /**<  */
+        BLE_GATT_UNIT_RADIANT_INTENSITY_WATT_PER_STERADIAN                   = 0x2755,      /**<  */
+        BLE_GATT_UNIT_RADIANCE_WATT_PER_SQUARE_METRE_STERADIAN               = 0x2756,      /**<  */
+        BLE_GATT_UNIT_CATALYTIC_ACTIVITY_CONCENTRATION_KATAL_PER_CUBIC_METRE = 0x2757,      /**<  */
+        BLE_GATT_UNIT_TIME_MINUTE                                            = 0x2760,      /**< Time, minute. */
+        BLE_GATT_UNIT_TIME_HOUR                                              = 0x2761,      /**< Time, hour. */
+        BLE_GATT_UNIT_TIME_DAY                                               = 0x2762,      /**< Time, day. */
+        BLE_GATT_UNIT_PLANE_ANGLE_DEGREE                                     = 0x2763,      /**<  */
+        BLE_GATT_UNIT_PLANE_ANGLE_MINUTE                                     = 0x2764,      /**<  */
+        BLE_GATT_UNIT_PLANE_ANGLE_SECOND                                     = 0x2765,      /**<  */
+        BLE_GATT_UNIT_AREA_HECTARE                                           = 0x2766,      /**<  */
+        BLE_GATT_UNIT_VOLUME_LITRE                                           = 0x2767,      /**<  */
+        BLE_GATT_UNIT_MASS_TONNE                                             = 0x2768,      /**<  */
+        BLE_GATT_UNIT_PRESSURE_BAR                                           = 0x2780,      /**< Pressure, bar. */
+        BLE_GATT_UNIT_PRESSURE_MILLIMETRE_OF_MERCURY                         = 0x2781,      /**< Pressure, millimetre of mercury. */
+        BLE_GATT_UNIT_LENGTH_ANGSTROM                                        = 0x2782,      /**<  */
+        BLE_GATT_UNIT_LENGTH_NAUTICAL_MILE                                   = 0x2783,      /**<  */
+        BLE_GATT_UNIT_AREA_BARN                                              = 0x2784,      /**<  */
+        BLE_GATT_UNIT_VELOCITY_KNOT                                          = 0x2785,      /**<  */
+        BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_NEPER                       = 0x2786,      /**<  */
+        BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_BEL                         = 0x2787,      /**<  */
+        BLE_GATT_UNIT_LENGTH_YARD                                            = 0x27A0,      /**< Length, yard. */
+        BLE_GATT_UNIT_LENGTH_PARSEC                                          = 0x27A1,      /**< Length, parsec. */
+        BLE_GATT_UNIT_LENGTH_INCH                                            = 0x27A2,      /**< Length, inch. */
+        BLE_GATT_UNIT_LENGTH_FOOT                                            = 0x27A3,      /**< Length, foot. */
+        BLE_GATT_UNIT_LENGTH_MILE                                            = 0x27A4,      /**< Length, mile. */
+        BLE_GATT_UNIT_PRESSURE_POUND_FORCE_PER_SQUARE_INCH                   = 0x27A5,      /**<  */
+        BLE_GATT_UNIT_VELOCITY_KILOMETRE_PER_HOUR                            = 0x27A6,      /**< Velocity, kilometre per hour. */
+        BLE_GATT_UNIT_VELOCITY_MILE_PER_HOUR                                 = 0x27A7,      /**< Velocity, mile per hour. */
+        BLE_GATT_UNIT_ANGULAR_VELOCITY_REVOLUTION_PER_MINUTE                 = 0x27A8,      /**< Angular Velocity, revolution per minute. */
+        BLE_GATT_UNIT_ENERGY_GRAM_CALORIE                                    = 0x27A9,      /**< Energy, gram calorie. */
+        BLE_GATT_UNIT_ENERGY_KILOGRAM_CALORIE                                = 0x27AA,      /**< Energy, kilogram calorie. */
+        BLE_GATT_UNIT_ENERGY_KILOWATT_HOUR                                   = 0x27AB,      /**< Energy, killowatt hour. */
+        BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_FAHRENHEIT            = 0x27AC,      /**<  */
+        BLE_GATT_UNIT_PERCENTAGE                                             = 0x27AD,      /**< Percentage. */
+        BLE_GATT_UNIT_PER_MILLE                                              = 0x27AE,      /**<  */
+        BLE_GATT_UNIT_PERIOD_BEATS_PER_MINUTE                                = 0x27AF,      /**<  */
+        BLE_GATT_UNIT_ELECTRIC_CHARGE_AMPERE_HOURS                           = 0x27B0,      /**<  */
+        BLE_GATT_UNIT_MASS_DENSITY_MILLIGRAM_PER_DECILITRE                   = 0x27B1,      /**<  */
+        BLE_GATT_UNIT_MASS_DENSITY_MILLIMOLE_PER_LITRE                       = 0x27B2,      /**<  */
+        BLE_GATT_UNIT_TIME_YEAR                                              = 0x27B3,      /**< Time, year. */
+        BLE_GATT_UNIT_TIME_MONTH                                             = 0x27B4,      /**< Time, month. */
+        BLE_GATT_UNIT_CONCENTRATION_COUNT_PER_CUBIC_METRE                    = 0x27B5,      /**<  */
+        BLE_GATT_UNIT_IRRADIANCE_WATT_PER_SQUARE_METRE                       = 0x27B6       /**<  */
+    };
+
+    /**************************************************************************/
+    /*!
+        \brief  Standard GATT number types.
+
+        \note   See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5.2
+        \note   See http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+    */
+    /**************************************************************************/
+    enum {
+        BLE_GATT_FORMAT_RFU     = 0x00, /**< Reserved for future use. */
+        BLE_GATT_FORMAT_BOOLEAN = 0x01, /**< Boolean. */
+        BLE_GATT_FORMAT_2BIT    = 0x02, /**< Unsigned 2-bit integer. */
+        BLE_GATT_FORMAT_NIBBLE  = 0x03, /**< Unsigned 4-bit integer. */
+        BLE_GATT_FORMAT_UINT8   = 0x04, /**< Unsigned 8-bit integer. */
+        BLE_GATT_FORMAT_UINT12  = 0x05, /**< Unsigned 12-bit integer. */
+        BLE_GATT_FORMAT_UINT16  = 0x06, /**< Unsigned 16-bit integer. */
+        BLE_GATT_FORMAT_UINT24  = 0x07, /**< Unsigned 24-bit integer. */
+        BLE_GATT_FORMAT_UINT32  = 0x08, /**< Unsigned 32-bit integer. */
+        BLE_GATT_FORMAT_UINT48  = 0x09, /**< Unsigned 48-bit integer. */
+        BLE_GATT_FORMAT_UINT64  = 0x0A, /**< Unsigned 64-bit integer. */
+        BLE_GATT_FORMAT_UINT128 = 0x0B, /**< Unsigned 128-bit integer. */
+        BLE_GATT_FORMAT_SINT8   = 0x0C, /**< Signed 2-bit integer. */
+        BLE_GATT_FORMAT_SINT12  = 0x0D, /**< Signed 12-bit integer. */
+        BLE_GATT_FORMAT_SINT16  = 0x0E, /**< Signed 16-bit integer. */
+        BLE_GATT_FORMAT_SINT24  = 0x0F, /**< Signed 24-bit integer. */
+        BLE_GATT_FORMAT_SINT32  = 0x10, /**< Signed 32-bit integer. */
+        BLE_GATT_FORMAT_SINT48  = 0x11, /**< Signed 48-bit integer. */
+        BLE_GATT_FORMAT_SINT64  = 0x12, /**< Signed 64-bit integer. */
+        BLE_GATT_FORMAT_SINT128 = 0x13, /**< Signed 128-bit integer. */
+        BLE_GATT_FORMAT_FLOAT32 = 0x14, /**< IEEE-754 32-bit floating point. */
+        BLE_GATT_FORMAT_FLOAT64 = 0x15, /**< IEEE-754 64-bit floating point. */
+        BLE_GATT_FORMAT_SFLOAT  = 0x16, /**< IEEE-11073 16-bit SFLOAT. */
+        BLE_GATT_FORMAT_FLOAT   = 0x17, /**< IEEE-11073 32-bit FLOAT. */
+        BLE_GATT_FORMAT_DUINT16 = 0x18, /**< IEEE-20601 format. */
+        BLE_GATT_FORMAT_UTF8S   = 0x19, /**< UTF-8 string. */
+        BLE_GATT_FORMAT_UTF16S  = 0x1A, /**< UTF-16 string. */
+        BLE_GATT_FORMAT_STRUCT  = 0x1B  /**< Opaque Structure. */
+    };
+
+    /**************************************************************************/
+    /*!
+        \brief  Standard GATT characteristic properties.
+
+        \note   See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.1.1
+                and Section 3.3.3.1 for Extended Properties
+    */
+    /**************************************************************************/
+    enum Properties_t {
+        BLE_GATT_CHAR_PROPERTIES_NONE                        = 0x00,
+        BLE_GATT_CHAR_PROPERTIES_BROADCAST                   = 0x01, /**< Permits broadcasts of the characteristic value using the Server Characteristic Configuration descriptor. */
+        BLE_GATT_CHAR_PROPERTIES_READ                        = 0x02, /**< Permits reads of the characteristic value. */
+        BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE      = 0x04, /**< Permits writes of the characteristic value without response. */
+        BLE_GATT_CHAR_PROPERTIES_WRITE                       = 0x08, /**< Permits writes of the characteristic value with response. */
+        BLE_GATT_CHAR_PROPERTIES_NOTIFY                      = 0x10, /**< Permits notifications of a characteristic value without acknowledgment. */
+        BLE_GATT_CHAR_PROPERTIES_INDICATE                    = 0x20, /**< Permits indications of a characteristic value with acknowledgment. */
+        BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES = 0x40, /**< Permits signed writes to the characteristic value. */
+        BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES         = 0x80  /**< Additional characteristic properties are defined in the Characteristic Extended Properties descriptor */
+    };
+
+    /**************************************************************************/
+    /*!
+        \brief  GATT presentation format wrapper
+
+        \note   See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5
+        \note   See https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+    */
+    /**************************************************************************/
+    struct PresentationFormat_t {
+        uint8_t  gatt_format;    /**< Format of the value; see @ref ble_gatt_format_t. */
+        int8_t   exponent;       /**< Exponent for integer data types. Example: if Exponent = -3 and the char value is 3892, the actual value is 3.892 */
+        uint16_t gatt_unit;      /**< UUID from Bluetooth Assigned Numbers; see @ref ble_gatt_unit_t. */
+        uint8_t  gatt_namespace; /**< Namespace from Bluetooth Assigned Numbers, normally '1'; see @ref BLE_GATT_CPF_NAMESPACES. */
+        uint16_t gatt_nsdesc;    /**< Namespace description from Bluetooth Assigned Numbers, normally '0'; see @ref BLE_GATT_CPF_NAMESPACES. */
+    };
+
+    /**
+     *  @brief  Creates a new GattCharacteristic using the specified 16-bit
+     *          UUID, value length, and properties.
+     *
+     *  @note   The UUID value must be unique in the service and is normally >1.
+     *
+     *  @param[in]  uuid
+     *              The UUID to use for this characteristic.
+     *  @param[in]  valuePtr
+     *              The memory holding the initial value. The value is copied
+     *              into the stack when the enclosing service is added, and
+     *              is thereafter maintained internally by the stack.
+     *  @param[in]  len
+     *              The length in bytes of this characteristic's value.
+     *  @param[in]  maxLen
+     *              The max length in bytes of this characteristic's value.
+     *  @param[in]  hasVariableLen
+     *              Whether the attribute's value length changes over time.
+     *  @param[in]  props
+     *              The 8-bit field containing the characteristic's properties.
+     *  @param[in]  descriptors
+     *              A pointer to an array of descriptors to be included within
+     *              this characteristic. The memory for the descriptor array is
+     *              owned by the caller, and should remain valid at least until
+     *              the enclosing service is added to the GATT table.
+     *  @param[in]  numDescriptors
+     *              The number of descriptors in the previous array.
+     *
+     * @NOTE: If valuePtr == NULL, length == 0, and properties == READ
+     *        for the value attribute of a characteristic, then that particular
+     *        characteristic may be considered optional and dropped while
+     *        instantiating the service with the underlying BLE stack.
+     */
+    GattCharacteristic(const UUID    &uuid,
+                       uint8_t       *valuePtr       = NULL,
+                       uint16_t       len            = 0,
+                       uint16_t       maxLen         = 0,
+                       uint8_t        props          = BLE_GATT_CHAR_PROPERTIES_NONE,
+                       GattAttribute *descriptors[]  = NULL,
+                       unsigned       numDescriptors = 0,
+                       bool           hasVariableLen = true) :
+        _valueAttribute(uuid, valuePtr, len, maxLen, hasVariableLen),
+        _properties(props),
+        _requiredSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK),
+        _descriptors(descriptors),
+        _descriptorCount(numDescriptors),
+        enabledReadAuthorization(false),
+        enabledWriteAuthorization(false),
+        readAuthorizationCallback(),
+        writeAuthorizationCallback() {
+        /* empty */
+    }
+
+public:
+    /**
+     * Set up the minimum security (mode and level) requirements for access to the characteristic's value attribute.
+     *
+     * @param securityMode Can be one of encryption or signing, with or without protection for man in the middle attacks (MITM).
+     */
+    void requireSecurity(SecurityManager::SecurityMode_t securityMode) {
+        _requiredSecurity = securityMode;
+    }
+
+public:
+    /**
+     * Authorization.
+     */
+    void setWriteAuthorizationCallback(void (*callback)(GattWriteAuthCallbackParams *)) {
+        writeAuthorizationCallback.attach(callback);
+        enabledWriteAuthorization = true;
+    }
+    template <typename T>
+    void setWriteAuthorizationCallback(T *object, void (T::*member)(GattWriteAuthCallbackParams *)) {
+        writeAuthorizationCallback.attach(object, member);
+        enabledWriteAuthorization = true;
+    }
+    void setReadAuthorizationCallback(void (*callback)(GattReadAuthCallbackParams *)) {
+        readAuthorizationCallback.attach(callback);
+        enabledReadAuthorization = true;
+    }
+    template <typename T>
+    void setReadAuthorizationCallback(T *object, void (T::*member)(GattReadAuthCallbackParams *)) {
+        readAuthorizationCallback.attach(object, member);
+        enabledReadAuthorization = true;
+    }
+
+    /**
+     * Helper function meant to be called from the guts of the BLE stack to
+     * determine the authorization reply for a write request.
+     * @param  params To capture the context of the write-auth request. Also contains an out-parameter for reply.
+     * @return        true if the write is authorized to proceed.
+     */
+    GattAuthCallbackReply_t authorizeWrite(GattWriteAuthCallbackParams *params) {
+        if (!isWriteAuthorizationEnabled()) {
+            return AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+
+        params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* Initialized to no-error by default. */
+        writeAuthorizationCallback.call(params);
+        return params->authorizationReply;
+    }
+
+    /**
+     * Helper function meant to be called from the guts of the BLE stack to
+     * determine the authorization reply for a read request.
+     * @param  params To capture the context of the read-auth request.
+     *
+     * @NOTE:  To authorize or deny the read the params->authorizationReply field
+     *         should be set to true (authorize) or false (deny).
+     *
+     *         If the read is approved and params->data is unchanged (NULL),
+     *         the current characteristic value will be used.
+     *
+     *         If the read is approved, a new value can be provided by setting
+     *         the params->data pointer and params->len fields.
+     *
+     * @return        true if the read is authorized to proceed.
+     */
+    GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params) {
+        if (!isReadAuthorizationEnabled()) {
+            return AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+
+        params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* Initialized to no-error by default. */
+        readAuthorizationCallback.call(params);
+        return params->authorizationReply;
+    }
+
+    /* accessors */
+public:
+    GattAttribute&          getValueAttribute()                 {return _valueAttribute;                }
+    const GattAttribute&    getValueAttribute()           const {return _valueAttribute;                }
+    GattAttribute::Handle_t getValueHandle(void)          const {return getValueAttribute().getHandle();}
+    uint8_t                 getProperties(void)           const {return _properties;                    }
+    SecurityManager::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity;              }
+    uint8_t                 getDescriptorCount(void)      const {return _descriptorCount;               }
+    bool                    isReadAuthorizationEnabled()  const {return enabledReadAuthorization;       }
+    bool                    isWriteAuthorizationEnabled() const {return enabledWriteAuthorization;      }
+
+    GattAttribute *getDescriptor(uint8_t index) {
+        if (index >= _descriptorCount) {
+            return NULL;
+        }
+
+        return _descriptors[index];
+    }
+
+private:
+    GattAttribute                     _valueAttribute;
+    uint8_t                           _properties;
+    SecurityManager::SecurityMode_t   _requiredSecurity;
+    GattAttribute                   **_descriptors;
+    uint8_t                           _descriptorCount;
+
+    bool enabledReadAuthorization;
+    bool enabledWriteAuthorization;
+    FunctionPointerWithContext<GattReadAuthCallbackParams *>  readAuthorizationCallback;
+    FunctionPointerWithContext<GattWriteAuthCallbackParams *> writeAuthorizationCallback;
+
+private:
+    /* Disallow copy and assignment. */
+    GattCharacteristic(const GattCharacteristic &);
+    GattCharacteristic& operator=(const GattCharacteristic &);
+};
+
+template <typename T>
+class ReadOnlyGattCharacteristic : public GattCharacteristic {
+public:
+    ReadOnlyGattCharacteristic<T>(const UUID    &uuid,
+                                  T             *valuePtr,
+                                  uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                  GattAttribute *descriptors[]        = NULL,
+                                  unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T),
+                           BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties, descriptors, numDescriptors, false) {
+        /* empty */
+    }
+};
+
+template <typename T>
+class WriteOnlyGattCharacteristic : public GattCharacteristic {
+public:
+    WriteOnlyGattCharacteristic<T>(const UUID     &uuid,
+                                   T              *valuePtr,
+                                   uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                   GattAttribute *descriptors[]        = NULL,
+                                   unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T),
+                           BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties, descriptors, numDescriptors) {
+        /* empty */
+    }
+};
+
+template <typename T>
+class ReadWriteGattCharacteristic : public GattCharacteristic {
+public:
+    ReadWriteGattCharacteristic<T>(const UUID    &uuid,
+                                   T             *valuePtr,
+                                   uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                   GattAttribute *descriptors[]        = NULL,
+                                   unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T),
+                           BLE_GATT_CHAR_PROPERTIES_READ | BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties, descriptors, numDescriptors) {
+        /* empty */
+    }
+};
+
+template <typename T, unsigned NUM_ELEMENTS>
+class WriteOnlyArrayGattCharacteristic : public GattCharacteristic {
+public:
+    WriteOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const          UUID &uuid,
+                                                      T              valuePtr[NUM_ELEMENTS],
+                                                      uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                                      GattAttribute *descriptors[]        = NULL,
+                                                      unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS,
+                           BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties, descriptors, numDescriptors) {
+        /* empty */
+    }
+};
+
+template <typename T, unsigned NUM_ELEMENTS>
+class ReadOnlyArrayGattCharacteristic : public GattCharacteristic {
+public:
+    ReadOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID    &uuid,
+                                                     T              valuePtr[NUM_ELEMENTS],
+                                                     uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                                     GattAttribute *descriptors[]        = NULL,
+                                                     unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS,
+                           BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties, descriptors, numDescriptors, false) {
+        /* empty */
+    }
+};
+
+template <typename T, unsigned NUM_ELEMENTS>
+class ReadWriteArrayGattCharacteristic : public GattCharacteristic {
+public:
+    ReadWriteArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID    &uuid,
+                                                      T              valuePtr[NUM_ELEMENTS],
+                                                      uint8_t        additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE,
+                                                      GattAttribute *descriptors[]        = NULL,
+                                                      unsigned       numDescriptors       = 0) :
+        GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS,
+                           BLE_GATT_CHAR_PROPERTIES_READ | BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties, descriptors, numDescriptors) {
+        /* empty */
+    }
+};
+
+#endif // ifndef __GATT_CHARACTERISTIC_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattClient.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,475 @@
+/* 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 __GATT_CLIENT_H__
+#define __GATT_CLIENT_H__
+
+#include "Gap.h"
+#include "GattAttribute.h"
+#include "ServiceDiscovery.h"
+#include "CharacteristicDescriptorDiscovery.h"
+
+#include "GattCallbackParamTypes.h"
+
+#include "CallChainOfFunctionPointersWithContext.h"
+
+class GattClient {
+public:
+    typedef FunctionPointerWithContext<const GattReadCallbackParams*> ReadCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*> ReadCallbackChain_t;
+
+    enum WriteOp_t {
+        GATT_OP_WRITE_REQ = 0x01,  /**< Write request. */
+        GATT_OP_WRITE_CMD = 0x02,  /**< Write command. */
+    };
+
+    typedef FunctionPointerWithContext<const GattWriteCallbackParams*> WriteCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> WriteCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattHVXCallbackParams*> HVXCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*> HVXCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattClient *> GattClientShutdownCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattClient *> GattClientShutdownCallbackChain_t;
+
+    /*
+     * The following functions are meant to be overridden in the platform-specific sub-class.
+     */
+public:
+    /**
+     * Launch service discovery. Once launched, application callbacks will be
+     * invoked for matching services or characteristics. isServiceDiscoveryActive()
+     * can be used to determine status, and a termination callback (if one was set up)
+     * will be invoked at the end. Service discovery can be terminated prematurely,
+     * if needed, using terminateServiceDiscovery().
+     *
+     * @param  connectionHandle
+     *           Handle for the connection with the peer.
+     * @param  sc
+     *           This is the application callback for a matching service. Taken as
+     *           NULL by default. Note: service discovery may still be active
+     *           when this callback is issued; calling asynchronous BLE-stack
+     *           APIs from within this application callback might cause the
+     *           stack to abort service discovery. If this becomes an issue, it
+     *           may be better to make a local copy of the discoveredService and
+     *           wait for service discovery to terminate before operating on the
+     *           service.
+     * @param  cc
+     *           This is the application callback for a matching characteristic.
+     *           Taken as NULL by default. Note: service discovery may still be
+     *           active when this callback is issued; calling asynchronous
+     *           BLE-stack APIs from within this application callback might cause
+     *           the stack to abort service discovery. If this becomes an issue,
+     *           it may be better to make a local copy of the discoveredCharacteristic
+     *           and wait for service discovery to terminate before operating on the
+     *           characteristic.
+     * @param  matchingServiceUUID
+     *           UUID-based filter for specifying a service in which the application is
+     *           interested. By default it is set as the wildcard UUID_UNKNOWN,
+     *           in which case it matches all services. If characteristic-UUID
+     *           filter (below) is set to the wildcard value, then a service
+     *           callback will be invoked for the matching service (or for every
+     *           service if the service filter is a wildcard).
+     * @param  matchingCharacteristicUUIDIn
+     *           UUID-based filter for specifying characteristic in which the application
+     *           is interested. By default it is set as the wildcard UUID_UKNOWN
+     *           to match against any characteristic. If both service-UUID
+     *           filter and characteristic-UUID filter are used with non-wildcard
+     *           values, then only a single characteristic callback is
+     *           invoked for the matching characteristic.
+     *
+     * @note     Using wildcard values for both service-UUID and characteristic-
+     *           UUID will result in complete service discovery: callbacks being
+     *           called for every service and characteristic.
+     *
+     * @note     Providing NULL for the characteristic callback will result in
+     *           characteristic discovery being skipped for each matching
+     *           service. This allows for an inexpensive method to discover only
+     *           services.
+     *
+     * @return
+     *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+     */
+    virtual ble_error_t launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                               ServiceDiscovery::ServiceCallback_t         sc                           = NULL,
+                                               ServiceDiscovery::CharacteristicCallback_t  cc                           = NULL,
+                                               const UUID                                 &matchingServiceUUID          = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+                                               const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)sc;
+        (void)cc;
+        (void)matchingServiceUUID;
+        (void)matchingCharacteristicUUIDIn;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Launch service discovery for services. Once launched, service discovery will remain
+     * active with service-callbacks being issued back into the application for matching
+     * services. isServiceDiscoveryActive() can be used to
+     * determine status, and a termination callback (if set up) will be invoked
+     * at the end. Service discovery can be terminated prematurely, if needed,
+     * using terminateServiceDiscovery().
+     *
+     * @param  connectionHandle
+     *           Handle for the connection with the peer.
+     * @param  sc
+     *           This is the application callback for a matching service. Note: service discovery may still be active
+     *           when this callback is issued; calling asynchronous BLE-stack
+     *           APIs from within this application callback might cause the
+     *           stack to abort service discovery. If this becomes an issue, it
+     *           may be better to make a local copy of the discoveredService and
+     *           wait for service discovery to terminate before operating on the
+     *           service.
+     * @param  matchingServiceUUID
+     *           UUID-based filter for specifying a service in which the application is
+     *           interested. By default it is set as the wildcard UUID_UNKNOWN,
+     *           in which case it matches all services.
+     *
+     * @return
+     *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+     */
+    virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
+                                         ServiceDiscovery::ServiceCallback_t  callback,
+                                         const UUID                          &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) {
+        return launchServiceDiscovery(connectionHandle, callback, NULL, matchingServiceUUID); /* We take advantage of the property
+                                                                * that providing NULL for the characteristic callback will result in
+                                                                * characteristic discovery being skipped for each matching
+                                                                * service. This allows for an inexpensive method to discover only
+                                                                * services. Porters are free to override this. */
+    }
+
+    /**
+     * Launch service discovery for services. Once launched, service discovery will remain
+     * active with service-callbacks being issued back into the application for matching
+     * services. isServiceDiscoveryActive() can be used to
+     * determine status, and a termination callback (if set up) will be invoked
+     * at the end. Service discovery can be terminated prematurely, if needed,
+     * using terminateServiceDiscovery().
+     *
+     * @param  connectionHandle
+     *           Handle for the connection with the peer.
+     * @param  sc
+     *           This is the application callback for a matching service. Note: service discovery may still be active
+     *           when this callback is issued; calling asynchronous BLE-stack
+     *           APIs from within this application callback might cause the
+     *           stack to abort service discovery. If this becomes an issue, it
+     *           may be better to make a local copy of the discoveredService and
+     *           wait for service discovery to terminate before operating on the
+     *           service.
+     * @param  startHandle, endHandle
+     *           Handle range within which to limit the search.
+     *
+     * @return
+     *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+     */
+    virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
+                                         ServiceDiscovery::ServiceCallback_t  callback,
+                                         GattAttribute::Handle_t              startHandle,
+                                         GattAttribute::Handle_t              endHandle) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)callback;
+        (void)startHandle;
+        (void)endHandle;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Is service-discovery currently active?
+     */
+    virtual bool isServiceDiscoveryActive(void) const {
+        return false; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Terminate an ongoing service discovery. This should result in an
+     * invocation of TerminationCallback if service-discovery is active.
+     */
+    virtual void terminateServiceDiscovery(void) {
+        /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /* Initiate a GATT Client read procedure by attribute-handle. */
+    virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connHandle;
+        (void)attributeHandle;
+        (void)offset;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Initiate a GATT Client write procedure.
+     *
+     * @param[in] cmd
+     *              Command can be either a write-request (which generates a
+     *              matching response from the peripheral), or a write-command
+     *              (which doesn't require the connected peer to respond).
+     * @param[in] connHandle
+     *              Connection handle.
+     * @param[in] attributeHandle
+     *              Handle for the target attribtue on the remote GATT server.
+     * @param[in] length
+     *              Length of the new value.
+     * @param[in] value
+     *              New value being written.
+     */
+    virtual ble_error_t write(GattClient::WriteOp_t    cmd,
+                              Gap::Handle_t            connHandle,
+                              GattAttribute::Handle_t  attributeHandle,
+                              size_t                   length,
+                              const uint8_t           *value) const {
+        /* Avoid compiler warnings about unused variables. */
+        (void)cmd;
+        (void)connHandle;
+        (void)attributeHandle;
+        (void)length;
+        (void)value;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /* Event callback handlers. */
+public:
+    /**
+     * Set up a callback for read response events.
+     * It is possible to remove registered callbacks using
+     * onDataRead().detach(callbackToRemove)
+     */
+    void onDataRead(ReadCallback_t callback) {
+        onDataReadCallbackChain.add(callback);
+    }
+
+    /**
+     * @brief provide access to the callchain of read callbacks
+     * It is possible to register callbacks using onDataRead().add(callback);
+     * It is possible to unregister callbacks using onDataRead().detach(callback)
+     * @return The read callbacks chain
+     */
+    ReadCallbackChain_t& onDataRead() {
+        return onDataReadCallbackChain;
+    }
+
+    /**
+     * Set up a callback for write response events.
+     * It is possible to remove registered callbacks using
+     * onDataWritten().detach(callbackToRemove).
+     * @Note: Write commands (issued using writeWoResponse) don't generate a response.
+     */
+    void onDataWritten(WriteCallback_t callback) {
+        onDataWriteCallbackChain.add(callback);
+    }
+
+    /**
+     * @brief provide access to the callchain of data written callbacks
+     * It is possible to register callbacks using onDataWritten().add(callback);
+     * It is possible to unregister callbacks using onDataWritten().detach(callback)
+     * @return The data written callbacks chain
+     */
+    WriteCallbackChain_t& onDataWritten() {
+        return onDataWriteCallbackChain;
+    }
+
+    /**
+     * Set up a callback for write response events.
+     * @Note: Write commands (issued using writeWoResponse) don't generate a response.
+     *
+     * @note: This API is now *deprecated* and will be dropped in the future.
+     * Please use onDataWritten() instead.
+     */
+    void onDataWrite(WriteCallback_t callback) {
+        onDataWritten(callback);
+    }
+
+    /**
+     * Set up a callback for when serviceDiscovery terminates.
+     */
+    virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+        (void)callback; /* Avoid compiler warnings about ununsed variables. */
+
+        /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * @brief launch discovery of descriptors for a given characteristic
+     * @details This function will discover all descriptors available for a
+     * specific characteristic.
+     *
+     * @param characteristic[in] The characteristic targeted by this discovery
+     * procedure
+     * @param discoveryCallback[in] User function called each time a descriptor
+     * is found during the procedure.
+     * @param terminationCallback[in] User provided function which will be called
+     * once the discovery procedure is terminating. This will get called when all
+     * the descriptors have been discovered or if an error occur during the discovery
+     * procedure.
+     *
+     * @return
+     *   BLE_ERROR_NONE if characteristic descriptor discovery is launched
+     *   successfully; else an appropriate error.
+     */
+    virtual ble_error_t discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
+        (void) characteristic;
+        (void) discoveryCallback;
+        (void) terminationCallback;
+        /* Requesting action from porter(s): override this API if this capability is supported. */
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * @brief Indicate if the discovery of characteristic descriptors is active for a given characteristic
+     * or not.
+     * @param characteristic[in] The characteristic concerned by the descriptors discovery.
+     * @return true if a descriptors discovery is active for the characteristic in input; otherwise false.
+     */
+    virtual bool isCharacteristicDescriptorDiscoveryActive(const DiscoveredCharacteristic& characteristic) const
+     {
+        (void) characteristic;
+        return false; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * @brief Terminate an ongoing characteristic descriptor discovery.
+     * @detail This should result in an invocation of the TerminationCallback if
+     * the characteristic descriptor discovery is active.
+     * @param characteristic[in] The characteristic on which the running descriptors
+     * discovery should be stopped.
+     */
+    virtual void terminateCharacteristicDescriptorDiscovery(const DiscoveredCharacteristic& characteristic) {
+        /* Requesting action from porter(s): override this API if this capability is supported. */
+        (void) characteristic;
+    }
+
+    /**
+     * Set up a callback for when the GATT client receives an update event
+     * corresponding to a change in the value of a characteristic on the remote
+     * GATT server.
+     * It is possible to remove registered callbacks using onHVX().detach(callbackToRemove).
+     */
+    void onHVX(HVXCallback_t callback) {
+        onHVXCallbackChain.add(callback);
+    }
+
+    /**
+     * Setup a callback to be invoked to notify the user application that the
+     * GattClient instance is about to shutdown (possibly as a result of a call
+     * to BLE::shutdown()).
+     *
+     * @Note: It is possible to chain together multiple onShutdown callbacks
+     * (potentially from different modules of an application) to be notified
+     * before the GattClient is shutdown.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onShutdown().detach(callback)
+     */
+    void onShutdown(const GattClientShutdownCallback_t& callback) {
+        shutdownCallChain.add(callback);
+    }
+    template <typename T>
+    void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
+        shutdownCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of shutdown event callbacks
+     * It is possible to register callbacks using onShutdown().add(callback);
+     * It is possible to unregister callbacks using onShutdown().detach(callback)
+     * @return The shutdown event callbacks chain
+     */
+    GattClientShutdownCallbackChain_t& onShutdown() {
+        return shutdownCallChain;
+    }
+
+    /**
+     * @brief provide access to the callchain of HVX callbacks
+     * It is possible to register callbacks using onHVX().add(callback);
+     * It is possible to unregister callbacks using onHVX().detach(callback)
+     * @return The HVX callbacks chain
+     */
+    HVXCallbackChain_t& onHVX() {
+        return onHVXCallbackChain;
+    }
+
+public:
+    /**
+     * Notify all registered onShutdown callbacks that the GattClient is
+     * about to be shutdown and clear all GattClient state of the
+     * associated object.
+     *
+     * This function is meant to be overridden in the platform-specific
+     * sub-class. Nevertheless, the sub-class is only expected to reset its
+     * state and not the data held in GattClient members. This shall be achieved
+     * by a call to GattClient::reset() from the sub-class' reset()
+     * implementation.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t reset(void) {
+        /* Notify that the instance is about to shutdown */
+        shutdownCallChain.call(this);
+        shutdownCallChain.clear();
+
+        onDataReadCallbackChain.clear();
+        onDataWriteCallbackChain.clear();
+        onHVXCallbackChain.clear();
+
+        return BLE_ERROR_NONE;
+    }
+
+protected:
+    GattClient() {
+        /* Empty */
+    }
+
+    /* Entry points for the underlying stack to report events back to the user. */
+public:
+    void processReadResponse(const GattReadCallbackParams *params) {
+        onDataReadCallbackChain(params);
+    }
+
+    void processWriteResponse(const GattWriteCallbackParams *params) {
+        onDataWriteCallbackChain(params);
+    }
+
+    void processHVXEvent(const GattHVXCallbackParams *params) {
+        if (onHVXCallbackChain) {
+            onHVXCallbackChain(params);
+        }
+    }
+
+protected:
+    ReadCallbackChain_t               onDataReadCallbackChain;
+    WriteCallbackChain_t              onDataWriteCallbackChain;
+    HVXCallbackChain_t                onHVXCallbackChain;
+    GattClientShutdownCallbackChain_t shutdownCallChain;
+
+private:
+    /* Disallow copy and assignment. */
+    GattClient(const GattClient &);
+    GattClient& operator=(const GattClient &);
+};
+
+#endif // ifndef __GATT_CLIENT_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattServer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,545 @@
+/* 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 __GATT_SERVER_H__
+#define __GATT_SERVER_H__
+
+#include "Gap.h"
+#include "GattService.h"
+#include "GattAttribute.h"
+#include "GattServerEvents.h"
+#include "GattCallbackParamTypes.h"
+#include "CallChainOfFunctionPointersWithContext.h"
+
+class GattServer {
+public:
+    /* Event callback handlers. */
+    typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattServer *> GattServerShutdownCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattServer *> GattServerShutdownCallbackChain_t;
+
+    typedef FunctionPointerWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallbackChain_t;
+
+    typedef FunctionPointerWithContext<GattAttribute::Handle_t> EventCallback_t;
+
+protected:
+    GattServer() :
+        serviceCount(0),
+        characteristicCount(0),
+        dataSentCallChain(),
+        dataWrittenCallChain(),
+        dataReadCallChain(),
+        sysAttrMissingCallChain(),
+        updatesEnabledCallback(NULL),
+        updatesDisabledCallback(NULL),
+        confirmationReceivedCallback(NULL) {
+        /* empty */
+    }
+
+    /*
+     * The following functions are meant to be overridden in the platform-specific sub-class.
+     */
+public:
+
+    /**
+     * Add a service declaration to the local server ATT table. Also add the
+     * characteristics contained within.
+     */
+    virtual ble_error_t addService(GattService &service) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)service;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Read the value of a characteristic from the local GATT server.
+     * @param[in]     attributeHandle
+     *                  Attribute handle for the value attribute of the characteristic.
+     * @param[out]    buffer
+     *                  A buffer to hold the value being read.
+     * @param[in/out] lengthP
+     *                  Length of the buffer being supplied. If the attribute
+     *                  value is longer than the size of the supplied buffer,
+     *                  this variable will hold upon return the total attribute value length
+     *                  (excluding offset). The application may use this
+     *                  information to allocate a suitable buffer size.
+     *
+     * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
+     */
+    virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)attributeHandle;
+        (void)buffer;
+        (void)lengthP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Read the value of a characteristic from the local GATT server.
+     * @param[in]     connectionHandle
+     *                  Connection handle.
+     * @param[in]     attributeHandle
+     *                  Attribute handle for the value attribute of the characteristic.
+     * @param[out]    buffer
+     *                  A buffer to hold the value being read.
+     * @param[in/out] lengthP
+     *                  Length of the buffer being supplied. If the attribute
+     *                  value is longer than the size of the supplied buffer,
+     *                  this variable will hold upon return the total attribute value length
+     *                  (excluding offset). The application may use this
+     *                  information to allocate a suitable buffer size.
+     *
+     * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
+     *
+     * @note This API is a version of the above, with an additional connection handle
+     *     parameter to allow fetches for connection-specific multivalued
+     *     attributes (such as the CCCDs).
+     */
+    virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)attributeHandle;
+        (void)buffer;
+        (void)lengthP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Update the value of a characteristic on the local GATT server.
+     *
+     * @param[in] attributeHandle
+     *              Handle for the value attribute of the characteristic.
+     * @param[in] value
+     *              A pointer to a buffer holding the new value.
+     * @param[in] size
+     *              Size of the new value (in bytes).
+     * @param[in] localOnly
+     *              Should this update be kept on the local
+     *              GATT server regardless of the state of the
+     *              notify/indicate flag in the CCCD for this
+     *              Characteristic? If set to true, no notification
+     *              or indication is generated.
+     *
+     * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+     */
+    virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)attributeHandle;
+        (void)value;
+        (void)size;
+        (void)localOnly;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Update the value of a characteristic on the local GATT server. A version
+     * of the same as the above, with a connection handle parameter to allow updates
+     * for connection-specific multivalued attributes (such as the CCCDs).
+     *
+     * @param[in] connectionHandle
+     *              Connection handle.
+     * @param[in] attributeHandle
+     *              Handle for the value attribute of the characteristic.
+     * @param[in] value
+     *              A pointer to a buffer holding the new value.
+     * @param[in] size
+     *              Size of the new value (in bytes).
+     * @param[in] localOnly
+     *              Should this update be kept on the local
+     *              GattServer regardless of the state of the
+     *              notify/indicate flag in the CCCD for this
+     *              Characteristic? If set to true, no notification
+     *              or indication is generated.
+     *
+     * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+     */
+    virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)attributeHandle;
+        (void)value;
+        (void)size;
+        (void)localOnly;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Perform an explicit BLE notification of a given attribute.
+     *
+     * @param[in] attributeHandle
+     *              Handle for the value attribute of the Characteristic.
+     * @param[in] value
+     *              A pointer to a buffer holding the new value
+     * @param[in] size
+     *              Size of the new value (in bytes).
+     *
+     * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+     */
+    virtual ble_error_t notify(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size)
+    {
+        (void)attributeHandle;
+        (void)value;
+        (void)size;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+    }
+
+    /**
+     * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
+     *
+     * @param       characteristic
+     *                The characteristic.
+     * @param[out]  enabledP
+     *                Upon return, *enabledP is true if updates are enabled, else false.
+     *
+     * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
+     */
+    virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)characteristic;
+        (void)enabledP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
+     *
+     * @param       connectionHandle
+     *                The connection handle.
+     * @param[out]  enabledP
+     *                Upon return, *enabledP is true if updates are enabled, else false.
+     *
+     * @param  characteristic
+     *           The characteristic.
+     *
+     * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
+     */
+    virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)characteristic;
+        (void)enabledP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /**
+     * A virtual function to allow underlying stacks to indicate if they support
+     * onDataRead(). It should be overridden to return true as applicable.
+     */
+    virtual bool isOnDataReadAvailable() const {
+        return false; /* Requesting action from porters: override this API if this capability is supported. */
+    }
+
+    /*
+     * APIs with non-virtual implementations.
+     */
+public:
+    /**
+     * Add a callback for the GATT event DATA_SENT (which is triggered when
+     * updates are sent out by GATT in the form of notifications).
+     *
+     * @Note: It is possible to chain together multiple onDataSent callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     */
+    void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
+    template <typename T>
+    void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
+        dataSentCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief get the callback chain called when the event DATA_EVENT is triggered.
+     */
+    DataSentCallbackChain_t& onDataSent() {
+        return dataSentCallChain;
+    }
+
+    /**
+     * Set up a callback for when an attribute has its value updated by or at the
+     * connected peer. For a peripheral, this callback is triggered when the local
+     * GATT server has an attribute updated by a write command from the peer.
+     * For a central, this callback is triggered when a response is received for
+     * a write request.
+     *
+     * @Note: It is possible to chain together multiple onDataWritten callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics. Many services, such as DFU and UART, add their own
+     * onDataWritten callbacks behind the scenes to trap interesting events.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
+     */
+    void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
+    template <typename T>
+    void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
+        dataWrittenCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of data written event callbacks
+     * It is possible to register callbacks using onDataWritten().add(callback);
+     * It is possible to unregister callbacks using onDataWritten().detach(callback)
+     * @return The data written event callbacks chain
+     */
+    DataWrittenCallbackChain_t& onDataWritten() {
+        return dataWrittenCallChain;
+    }
+
+    /**
+     * Set up a callback for when asystem descriptor (CCCD) is missing.
+     * This may be raised in response to a BLE profile change om a bonded connection.
+     * This callback provides the opportunity for user applications to restore
+     * CCCD state at the appropriate time.
+     *
+     * @Note: It is possible to chain together multiple onSysAttrMissing callbacks
+     * (potentially from different modules of an application), although it is unlikely
+     * that this will be beneficial.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onSysAttrMissing().detach(callback)
+     */
+    void onSysAttrMissing(const SysAttrMissingCallback_t& callback) {sysAttrMissingCallChain.add(callback);}
+    template <typename T>
+    void onSysAttrMissing(T *objPtr, void (T::*memberPtr)(const GattSysAttrMissingCallbackParams* connectionHandle)) {
+        sysAttrMissingCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of data written event callbacks
+     * It is possible to register callbacks using onDataWritten().add(callback);
+     * It is possible to unregister callbacks using onDataWritten().detach(callback)
+     * @return The data written event callbacks chain
+     */
+    SysAttrMissingCallbackChain_t& onSysAttrMissing() {
+        return sysAttrMissingCallChain;
+    }
+    /**
+     * Setup a callback to be invoked on the peripheral when an attribute is
+     * being read by a remote client.
+     *
+     * @Note: This functionality may not be available on all underlying stacks.
+     * You could use GattCharacteristic::setReadAuthorizationCallback() as an
+     * alternative. Refer to isOnDataReadAvailable().
+     *
+     * @Note: It is possible to chain together multiple onDataRead callbacks
+     * (potentially from different modules of an application) to receive updates
+     * to characteristics. Services may add their own onDataRead callbacks
+     * behind the scenes to trap interesting events.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onDataRead().detach(callback)
+     *
+     * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
+     *         else BLE_ERROR_NONE.
+     */
+    ble_error_t onDataRead(const DataReadCallback_t& callback) {
+        if (!isOnDataReadAvailable()) {
+            return BLE_ERROR_NOT_IMPLEMENTED;
+        }
+
+        dataReadCallChain.add(callback);
+        return BLE_ERROR_NONE;
+    }
+    template <typename T>
+    ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
+        if (!isOnDataReadAvailable()) {
+            return BLE_ERROR_NOT_IMPLEMENTED;
+        }
+
+        dataReadCallChain.add(objPtr, memberPtr);
+        return BLE_ERROR_NONE;
+    }
+
+    /**
+     * @brief provide access to the callchain of data read event callbacks
+     * It is possible to register callbacks using onDataRead().add(callback);
+     * It is possible to unregister callbacks using onDataRead().detach(callback)
+     * @return The data read event callbacks chain
+     */
+    DataReadCallbackChain_t& onDataRead() {
+        return dataReadCallChain;
+    }
+
+    /**
+     * Setup a callback to be invoked to notify the user application that the
+     * GattServer instance is about to shutdown (possibly as a result of a call
+     * to BLE::shutdown()).
+     *
+     * @Note: It is possible to chain together multiple onShutdown callbacks
+     * (potentially from different modules of an application) to be notified
+     * before the GattServer is shutdown.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onShutdown().detach(callback)
+     */
+    void onShutdown(const GattServerShutdownCallback_t& callback) {
+        shutdownCallChain.add(callback);
+    }
+    template <typename T>
+    void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
+        shutdownCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of shutdown event callbacks
+     * It is possible to register callbacks using onShutdown().add(callback);
+     * It is possible to unregister callbacks using onShutdown().detach(callback)
+     * @return The shutdown event callbacks chain
+     */
+    GattServerShutdownCallbackChain_t& onShutdown() {
+        return shutdownCallChain;
+    }
+
+    /**
+     * Set up a callback for when notifications or indications are enabled for a
+     * characteristic on the local GATT server.
+     */
+    void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
+
+    /**
+     * Set up a callback for when notifications or indications are disabled for a
+     * characteristic on the local GATT server.
+     */
+    void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
+
+    /**
+     * Set up a callback for when the GATT server receives a response for an
+     * indication event sent previously.
+     */
+    void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
+
+    /* Entry points for the underlying stack to report events back to the user. */
+protected:
+    void handleSysAttrMissingEvent(const GattSysAttrMissingCallbackParams *params) {
+        sysAttrMissingCallChain.call(params);
+    }
+
+    void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
+        dataWrittenCallChain.call(params);
+    }
+
+    void handleDataReadEvent(const GattReadCallbackParams *params) {
+        dataReadCallChain.call(params);
+    }
+
+    void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
+        switch (type) {
+            case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
+                if (updatesEnabledCallback) {
+                    updatesEnabledCallback(attributeHandle);
+                }
+                break;
+            case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
+                if (updatesDisabledCallback) {
+                    updatesDisabledCallback(attributeHandle);
+                }
+                break;
+            case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
+                if (confirmationReceivedCallback) {
+                    confirmationReceivedCallback(attributeHandle);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    void handleDataSentEvent(unsigned count) {
+        dataSentCallChain.call(count);
+    }
+
+public:
+    /**
+     * Notify all registered onShutdown callbacks that the GattServer is
+     * about to be shutdown and clear all GattServer state of the
+     * associated object.
+     *
+     * This function is meant to be overridden in the platform-specific
+     * sub-class. Nevertheless, the sub-class is only expected to reset its
+     * state and not the data held in GattServer members. This shall be achieved
+     * by a call to GattServer::reset() from the sub-class' reset()
+     * implementation.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t reset(void) {
+        /* Notify that the instance is about to shutdown */
+        shutdownCallChain.call(this);
+        shutdownCallChain.clear();
+
+        serviceCount = 0;
+        characteristicCount = 0;
+
+        dataSentCallChain.clear();
+        dataWrittenCallChain.clear();
+        dataReadCallChain.clear();
+        sysAttrMissingCallChain.clear();
+        updatesEnabledCallback       = NULL;
+        updatesDisabledCallback      = NULL;
+        confirmationReceivedCallback = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+protected:
+    uint8_t serviceCount;
+    uint8_t characteristicCount;
+
+private:
+    DataSentCallbackChain_t           dataSentCallChain;
+    DataWrittenCallbackChain_t        dataWrittenCallChain;
+    DataReadCallbackChain_t           dataReadCallChain;
+    SysAttrMissingCallbackChain_t     sysAttrMissingCallChain;
+    GattServerShutdownCallbackChain_t shutdownCallChain;
+    EventCallback_t                   updatesEnabledCallback;
+    EventCallback_t                   updatesDisabledCallback;
+    EventCallback_t                   confirmationReceivedCallback;
+
+private:
+    /* Disallow copy and assignment. */
+    GattServer(const GattServer &);
+    GattServer& operator=(const GattServer &);
+};
+
+#endif // ifndef __GATT_SERVER_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattServerEvents.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,39 @@
+/* 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 __GATT_SERVER_EVENTS_H__
+#define __GATT_SERVER_EVENTS_H__
+
+/*!
+    \brief
+    The base class used to abstract away the callback events that can be
+    triggered with the GATT Server.
+*/
+class GattServerEvents
+{
+public:
+    typedef enum gattEvent_e {
+        GATT_EVENT_DATA_SENT               = 1,  /**< Fired when a message was successfully sent out (notify only?) */
+        GATT_EVENT_DATA_WRITTEN            = 2,  /**< Client wrote data to the server (separate into char and descriptor writes?) */
+        GATT_EVENT_UPDATES_ENABLED         = 3,  /**< Notify/Indicate enabled in CCCD. */
+        GATT_EVENT_UPDATES_DISABLED        = 4,  /**< Notify/Indicate disabled in CCCD. */
+        GATT_EVENT_CONFIRMATION_RECEIVED   = 5,  /**< Response received from Indicate message. */
+        GATT_EVENT_READ_AUTHORIZATION_REQ  = 6,  /**< Request application to authorize read. */
+        GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7  /**< Request application to authorize write. */
+    } gattEvent_t;
+};
+
+#endif // ifndef __GATT_SERVER_EVENTS_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/GattService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,86 @@
+/* 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 __GATT_SERVICE_H__
+#define __GATT_SERVICE_H__
+
+#include "UUID.h"
+#include "GattCharacteristic.h"
+
+class GattService {
+public:
+    enum {
+        UUID_ALERT_NOTIFICATION_SERVICE     = 0x1811,
+        UUID_BATTERY_SERVICE                = 0x180F,
+        UUID_BLOOD_PRESSURE_SERVICE         = 0x1810,
+        UUID_CURRENT_TIME_SERVICE           = 0x1805,
+        UUID_CYCLING_SPEED_AND_CADENCE      = 0x1816,
+        UUID_DEVICE_INFORMATION_SERVICE     = 0x180A,
+        UUID_ENVIRONMENTAL_SERVICE          = 0x181A,
+        UUID_GLUCOSE_SERVICE                = 0x1808,
+        UUID_HEALTH_THERMOMETER_SERVICE     = 0x1809,
+        UUID_HEART_RATE_SERVICE             = 0x180D,
+        UUID_HUMAN_INTERFACE_DEVICE_SERVICE = 0x1812,
+        UUID_IMMEDIATE_ALERT_SERVICE        = 0x1802,
+        UUID_LINK_LOSS_SERVICE              = 0x1803,
+        UUID_NEXT_DST_CHANGE_SERVICE        = 0x1807,
+        UUID_PHONE_ALERT_STATUS_SERVICE     = 0x180E,
+        UUID_REFERENCE_TIME_UPDATE_SERVICE  = 0x1806,
+        UUID_RUNNING_SPEED_AND_CADENCE      = 0x1814,
+        UUID_SCAN_PARAMETERS_SERVICE        = 0x1813,
+        UUID_TX_POWER_SERVICE               = 0x1804
+    };
+
+public:
+    /**
+     *  @brief  Creates a new GattService using the specified 16-bit
+     *          UUID, value length, and properties.
+     *
+     *  @note   The UUID value must be unique and is normally >1.
+     *
+     *  @param[in]  uuid
+     *              The UUID to use for this service.
+     *  @param[in]  characteristics
+     *              A pointer to an array of characteristics to be included within this service.
+     *  @param[in]  numCharacteristics
+     *              The number of characteristics.
+     */
+    GattService(const UUID &uuid, GattCharacteristic *characteristics[], unsigned numCharacteristics) :
+        _primaryServiceID(uuid), _characteristicCount(numCharacteristics), _characteristics(characteristics), _handle(0) {
+        /* empty */
+    }
+
+    const UUID &getUUID(void)                const {return _primaryServiceID;   }
+    uint16_t    getHandle(void)              const {return _handle;             }
+    uint8_t     getCharacteristicCount(void) const {return _characteristicCount;}
+    void setHandle(uint16_t handle) {_handle = handle;}
+
+    GattCharacteristic *getCharacteristic(uint8_t index) {
+        if (index >= _characteristicCount) {
+            return NULL;
+        }
+
+        return _characteristics[index];
+    }
+
+private:
+    UUID                 _primaryServiceID;
+    uint8_t              _characteristicCount;
+    GattCharacteristic **_characteristics;
+    uint16_t             _handle;
+};
+
+#endif // ifndef __GATT_SERVICE_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/SafeBool.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,114 @@
+/* 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 BLE_API_SAFE_BOOL_H_
+#define BLE_API_SAFE_BOOL_H_
+
+//safe bool idiom, see : http://www.artima.com/cppsource/safebool.html
+
+namespace SafeBool_ {
+/**
+ * @brief Base class for all intances of SafeBool, 
+ * This base class reduce instantiation of trueTag function
+ */
+class base {
+  template<typename>
+  friend class SafeBool;
+
+protected:
+    //the bool type is a pointer to method which can be used in boolean context
+  typedef void (base::*BoolType_t)() const;
+
+  // non implemented call, use to disallow conversion between unrelated types 
+  void invalidTag() const;
+
+  // member function which indicate true value
+  void trueTag() const {}
+};
+
+
+}
+
+/**
+ * @brief template class SafeBool use CRTP to made boolean conversion easy and correct.
+ * Derived class should implement the function bool toBool() const to make this work. Inheritance 
+ * should be public.
+ *
+ * @tparam T Type of the derived class
+ * 
+ * \code 
+ * 
+ * class A : public SafeBool<A> { 
+ * public:
+ * 
+ *      // boolean conversion
+ *      bool toBool() { 
+ *      
+ *      }  
+ * };
+ * 
+ * class B : public SafeBool<B> { 
+ * public:
+ * 
+ *      // boolean conversion
+ *      bool toBool() const { 
+ *      
+ *      }  
+ * };
+ * 
+ * A a;
+ * B b;
+ * 
+ * // will compile 
+ * if(a) { 
+ * 
+ * }
+ * 
+ * // compilation error 
+ * if(a == b) { 
+ * 
+ * }
+ * 
+ * 
+ * \endcode
+ */
+template <typename T> 
+class SafeBool : public SafeBool_::base {
+public:
+  /** 
+   * bool operator implementation, derived class has to provide bool toBool() const function.
+   */
+  operator BoolType_t() const {
+    return (static_cast<const T*>(this))->toBool()
+      ? &SafeBool<T>::trueTag : 0;
+  }
+};
+
+//Avoid conversion to bool between different classes
+template <typename T, typename U>
+void operator==(const SafeBool<T>& lhs,const SafeBool<U>& rhs) {
+    lhs.invalidTag();
+//    return false;
+}
+
+//Avoid conversion to bool between different classes
+template <typename T,typename U>
+void operator!=(const SafeBool<T>& lhs,const SafeBool<U>& rhs) {
+  lhs.invalidTag();
+//  return false;
+}
+
+#endif /* BLE_API_SAFE_BOOL_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/SecurityManager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,331 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SECURITY_MANAGER_H__
+#define __SECURITY_MANAGER_H__
+
+#include <stdint.h>
+
+#include "Gap.h"
+#include "CallChainOfFunctionPointersWithContext.h"
+
+class SecurityManager {
+public:
+    enum SecurityMode_t {
+        SECURITY_MODE_NO_ACCESS,
+        SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< Require no protection, open link. */
+        SECURITY_MODE_ENCRYPTION_NO_MITM,   /**< Require encryption, but no MITM protection. */
+        SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< Require encryption and MITM protection. */
+        SECURITY_MODE_SIGNED_NO_MITM,       /**< Require signing or encryption, but no MITM protection. */
+        SECURITY_MODE_SIGNED_WITH_MITM,     /**< Require signing or encryption, and MITM protection. */
+    };
+
+    /**
+     * @brief Defines possible security status or states.
+     *
+     * @details Defines possible security status or states of a link when requested by getLinkSecurity().
+     */
+    enum LinkSecurityStatus_t {
+        NOT_ENCRYPTED,          /**< The link is not secured. */
+        ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
+        ENCRYPTED               /**< The link is secure.*/
+    };
+
+    enum SecurityIOCapabilities_t {
+      IO_CAPS_DISPLAY_ONLY     = 0x00,   /**< Display only. */
+      IO_CAPS_DISPLAY_YESNO    = 0x01,   /**< Display and yes/no entry. */
+      IO_CAPS_KEYBOARD_ONLY    = 0x02,   /**< Keyboard only. */
+      IO_CAPS_NONE             = 0x03,   /**< No I/O capabilities. */
+      IO_CAPS_KEYBOARD_DISPLAY = 0x04,   /**< Keyboard and display. */
+    };
+
+    enum SecurityCompletionStatus_t {
+        SEC_STATUS_SUCCESS              = 0x00,  /**< Procedure completed with success. */
+        SEC_STATUS_TIMEOUT              = 0x01,  /**< Procedure timed out. */
+        SEC_STATUS_PDU_INVALID          = 0x02,  /**< Invalid PDU received. */
+        SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81,  /**< Passkey entry failed (user canceled or other). */
+        SEC_STATUS_OOB_NOT_AVAILABLE    = 0x82,  /**< Out of Band Key not available. */
+        SEC_STATUS_AUTH_REQ             = 0x83,  /**< Authentication requirements not met. */
+        SEC_STATUS_CONFIRM_VALUE        = 0x84,  /**< Confirm value failed. */
+        SEC_STATUS_PAIRING_NOT_SUPP     = 0x85,  /**< Pairing not supported.  */
+        SEC_STATUS_ENC_KEY_SIZE         = 0x86,  /**< Encryption key size. */
+        SEC_STATUS_SMP_CMD_UNSUPPORTED  = 0x87,  /**< Unsupported SMP command. */
+        SEC_STATUS_UNSPECIFIED          = 0x88,  /**< Unspecified reason. */
+        SEC_STATUS_REPEATED_ATTEMPTS    = 0x89,  /**< Too little time elapsed since last attempt. */
+        SEC_STATUS_INVALID_PARAMS       = 0x8A,  /**< Invalid parameters. */
+    };
+
+    /**
+     * Declaration of type containing a passkey to be used during pairing. This
+     * is passed into initializeSecurity() to specify a pre-programmed passkey
+     * for authentication instead of generating a random one.
+     */
+    static const unsigned PASSKEY_LEN = 6;
+    typedef uint8_t Passkey_t[PASSKEY_LEN];         /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+
+public:
+    typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle);
+    typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps);
+    typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status);
+    typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode);
+    typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey);
+
+    typedef FunctionPointerWithContext<const SecurityManager *> SecurityManagerShutdownCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const SecurityManager *> SecurityManagerShutdownCallbackChain_t;
+
+    /*
+     * The following functions are meant to be overridden in the platform-specific sub-class.
+     */
+public:
+    /**
+     * Enable the BLE 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.
+     * Calling this API is a prerequisite for encryption and pairing (bonding).
+     *
+     * @param[in]  enableBonding Allow for bonding.
+     * @param[in]  requireMITM   Require protection for man-in-the-middle attacks.
+     * @param[in]  iocaps        To specify the I/O 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.
+     */
+    virtual ble_error_t init(bool                     enableBonding = true,
+                             bool                     requireMITM   = true,
+                             SecurityIOCapabilities_t iocaps        = IO_CAPS_NONE,
+                             const Passkey_t          passkey       = NULL) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)enableBonding;
+        (void)requireMITM;
+        (void)iocaps;
+        (void)passkey;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
+    }
+
+    /**
+     * Get the security status of a connection.
+     *
+     * @param[in]  connectionHandle   Handle to identify the connection.
+     * @param[out] securityStatusP    Security status.
+     *
+     * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
+     */
+    virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)securityStatusP;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
+    }
+
+    /**
+     * 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       Requested security mode.
+     *
+     * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
+     */
+    virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) {
+        /* Avoid compiler warnings about unused variables. */
+        (void)connectionHandle;
+        (void)securityMode;
+
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Delete all peer device context and all related bonding information from
+     * the database within the security manager.
+     *
+     * @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 or
+     *                                    application registration.
+     */
+    virtual ble_error_t purgeAllBondingState(void) {
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
+    }
+
+    /**
+     * Get a list of addresses from all peers in the bond table.
+     *
+     * @param[in/out]   addresses
+     *                  (on input) addresses.capacity contains the maximum
+     *                  number of addresses to be returned.
+     *                  (on output) The populated table with copies of the
+     *                  addresses in the implementation's whitelist.
+     *
+     * @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 or
+     *                                    application registration.
+     *
+     * @experimental
+     */
+    virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
+        /* Avoid compiler warnings about unused variables */
+        (void) addresses;
+
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */
+    }
+
+    /* Event callback handlers. */
+public:
+    /**
+     * Setup a callback to be invoked to notify the user application that the
+     * SecurityManager instance is about to shutdown (possibly as a result of a call
+     * to BLE::shutdown()).
+     *
+     * @Note: It is possible to chain together multiple onShutdown callbacks
+     * (potentially from different modules of an application) to be notified
+     * before the SecurityManager is shutdown.
+     *
+     * @Note: It is also possible to set up a callback into a member function of
+     * some object.
+     *
+     * @Note It is possible to unregister a callback using onShutdown().detach(callback)
+     */
+    void onShutdown(const SecurityManagerShutdownCallback_t& callback) {
+        shutdownCallChain.add(callback);
+    }
+    template <typename T>
+    void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
+        shutdownCallChain.add(objPtr, memberPtr);
+    }
+
+    /**
+     * @brief provide access to the callchain of shutdown event callbacks
+     * It is possible to register callbacks using onShutdown().add(callback);
+     * It is possible to unregister callbacks using onShutdown().detach(callback)
+     * @return The shutdown event callbacks chain
+     */
+    SecurityManagerShutdownCallbackChain_t& onShutdown() {
+        return shutdownCallChain;
+    }
+
+    /**
+     * To indicate that a security procedure for the link has started.
+     */
+    virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;}
+
+    /**
+     * To indicate that the security procedure for the link has completed.
+     */
+    virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;}
+
+    /**
+     * To indicate that the link with the peer is secured. For bonded devices,
+     * subsequent reconnections with a bonded peer will result only in this callback
+     * when the link is secured; setup procedures will not occur (unless the
+     * bonding information is either lost or deleted on either or both sides).
+     */
+    virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;}
+
+    /**
+     * To indicate that device context is stored persistently.
+     */
+    virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;}
+
+    /**
+     * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability.
+     */
+    virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;}
+
+    /* Entry points for the underlying stack to report events back to the user. */
+public:
+    void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) {
+        if (securitySetupInitiatedCallback) {
+            securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps);
+        }
+    }
+
+    void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) {
+        if (securitySetupCompletedCallback) {
+            securitySetupCompletedCallback(handle, status);
+        }
+    }
+
+    void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) {
+        if (linkSecuredCallback) {
+            linkSecuredCallback(handle, securityMode);
+        }
+    }
+
+    void processSecurityContextStoredEvent(Gap::Handle_t handle) {
+        if (securityContextStoredCallback) {
+            securityContextStoredCallback(handle);
+        }
+    }
+
+    void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) {
+        if (passkeyDisplayCallback) {
+            passkeyDisplayCallback(handle, passkey);
+        }
+    }
+
+protected:
+    SecurityManager() :
+        securitySetupInitiatedCallback(),
+        securitySetupCompletedCallback(),
+        linkSecuredCallback(),
+        securityContextStoredCallback(),
+        passkeyDisplayCallback() {
+        /* empty */
+    }
+
+public:
+    /**
+     * Notify all registered onShutdown callbacks that the SecurityManager is
+     * about to be shutdown and clear all SecurityManager state of the
+     * associated object.
+     *
+     * This function is meant to be overridden in the platform-specific
+     * sub-class. Nevertheless, the sub-class is only expected to reset its
+     * state and not the data held in SecurityManager members. This shall be
+     * achieved by a call to SecurityManager::reset() from the sub-class'
+     * reset() implementation.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t reset(void) {
+        /* Notify that the instance is about to shutdown */
+        shutdownCallChain.call(this);
+        shutdownCallChain.clear();
+
+        securitySetupInitiatedCallback = NULL;
+        securitySetupCompletedCallback = NULL;
+        linkSecuredCallback            = NULL;
+        securityContextStoredCallback  = NULL;
+        passkeyDisplayCallback         = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+protected:
+    SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback;
+    SecuritySetupCompletedCallback_t securitySetupCompletedCallback;
+    LinkSecuredCallback_t            linkSecuredCallback;
+    HandleSpecificEvent_t            securityContextStoredCallback;
+    PasskeyDisplayCallback_t         passkeyDisplayCallback;
+
+private:
+    SecurityManagerShutdownCallbackChain_t shutdownCallChain;
+};
+
+#endif /*__SECURITY_MANAGER_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/ServiceDiscovery.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,164 @@
+/* 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 __SERVICE_DISOVERY_H__
+#define __SERVICE_DISOVERY_H__
+
+#include "UUID.h"
+#include "Gap.h"
+#include "GattAttribute.h"
+
+class DiscoveredService;
+class DiscoveredCharacteristic;
+
+class ServiceDiscovery {
+public:
+    /*
+     * Exposed application callback types.
+     */
+
+    /**
+     * Callback type for when a matching service is found during service-
+     * discovery. The receiving function is passed in a pointer to a
+     * DiscoveredService object, which will remain valid for the lifetime of the
+     * callback. Memory for this object is owned by the BLE_API eventing
+     * framework. The application can safely make a persistent shallow-copy of
+     * this object to work with the service beyond the callback.
+     */
+    typedef FunctionPointerWithContext<const DiscoveredService *> ServiceCallback_t;
+
+    /**
+     * Callback type for when a matching characteristic is found during service-
+     * discovery. The receiving function is passed in a pointer to a
+     * DiscoveredCharacteristic object, which will remain valid for the lifetime
+     * of the callback. Memory for this object is owned by the BLE_API eventing
+     * framework. The application can safely make a persistent shallow-copy of
+     * this object to work with the characteristic beyond the callback.
+     */
+    typedef FunctionPointerWithContext<const DiscoveredCharacteristic *> CharacteristicCallback_t;
+
+    /**
+     * Callback type for when serviceDiscovery terminates.
+     */
+    typedef FunctionPointerWithContext<Gap::Handle_t> TerminationCallback_t;
+
+public:
+    /**
+     * Launch service discovery. Once launched, service discovery will remain
+     * active with callbacks being issued back into the application for matching
+     * services or characteristics. isActive() can be used to determine status, and
+     * a termination callback (if set up) will be invoked at the end. Service
+     * discovery can be terminated prematurely, if needed, using terminate().
+     *
+     * @param  connectionHandle
+     *           Handle for the connection with the peer.
+     * @param  sc
+     *           This is the application callback for a matching service. Taken as
+     *           NULL by default. Note: service discovery may still be active
+     *           when this callback is issued; calling asynchronous BLE-stack
+     *           APIs from within this application callback might cause the
+     *           stack to abort service discovery. If this becomes an issue, it
+     *           may be better to make a local copy of the discoveredService and
+     *           wait for service discovery to terminate before operating on the
+     *           service.
+     * @param  cc
+     *           This is the application callback for a matching characteristic.
+     *           Taken as NULL by default. Note: service discovery may still be
+     *           active when this callback is issued; calling asynchronous
+     *           BLE-stack APIs from within this application callback might cause
+     *           the stack to abort service discovery. If this becomes an issue,
+     *           it may be better to make a local copy of the discoveredCharacteristic
+     *           and wait for service discovery to terminate before operating on the
+     *           characteristic.
+     * @param  matchingServiceUUID
+     *           UUID-based filter for specifying a service in which the application is
+     *           interested. By default it is set as the wildcard UUID_UNKNOWN,
+     *           in which case it matches all services. If characteristic-UUID
+     *           filter (below) is set to the wildcard value, then a service
+     *           callback will be invoked for the matching service (or for every
+     *           service if the service filter is a wildcard).
+     * @param  matchingCharacteristicUUIDIn
+     *           UUID-based filter for specifying a characteristic in which the application
+     *           is interested. By default it is set as the wildcard UUID_UKNOWN
+     *           to match against any characteristic. If both service-UUID
+     *           filter and characteristic-UUID filter are used with non-wildcard
+     *           values, then only a single characteristic callback is
+     *           invoked for the matching characteristic.
+     *
+     * @note     Using wildcard values for both service-UUID and characteristic-
+     *           UUID will result in complete service discovery: callbacks being
+     *           called for every service and characteristic.
+     *
+     * @note     Providing NULL for the characteristic callback will result in
+     *           characteristic discovery being skipped for each matching
+     *           service. This allows for an inexpensive method to discover only
+     *           services.
+     *
+     * @return
+     *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+     */
+    virtual ble_error_t launch(Gap::Handle_t             connectionHandle,
+                               ServiceCallback_t         sc = NULL,
+                               CharacteristicCallback_t  cc = NULL,
+                               const UUID               &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+                               const UUID               &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0;
+
+    /**
+     * Is service-discovery currently active?
+     */
+    virtual bool        isActive(void) const = 0;
+
+    /**
+     * Terminate an ongoing service discovery. This should result in an
+     * invocation of the TerminationCallback if service discovery is active.
+     */
+    virtual void        terminate(void) = 0;
+
+    /**
+     * Set up a callback to be invoked when service discovery is terminated.
+     */
+    virtual void        onTermination(TerminationCallback_t callback) = 0;
+
+    /**
+     * Clear all ServiceDiscovery state of the associated object.
+     *
+     * This function is meant to be overridden in the platform-specific
+     * sub-class. Nevertheless, the sub-class is only expected to reset its
+     * state and not the data held in ServiceDiscovery members. This shall be
+     * achieved by a call to ServiceDiscovery::reset() from the sub-class'
+     * reset() implementation.
+     *
+     * @return BLE_ERROR_NONE on success.
+     */
+    virtual ble_error_t reset(void) {
+        connHandle                 = 0;
+        matchingServiceUUID        = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN);
+        serviceCallback            = NULL;
+        matchingCharacteristicUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN);
+        characteristicCallback     = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+protected:
+    Gap::Handle_t            connHandle; /**< Connection handle as provided by the SoftDevice. */
+    UUID                     matchingServiceUUID;
+    ServiceCallback_t        serviceCallback;
+    UUID                     matchingCharacteristicUUID;
+    CharacteristicCallback_t characteristicCallback;
+};
+
+#endif // ifndef __SERVICE_DISOVERY_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/UUID.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,227 @@
+/* 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 __UUID_H__
+#define __UUID_H__
+
+#include <stdint.h>
+#include <string.h>
+#include <algorithm>
+
+#include "blecommon.h"
+
+/**
+ * A trivial converter for single hexadecimal character to unsigned-int.
+ * @param  c hexadecimal character.
+ * @return   the corresponding value as unsigned int.
+ */
+static uint8_t char2int(char c) {
+    if ((c >= '0') && (c <= '9')) {
+        return c - '0';
+    } else if ((c >= 'a') && (c <= 'f')) {
+        return c - 'a' + 10;
+    } else if ((c >= 'A') && (c <= 'F')) {
+        return c - 'A' + 10;
+    } else {
+        return 0;
+    }
+}
+
+class UUID {
+public:
+    enum UUID_Type_t {
+        UUID_TYPE_SHORT = 0,    // Short BLE UUID.
+        UUID_TYPE_LONG  = 1     // Full 128-bit UUID.
+    };
+
+    /**
+     * An enumeration to specify byte ordering of the long version of the UUID.
+     */
+    typedef enum {
+        MSB, /*!< Most-significant byte first (at the smallest address) */
+        LSB  /*!< least-significant byte first (at the smallest address) */
+    } ByteOrder_t;
+
+    typedef uint16_t      ShortUUIDBytes_t;
+
+    static const unsigned LENGTH_OF_LONG_UUID = 16;
+    typedef uint8_t       LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
+
+    static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4;
+
+public:
+
+    /**
+     * Creates a new 128-bit UUID.
+     *
+     * @note   The UUID is a unique 128-bit (16 byte) ID used to identify
+     *         different service or characteristics on the BLE device.
+     *
+     * @param  stringUUID
+     *          The 128-bit (16-byte) UUID as a human readable const-string.
+     *          Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+     *          Upper and lower case supported. Hyphens are optional, but only
+     *          upto four of them. The UUID is stored internally as a 16 byte
+     *          array, LSB (little endian), which is opposite from the string.
+     */
+    UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
+        bool nibble = false;
+        uint8_t byte = 0;
+        size_t baseIndex = 0;
+        uint8_t tempUUID[LENGTH_OF_LONG_UUID];
+
+        // Iterate through string, abort if NULL is encountered prematurely.
+        // Ignore upto four hyphens.
+        for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) {
+            if (stringUUID[index] == '\0') {
+                // error abort
+                break;
+            } else if (stringUUID[index] == '-') {
+                // ignore hyphen
+                continue;
+            } else if (nibble) {
+                // got second nibble
+                byte |= char2int(stringUUID[index]);
+                nibble = false;
+
+                // store copy
+                tempUUID[baseIndex++] = byte;
+            } else {
+                // got first nibble
+                byte = char2int(stringUUID[index]) << 4;
+                nibble = true;
+            }
+        }
+
+        // populate internal variables if string was successfully parsed
+        if (baseIndex == LENGTH_OF_LONG_UUID) {
+            setupLong(tempUUID, UUID::MSB);
+        } else {
+            const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+                                    0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
+            setupLong(sig, UUID::MSB);
+        }
+    }
+
+    /**
+     * Creates a new 128-bit UUID.
+     *
+     * @note   The UUID is a unique 128-bit (16 byte) ID used to identify
+     *         different service or characteristics on the BLE device.
+     *
+     * @param longUUID
+     *          The 128-bit (16-byte) UUID value.
+     * @param order
+     *          The bit order of the UUID, MSB by default.
+     */
+    UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) {
+        setupLong(longUUID, order);
+    }
+
+    /**
+     * Creates a new 16-bit UUID.
+     *
+     * @note The UUID is a unique 16-bit (2 byte) ID used to identify
+     *       different service or characteristics on the BLE device.
+     *
+     * For efficiency, and because 16 bytes would take a large chunk of the
+     * 27-byte data payload length of the Link Layer, the BLE specification adds
+     * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened
+     * formats can be used only with UUIDs that are defined in the Bluetooth
+     * specification (listed by the Bluetooth SIG as standard
+     * Bluetooth UUIDs).
+     *
+     * To reconstruct the full 128-bit UUID from the shortened version, insert
+     * the 16-bit short value (indicated by xxxx, including leading zeros) into
+     * the Bluetooth Base UUID:
+     *
+     *  0000xxxx-0000-1000-8000-00805F9B34FB
+     *
+     * @note Shortening is not available for UUIDs that are not derived from the
+     *       Bluetooth Base UUID. Such non-standard UUIDs are commonly called
+     *       vendor-specific UUIDs. In these cases, you'll need to use the full
+     *       128-bit UUID value at all times.
+     *
+     * @note We don't yet support 32-bit shortened UUIDs.
+     */
+    UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) {
+        /* Empty */
+    }
+
+    UUID(const UUID &source) {
+        type      = source.type;
+        shortUUID = source.shortUUID;
+        memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID);
+    }
+
+    UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) {
+        /* empty */
+    }
+
+    /**
+     * Fill in a 128-bit UUID; this is useful when the UUID isn't known at the time of the object construction.
+     */
+    void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) {
+        type      = UUID_TYPE_LONG;
+        if (order == UUID::MSB) {
+            // Switch endian. Input is big-endian, internal representation is little endian.
+            std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
+        } else {
+            std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID);
+        }
+        shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12]));
+    }
+
+public:
+    UUID_Type_t       shortOrLong(void)  const {return type;     }
+    const uint8_t    *getBaseUUID(void)  const {
+        if (type == UUID_TYPE_SHORT) {
+            return (const uint8_t*)&shortUUID;
+        } else {
+            return baseUUID;
+        }
+    }
+
+    ShortUUIDBytes_t  getShortUUID(void) const {return shortUUID;}
+    uint8_t           getLen(void)       const {
+        return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID);
+    }
+
+    bool operator== (const UUID &other) const {
+        if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) &&
+            (this->shortUUID == other.shortUUID)) {
+            return true;
+        }
+
+        if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) &&
+            (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    bool operator!= (const UUID &other) const {
+        return !(*this == other);
+    }
+
+private:
+    UUID_Type_t      type;      // UUID_TYPE_SHORT or UUID_TYPE_LONG
+    LongUUIDBytes_t  baseUUID;  // The long UUID
+    ShortUUIDBytes_t shortUUID; // 16 bit UUID
+};
+
+#endif // ifndef __UUID_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/blecommon.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,81 @@
+/* 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 __BLE_COMMON_H__
+#define __BLE_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*! @brief Assigned values for BLE UUIDs. */
+enum {
+    BLE_UUID_UNKNOWN                             = 0x0000, /**< Reserved UUID. */
+    BLE_UUID_SERVICE_PRIMARY                     = 0x2800, /**< Primary Service. */
+    BLE_UUID_SERVICE_SECONDARY                   = 0x2801, /**< Secondary Service. */
+    BLE_UUID_SERVICE_INCLUDE                     = 0x2802, /**< Include. */
+    BLE_UUID_CHARACTERISTIC                      = 0x2803, /**< Characteristic. */
+    BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP            = 0x2900, /**< Characteristic Extended Properties Descriptor. */
+    BLE_UUID_DESCRIPTOR_CHAR_USER_DESC           = 0x2901, /**< Characteristic User Description Descriptor. */
+    BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG       = 0x2902, /**< Client Characteristic Configuration Descriptor. */
+    BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG       = 0x2903, /**< Server Characteristic Configuration Descriptor. */
+    BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT = 0x2904, /**< Characteristic Presentation Format Descriptor. */
+    BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT    = 0x2905, /**< Characteristic Aggregate Format Descriptor. */
+
+/* GATT specific UUIDs */
+    BLE_UUID_GATT                                = 0x1801, /**< Generic Attribute Profile. */
+    BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED = 0x2A05, /**< Service Changed Characteristic. */
+
+/* GAP specific UUIDs */
+    BLE_UUID_GAP                                 = 0x1800, /**< Generic Access Profile. */
+    BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME      = 0x2A00, /**< Device Name Characteristic. */
+    BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE       = 0x2A01, /**< Appearance Characteristic. */
+    BLE_UUID_GAP_CHARACTERISTIC_PPF              = 0x2A02, /**< Peripheral Privacy Flag Characteristic. */
+    BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR      = 0x2A03, /**< Reconnection Address Characteristic. */
+    BLE_UUID_GAP_CHARACTERISTIC_PPCP             = 0x2A04, /**< Peripheral Preferred Connection Parameters Characteristic. */
+};
+
+/*! @brief Error codes for the BLE API. */
+enum ble_error_t {
+    BLE_ERROR_NONE                      = 0, /**< No error. */
+    BLE_ERROR_BUFFER_OVERFLOW           = 1, /**< The requested action would cause a buffer overflow and has been aborted. */
+    BLE_ERROR_NOT_IMPLEMENTED           = 2, /**< Requested a feature that isn't yet implemented or isn't supported by the target HW. */
+    BLE_ERROR_PARAM_OUT_OF_RANGE        = 3, /**< One of the supplied parameters is outside the valid range. */
+    BLE_ERROR_INVALID_PARAM             = 4, /**< One of the supplied parameters is invalid. */
+    BLE_STACK_BUSY                      = 5, /**< The stack is busy. */
+    BLE_ERROR_INVALID_STATE             = 6, /**< Invalid state. */
+    BLE_ERROR_NO_MEM                    = 7, /**< Out of memory */
+    BLE_ERROR_OPERATION_NOT_PERMITTED   = 8,
+    BLE_ERROR_INITIALIZATION_INCOMPLETE = 9,
+    BLE_ERROR_ALREADY_INITIALIZED       = 10,
+    BLE_ERROR_UNSPECIFIED               = 11, /**< Unknown error. */
+    BLE_ERROR_INTERNAL_STACK_FAILURE    = 12, /**< The platform-specific stack failed */
+};
+
+/** @brief Default MTU size. */
+static const unsigned BLE_GATT_MTU_SIZE_DEFAULT = 23;
+
+enum HVXType_t {
+    BLE_HVX_NOTIFICATION = 0x01,  /**< Handle Value Notification. */
+    BLE_HVX_INDICATION   = 0x02,  /**< Handle Value Indication. */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ifndef __BLE_COMMON_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/deprecate.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,26 @@
+/* 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 __DEPRECATE_H__
+#define __DEPRECATE_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+	#include "compiler-polyfill/attributes.h"
+#else
+	#define __deprecated_message(msg)
+#endif
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/BatteryService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,66 @@
+/* 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 __BLE_BATTERY_SERVICE_H__
+#define __BLE_BATTERY_SERVICE_H__
+
+#include "ble/BLE.h"
+
+/**
+* @class BatteryService
+* @brief BLE Battery Service. This service displays the battery level from 0% to 100%, represented as an 8bit number.
+* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml
+* Battery Level Char:  https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml
+*/
+class BatteryService {
+public:
+    /**
+     * @param[ref] _ble
+     *               BLE object for the underlying controller.
+     * @param[in] level
+     *               8bit batterly level. Usually used to represent percentage of batterly charge remaining.
+     */
+    BatteryService(BLE &_ble, uint8_t level = 100) :
+        ble(_ble),
+        batteryLevel(level),
+        batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) {
+
+        GattCharacteristic *charTable[] = {&batteryLevelCharacteristic};
+        GattService         batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(batteryService);
+    }
+
+    /**
+     * @brief Update the battery level with a new value. [Valid values lie between 0 and 100];
+     * anything outside this range will be ignored.
+     *
+     * @param newLevel
+     *              Update to battery level.
+     */
+    void updateBatteryLevel(uint8_t newLevel) {
+        batteryLevel = newLevel;
+        ble.gattServer().write(batteryLevelCharacteristic.getValueHandle(), &batteryLevel, 1);
+    }
+
+protected:
+    BLE &ble;
+
+    uint8_t    batteryLevel;
+    ReadOnlyGattCharacteristic<uint8_t> batteryLevelCharacteristic;
+};
+
+#endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/DFUService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
+ */
+
+#ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */
+
+#ifndef __BLE_DFU_SERVICE_H__
+#define __BLE_DFU_SERVICE_H__
+
+#include "ble/BLE.h"
+#include "ble/UUID.h"
+
+extern "C" {
+#include "dfu_app_handler.h"
+}
+
+extern const uint8_t  DFUServiceBaseUUID[];
+extern const uint16_t DFUServiceShortUUID;
+extern const uint16_t DFUServiceControlCharacteristicShortUUID;
+
+extern const uint8_t  DFUServiceUUID[];
+extern const uint8_t  DFUServiceControlCharacteristicUUID[];
+extern const uint8_t  DFUServicePacketCharacteristicUUID[];
+
+/**
+* @class DFUService
+* @brief Device Firmware Update Service.
+*/
+class DFUService {
+public:
+    /**
+     * @brief Signature for the handover callback. The application may provide this
+     * callback when setting up the DFU service. The callback is then
+     * invoked before handing control over to the bootloader.
+     */
+    typedef void (*ResetPrepare_t)(void);
+
+public:
+    /**
+    * @brief Adds Device Firmware Update Service to an existing BLE object.
+    *
+    * @param[ref] _ble
+    *               BLE object for the underlying controller.
+    * @param[in] _handoverCallback
+    *                Application-specific handover callback.
+    */
+    DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) :
+        ble(_ble),
+        controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+        packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES,
+               GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
+        controlBytes(),
+        packetBytes() {
+        static bool serviceAdded = false; /* We only add the DFU service once. */
+        if (serviceAdded) {
+            return;
+        }
+
+        /* Set an initial value for control bytes, so that the application's DFU service can
+         * be distinguished from the real DFU service provided by the bootloader. */
+        controlBytes[0] = 0xFF;
+        controlBytes[1] = 0xFF;
+
+        GattCharacteristic *dfuChars[] = {&controlPoint, &packet};
+        GattService         dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *));
+
+        ble.addService(dfuService);
+        handoverCallback = _handoverCallback;
+        serviceAdded     = true;
+
+        ble.onDataWritten(this, &DFUService::onDataWritten);
+    }
+
+    /**
+    * @brief Get the handle for the value attribute of the control characteristic.
+    */
+    uint16_t getControlHandle(void) const {
+        return controlPoint.getValueHandle();
+    }
+
+    /**
+     * @brief This callback allows the DFU service to receive the initial trigger to
+     * hand control over to the bootloader. First, the application is given a
+     * chance to clean up.
+     *
+     * @param[in] params
+     *     Information about the characterisitc being updated.
+     */
+    virtual void onDataWritten(const GattWriteCallbackParams *params) {
+        if (params->handle == controlPoint.getValueHandle()) {
+            /* At present, writing anything will do the trick - this needs to be improved. */
+            if (handoverCallback) {
+                handoverCallback();
+            }
+
+            // Call bootloader_start implicitly trough a event handler call
+            // it is a work around for bootloader_start not being public in sdk 8.1
+            ble_dfu_t p_dfu;
+            ble_dfu_evt_t p_evt;
+
+            p_dfu.conn_handle = params->connHandle;
+            p_evt.ble_dfu_evt_type = BLE_DFU_START;
+
+            dfu_app_on_dfu_evt(&p_dfu, &p_evt);
+        }
+    }
+
+protected:
+    static const unsigned SIZEOF_CONTROL_BYTES = 2;
+    static const unsigned SIZEOF_PACKET_BYTES  = 20;
+
+protected:
+    BLE          &ble;
+
+    /**< Writing to the control characteristic triggers the handover to DFU 
+      *  bootloader. At present, writing anything will do the trick - this needs
+      *  to be improved. */
+    WriteOnlyArrayGattCharacteristic<uint8_t, SIZEOF_CONTROL_BYTES> controlPoint;
+
+    /**< The packet characteristic in this service doesn't do anything meaningful;
+      *  it is only a placeholder to mimic the corresponding characteristic in the
+      *  actual DFU service implemented by the bootloader. Without this, some
+      *  FOTA clients might get confused, because service definitions change after
+      *  handing control over to the bootloader. */
+    GattCharacteristic  packet;
+
+    uint8_t             controlBytes[SIZEOF_CONTROL_BYTES];
+    uint8_t             packetBytes[SIZEOF_PACKET_BYTES];
+
+    static ResetPrepare_t handoverCallback;  /**< Application-specific handover callback. */
+};
+
+#endif /* #ifndef __BLE_DFU_SERVICE_H__*/
+#endif /* #ifdef TARGET_NRF51822 */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/DeviceInformationService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,116 @@
+/* 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 __BLE_DEVICE_INFORMATION_SERVICE_H__
+#define __BLE_DEVICE_INFORMATION_SERVICE_H__
+
+#include "ble/BLE.h"
+
+/**
+* @class DeviceInformationService
+* @brief BLE Device Information Service
+* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml
+* Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml
+*/
+class DeviceInformationService {
+public:
+    /**
+     * @brief Device Information Service Constructor: copies device-specific information 
+     * into the BLE stack.
+     *
+     * @param[ref] _ble
+     *                BLE object for the underlying controller.
+     * @param[in] manufacturersName
+     *                The name of the manufacturer of the device.
+     * @param[in] modelNumber
+     *                The model number that is assigned by the device vendor.
+     * @param[in] serialNumber
+     *                The serial number for a particular instance of the device. 
+     * @param[in] hardwareRevision
+     *                The hardware revision for the hardware within the device.
+     * @param[in] firmwareRevision
+     *                The device's firmware version. 
+     * @param[in] softwareRevision
+     *                The device's software version.
+     */
+    DeviceInformationService(BLE        &_ble,
+                             const char *manufacturersName = NULL,
+                             const char *modelNumber       = NULL,
+                             const char *serialNumber      = NULL,
+                             const char *hardwareRevision  = NULL,
+                             const char *firmwareRevision  = NULL,
+                             const char *softwareRevision  = NULL) :
+        ble(_ble),
+        manufacturersNameStringCharacteristic(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR,
+                                              (uint8_t *)manufacturersName,
+                                              (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Min length */
+                                              (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Max length */
+                                              GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+        modelNumberStringCharacteristic(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR,
+                                        (uint8_t *)modelNumber,
+                                        (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Min length */
+                                        (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Max length */
+                                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+        serialNumberStringCharacteristic(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR,
+                                         (uint8_t *)serialNumber,
+                                         (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Min length */
+                                         (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Max length */
+                                         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+        hardwareRevisionStringCharacteristic(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR,
+                                             (uint8_t *)hardwareRevision,
+                                             (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Min length */
+                                             (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Max length */
+                                             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+        firmwareRevisionStringCharacteristic(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR,
+                                             (uint8_t *)firmwareRevision,
+                                             (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Min length */
+                                             (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Max length */
+                                             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+        softwareRevisionStringCharacteristic(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR,
+                                             (uint8_t *)softwareRevision,
+                                             (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Min length */
+                                             (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Max length */
+                                             GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)
+    {
+        static bool serviceAdded = false; /* We only add the information service once. */
+        if (serviceAdded) {
+            return;
+        }
+
+        GattCharacteristic *charTable[] = {&manufacturersNameStringCharacteristic,
+                                           &modelNumberStringCharacteristic,
+                                           &serialNumberStringCharacteristic,
+                                           &hardwareRevisionStringCharacteristic,
+                                           &firmwareRevisionStringCharacteristic,
+                                           &softwareRevisionStringCharacteristic};
+        GattService         deviceInformationService(GattService::UUID_DEVICE_INFORMATION_SERVICE, charTable,
+                                                     sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(deviceInformationService);
+        serviceAdded = true;
+    }
+
+protected:
+    BLE                &ble;
+    GattCharacteristic  manufacturersNameStringCharacteristic;
+    GattCharacteristic  modelNumberStringCharacteristic;
+    GattCharacteristic  serialNumberStringCharacteristic;
+    GattCharacteristic  hardwareRevisionStringCharacteristic;
+    GattCharacteristic  firmwareRevisionStringCharacteristic;
+    GattCharacteristic  softwareRevisionStringCharacteristic;
+};
+
+#endif /* #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/EddystoneConfigService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,542 @@
+/* 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 SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
+#define SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
+
+#warning ble/services/EddystoneConfigService.h is deprecated. Please use the example in 'github.com/ARMmbed/ble-examples/tree/master/BLE_EddystoneService'.
+
+#include "mbed.h"
+#include "ble/BLE.h"
+#include "ble/services/EddystoneService.h"
+
+#define UUID_URI_BEACON(FIRST, SECOND) {                         \
+        0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba,       \
+        0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8,          \
+}
+
+static const uint8_t UUID_URI_BEACON_SERVICE[]    = UUID_URI_BEACON(0x20, 0x80);
+static const uint8_t UUID_LOCK_STATE_CHAR[]       = UUID_URI_BEACON(0x20, 0x81);
+static const uint8_t UUID_LOCK_CHAR[]             = UUID_URI_BEACON(0x20, 0x82);
+static const uint8_t UUID_UNLOCK_CHAR[]           = UUID_URI_BEACON(0x20, 0x83);
+static const uint8_t UUID_URI_DATA_CHAR[]         = UUID_URI_BEACON(0x20, 0x84);
+static const uint8_t UUID_FLAGS_CHAR[]            = UUID_URI_BEACON(0x20, 0x85);
+static const uint8_t UUID_ADV_POWER_LEVELS_CHAR[] = UUID_URI_BEACON(0x20, 0x86);
+static const uint8_t UUID_TX_POWER_MODE_CHAR[]    = UUID_URI_BEACON(0x20, 0x87);
+static const uint8_t UUID_BEACON_PERIOD_CHAR[]    = UUID_URI_BEACON(0x20, 0x88);
+static const uint8_t UUID_RESET_CHAR[]            = UUID_URI_BEACON(0x20, 0x89);
+extern const uint8_t BEACON_EDDYSTONE[2];
+
+/**
+* @class EddystoneConfigService
+* @brief Eddystone Configuration Service. Used to set URL, adjust power levels, and set flags.
+* See https://github.com/google/eddystone
+*
+*/
+class EddystoneConfigService
+{
+public:
+    /**
+     * @brief Transmission Power Modes for UriBeacon
+     */
+    enum {
+        TX_POWER_MODE_LOWEST,
+        TX_POWER_MODE_LOW,
+        TX_POWER_MODE_MEDIUM,
+        TX_POWER_MODE_HIGH,
+        NUM_POWER_MODES
+    };
+
+    static const unsigned ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service.
+    static const unsigned SERVICE_DATA_MAX          = 31;   // Maximum size of service data in ADV packets.
+
+    typedef uint8_t Lock_t[16];                             /* 128 bits. */
+    typedef int8_t PowerLevels_t[NUM_POWER_MODES];
+
+    // There are currently three subframes defined: URI, UID, and TLM.
+#define EDDYSTONE_MAX_FRAMETYPE 3
+    static const unsigned URI_DATA_MAX = 18;
+    typedef uint8_t UriData_t[URI_DATA_MAX];
+
+    // UID Frame Type subfields.
+    static const size_t UID_NAMESPACEID_SIZE = 10;
+    typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
+    static const size_t UID_INSTANCEID_SIZE = 6;
+    typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE];
+
+    // Eddystone Frame Type ID.
+    static const uint8_t FRAME_TYPE_UID = 0x00;
+    static const uint8_t FRAME_TYPE_URL = 0x10;
+    static const uint8_t FRAME_TYPE_TLM = 0x20;
+
+    static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14B.
+    static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes.
+
+    struct Params_t {
+        // Config Data
+        bool             isConfigured; // Flag for configuration being complete:
+                                       //   True = configured, False = not configured. Reset at instantiation, used for external callbacks.
+        uint8_t          lockedState;
+        Lock_t           lock;
+        uint8_t          flags;
+        PowerLevels_t    advPowerLevels;  // Current value of AdvertisedPowerLevels.
+        uint8_t          txPowerMode;     // Firmware power levels used with setTxPower().
+        uint16_t         beaconPeriod;
+        // TLM Frame Data
+        uint8_t          tlmVersion;      // Version of TLM packet.
+        bool             tlmEnabled;
+        float            tlmBeaconPeriod; // How often to broadcat TLM frame, in seconds.
+        // URI Frame Data
+        uint8_t          uriDataLength;
+        UriData_t        uriData;
+        bool             uriEnabled;
+        float            uriBeaconPeriod; // How often to broadcast URIFrame, in seconds.
+        // UID Frame Data
+        UIDNamespaceID_t uidNamespaceID;  // UUID type, Namespace ID, 10B.
+        UIDInstanceID_t  uidInstanceID;   // UUID type, Instance ID, 6B.
+        bool             uidEnabled;
+        float            uidBeaconPeriod; // How often to broadcast UID Frame, in seconds.
+    };
+
+    /**
+     * @param[ref]    ble
+     *                    BLEDevice object for the underlying controller.
+     * @param[in/out] paramsIn
+     *                    Reference to application-visible beacon state, loaded
+     *                    from persistent storage at startup.
+     * @param[in]     defaultAdvPowerLevelsIn
+     *                    Default power-levels array; applies only if resetToDefaultsFlag is true.
+     */
+    EddystoneConfigService(BLEDevice     &bleIn,
+                           Params_t      &paramsIn,
+                           PowerLevels_t &defaultAdvPowerLevelsIn,
+                           PowerLevels_t &radioPowerLevelsIn) :
+        ble(bleIn),
+        params(paramsIn),       // Initialize URL data.
+        defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
+        radioPowerLevels(radioPowerLevelsIn),
+        initSucceeded(false),
+        resetFlag(),
+        defaultUidNamespaceID(), // Initialize UID data.
+        defaultUidInstanceID(),
+        defaultUidPower(defaultAdvPowerLevelsIn[params.txPowerMode]),
+        uidIsSet(false),
+        defaultUriDataLength(),
+        defaultUriData(),
+        defaultUrlPower(defaultAdvPowerLevelsIn[params.txPowerMode]),
+        urlIsSet(false),
+        tlmIsSet(false),
+        lockedStateChar(UUID_LOCK_STATE_CHAR, &params.lockedState),
+        lockChar(UUID_LOCK_CHAR, &params.lock),
+        uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
+                    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
+        unlockChar(UUID_UNLOCK_CHAR, &params.lock),
+        flagsChar(UUID_FLAGS_CHAR, &params.flags),
+        advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, &params.advPowerLevels),
+        txPowerModeChar(UUID_TX_POWER_MODE_CHAR, &params.txPowerMode),
+        beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, &params.beaconPeriod),
+        resetChar(UUID_RESET_CHAR, &resetFlag) {
+        // Set Eddystone as not configured yet. Used to exit config before timeout if GATT services are written to.
+        params.isConfigured = false;
+
+        lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback);
+        unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback);
+        uriDataChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::uriDataWriteAuthorizationCallback);
+        flagsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
+        advPowerLevelsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<PowerLevels_t>);
+        txPowerModeChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::powerModeAuthorizationCallback);
+        beaconPeriodChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint16_t>);
+        resetChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
+
+        static GattCharacteristic *charTable[] = {
+            &lockedStateChar, &lockChar, &unlockChar, &uriDataChar,
+            &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar
+        };
+
+        GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(configService);
+        ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback);
+    }
+
+    /**
+     * @brief Start EddystoneConfig advertising. This function should be called
+     * after the EddystoneConfig constructor and after all the frames have been added.
+     *
+     * @paramsP[in]   resetToDefaultsFlag
+     *                    Applies to the state of the 'paramsIn' parameter.
+     *                    If true, it indicates that paramsIn is potentially
+     *                    un-initialized, and default values should be used
+     *                    instead. Otherwise, paramsIn overrides the defaults.
+     */
+    void start(bool resetToDefaultsFlag){
+        INFO("reset to defaults flag = %d", resetToDefaultsFlag);
+        if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) {
+            INFO("Reset to Defaults triggered");
+            resetToDefaultsFlag = true;
+        }
+
+        if (resetToDefaultsFlag) {
+            resetToDefaults();
+        } else {
+            updateCharacteristicValues();
+        }
+
+        setupEddystoneConfigAdvertisements(); /* Set up advertising for the config service. */
+        initSucceeded = true;
+    }
+
+    /*
+    * Check if Eddystone initialized successfully.
+    */
+    bool initSuccessfully(void) const {
+        return initSucceeded;
+    }
+
+    /*
+    * @brief Function to update the default values for the TLM frame. Only applied if Reset Defaults is applied.
+    *
+    * @param[in] tlmVersionIn     Version of the TLM frame being used.
+    * @param[in] advPeriodInMin How long between TLM frames being advertised, measured in minutes.
+    *
+    */
+    void setDefaultTLMFrameData(uint8_t tlmVersionIn = 0, float advPeriodInSec = 60){
+        DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f", tlmVersionIn, advPeriodInSec);
+        defaultTlmVersion   = tlmVersionIn;
+        TlmBatteryVoltage   = 0;
+        TlmBeaconTemp       = 0x8000;
+        TlmPduCount         = 0;
+        TlmTimeSinceBoot    = 0;
+        defaultTlmAdvPeriod = advPeriodInSec;
+        tlmIsSet            = true; // Flag to add this to Eddystone service when config is done.
+    }
+
+    /*
+    * @brief Function to update the default values for the URI frame. Only applied if Reset Defaults is applied.
+    *
+    * @param[in] uriIn      URL to advertise.
+    * @param[in] advPeriod  How long to advertise the URL, measured in number of ADV frames.
+    *
+    */
+    void setDefaultURIFrameData(const char *uriIn, float advPeriod = 1){
+        DBG("Setting Default URI Data");
+        // Set URL Frame
+        EddystoneService::encodeURL(uriIn, defaultUriData, defaultUriDataLength);   // Encode URL to URL Formatting.
+        if (defaultUriDataLength > URI_DATA_MAX) {
+            return;
+        }
+        INFO("\t  URI input = %s : %d", uriIn, defaultUriDataLength);
+        INFO("\t default URI = %s : %d ", defaultUriData, defaultUriDataLength );
+        defaultUriAdvPeriod = advPeriod;
+        urlIsSet            = true; // Flag to add this to Eddystone service when config is done.
+    }
+
+    /*
+    * @brief Function to update the default values for the UID frame. Only applied if Reset Defaults is applied.
+    *
+    * @param[in] namespaceID 10Byte Namespace ID.
+    * @param[in] instanceID  6Byte Instance ID.
+    * @param[in] advPeriod   How long to advertise the URL, measured in the number of ADV frames.
+    *
+    */
+    void setDefaultUIDFrameData(UIDNamespaceID_t *namespaceID, UIDInstanceID_t *instanceID, float advPeriod = 10){
+        //Set UID frame
+        DBG("Setting default UID Data");
+        memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
+        memcpy(defaultUidInstanceID,  instanceID,  UID_INSTANCEID_SIZE);
+        defaultUidAdvPeriod = advPeriod;
+        uidIsSet            = true; // Flag to add this to Eddystone service when config is done.
+    }
+
+    /* Start out by advertising the config service for a limited time after
+     * startup, then switch to the normal non-connectible beacon functionality.
+     */
+    void setupEddystoneConfigAdvertisements() {
+        const char DEVICE_NAME[] = "eddystone Config";
+
+        ble.clearAdvertisingPayload();
+
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+
+        // UUID is in a different order in the ADV frame (!)
+        uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
+        for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
+            reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
+        }
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID));
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
+        ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME));
+        ble.accumulateScanResponse(
+            GapAdvertisingData::TX_POWER_LEVEL,
+            reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[EddystoneConfigService::TX_POWER_MODE_LOW]),
+            sizeof(uint8_t));
+
+        ble.setTxPower(radioPowerLevels[params.txPowerMode]);
+        ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
+        ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+        ble.setAdvertisingInterval(ADVERTISING_INTERVAL_MSEC);
+    }
+
+    /*
+    *   This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function
+    *   to load saved config params, or it can be called explicitly to reset the Eddystone beacon to hardcoded values on each reset.
+    *
+    */
+    void setupEddystoneAdvertisements() {
+        DBG("Switching Config -> adv");
+        // Save params to storage.
+        extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */
+        saveURIBeaconConfigParams(&params);
+        INFO("Saved Params to Memory.")
+        // Set up Eddystone Service.
+        static EddystoneService eddyServ(ble, params.beaconPeriod, radioPowerLevels[params.txPowerMode]);
+        // Set configured frames (TLM, UID, URI and so on).
+        if (params.tlmEnabled) {
+            eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod);
+        }
+        if (params.uriEnabled) {
+            eddyServ.setURLFrameEncodedData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriDataLength, params.uriBeaconPeriod);
+        }
+        if (params.uidEnabled) {
+            eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode],
+                                     (uint8_t *)params.uidNamespaceID,
+                                     (uint8_t *)params.uidInstanceID,
+                                     params.uidBeaconPeriod);
+        }
+        // Start advertising the Eddystone service.
+        eddyServ.start();
+    }
+
+private:
+    /*
+     * This callback is invoked when a GATT client attempts to modify any of the
+     * characteristics of this service. Attempts to do so are also applied to
+     * the internal state of this service object.
+     */
+    void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) {
+        uint16_t handle = writeParams->handle;
+
+        if (handle == lockChar.getValueHandle()) {
+            // Validated earlier.
+            memcpy(params.lock, writeParams->data, sizeof(Lock_t));
+            // Set the state to be locked by the lock code (note: zeros are a valid lock).
+            params.lockedState = true;
+            INFO("Device Locked");
+        } else if (handle == unlockChar.getValueHandle()) {
+            // Validated earlier.
+            params.lockedState = false;
+            INFO("Device Unlocked");
+        } else if (handle == uriDataChar.getValueHandle()) {
+            params.uriDataLength = writeParams->len;
+            memset(params.uriData, 0x00, URI_DATA_MAX);                      // Clear URI string.
+            memcpy(params.uriData, writeParams->data, writeParams->len); // Set URI string.
+            params.uriEnabled = true;
+            INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len);
+        } else if (handle == flagsChar.getValueHandle()) {
+            params.flags = *(writeParams->data);
+            INFO("flagsChar = 0x%x", params.flags);
+        } else if (handle == advPowerLevelsChar.getValueHandle()) {
+            memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
+            INFO("PowerLevelsChar = %4x", params.advPowerLevels);
+        } else if (handle == txPowerModeChar.getValueHandle()) {
+            params.txPowerMode = *(writeParams->data);
+            INFO("TxPowerModeChar = %d", params.txPowerMode);
+        } else if (handle == beaconPeriodChar.getValueHandle()) {
+            params.beaconPeriod = *((uint16_t *)(writeParams->data));
+            INFO("BeaconPeriod = %d", params.beaconPeriod);
+
+            /* Re-map beaconPeriod to within permissible bounds if necessary. */
+            if (params.beaconPeriod != 0) {
+                bool paramsUpdated = false;
+                if (params.beaconPeriod < ble.getMinAdvertisingInterval()) {
+                    params.beaconPeriod = ble.getMinAdvertisingInterval();
+                    paramsUpdated       = true;
+                } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) {
+                    params.beaconPeriod = ble.getMaxAdvertisingInterval();
+                    paramsUpdated       = true;
+                }
+                if (paramsUpdated) {
+                    ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
+                }
+            }
+        } else if (handle == resetChar.getValueHandle()) {
+            INFO("Reset triggered from Config Service, resetting to defaults");
+            resetToDefaults();
+        }
+        updateCharacteristicValues();
+        params.isConfigured = true; // Some configuration data has been passed; on disconnect switch to advertising mode.
+    }
+
+    /*
+     * Reset the default values.
+     */
+    void resetToDefaults(void) {
+        INFO("Resetting to defaults");
+        // General.
+        params.lockedState = false;
+        memset(params.lock, 0, sizeof(Lock_t));
+        params.flags = 0x10;
+        memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
+        params.txPowerMode  = TX_POWER_MODE_LOW;
+        params.beaconPeriod = (uint16_t) defaultUriAdvPeriod * 1000;
+
+        // TLM Frame.
+        params.tlmVersion      = defaultTlmVersion;
+        params.tlmBeaconPeriod = defaultTlmAdvPeriod;
+        params.tlmEnabled      = tlmIsSet;
+
+        // URL Frame.
+        memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
+        params.uriDataLength   = defaultUriDataLength;
+        params.uriBeaconPeriod = defaultUriAdvPeriod;
+        params.uriEnabled      = urlIsSet;
+
+        // UID Frame.
+        memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
+        memcpy(params.uidInstanceID,  defaultUidInstanceID,  UID_INSTANCEID_SIZE);
+        params.uidBeaconPeriod = defaultUidAdvPeriod;
+        params.uidEnabled      = uidIsSet;
+
+        updateCharacteristicValues();
+    }
+
+    /*
+     * Internal helper function used to update the GATT database following any
+     * change to the internal state of the service object.
+     */
+    void updateCharacteristicValues(void) {
+        ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &params.lockedState, 1);
+        ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
+        ble.updateCharacteristicValue(flagsChar.getValueHandle(), &params.flags, 1);
+        ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(),
+                                      reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
+        ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), &params.txPowerMode, 1);
+        ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(),
+                                      reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
+    }
+
+private:
+    void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (params.lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(Lock_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        } else if (authParams->len != sizeof(Lock_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (params.lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (params.lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(uint8_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    template <typename T>
+    void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (params.lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(T)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    BLEDevice                                  &ble;
+    Params_t                                   &params;
+    Ticker                                     timeSinceBootTick;
+    Timeout                                    switchFrame;
+    // Default value that is restored on reset.
+    PowerLevels_t                              &defaultAdvPowerLevels; // This goes into the advertising frames (radio power measured at 1m from device).
+    PowerLevels_t                              &radioPowerLevels;      // This configures the power levels of the radio.
+    uint8_t                                    lockedState;
+    bool                                       initSucceeded;
+    uint8_t                                    resetFlag;
+    bool                                       switchFlag;
+
+    //UID default value that is restored on reset.
+    UIDNamespaceID_t                           defaultUidNamespaceID;
+    UIDInstanceID_t                            defaultUidInstanceID;
+    float                                      defaultUidAdvPeriod;
+    int8_t                                     defaultUidPower;
+    uint16_t                                   uidRFU;
+    bool                                       uidIsSet;
+
+    //URI default value that is restored on reset.
+    uint8_t                                    defaultUriDataLength;
+    UriData_t                                  defaultUriData;
+    int8_t                                     defaultUrlPower;
+    float                                      defaultUriAdvPeriod;
+    bool                                       urlIsSet;
+
+    //TLM default value that is restored on reset.
+    uint8_t                                    defaultTlmVersion;
+    float                                      defaultTlmAdvPeriod;
+    volatile uint16_t                          TlmBatteryVoltage;
+    volatile uint16_t                          TlmBeaconTemp;
+    volatile uint32_t                          TlmPduCount;
+    volatile uint32_t                          TlmTimeSinceBoot;
+    bool                                       tlmIsSet;
+
+    ReadOnlyGattCharacteristic<uint8_t>        lockedStateChar;
+    WriteOnlyGattCharacteristic<Lock_t>        lockChar;
+    GattCharacteristic                         uriDataChar;
+    WriteOnlyGattCharacteristic<Lock_t>        unlockChar;
+    ReadWriteGattCharacteristic<uint8_t>       flagsChar;
+    ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar;
+    ReadWriteGattCharacteristic<uint8_t>       txPowerModeChar;
+    ReadWriteGattCharacteristic<uint16_t>      beaconPeriodChar;
+    WriteOnlyGattCharacteristic<uint8_t>       resetChar;
+};
+
+#endif  // SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/EddystoneService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,653 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SERVICES_EDDYSTONEBEACON_H_
+#define SERVICES_EDDYSTONEBEACON_H_
+
+#warning ble/services/EddystoneService.h is deprecated. Please use the example in 'github.com/ARMmbed/ble-examples/tree/master/BLE_EddystoneService'.
+
+#include "ble/BLE.h"
+#include "mbed.h"
+#include "CircularBuffer.h"
+static const uint8_t BEACON_EDDYSTONE[] = {0xAA, 0xFE};
+
+//Debug is disabled by default
+#if 0
+#define DBG(MSG, ...)  printf("[EddyStone: DBG]" MSG " \t[%s,%d]\r\n", \
+                            ## __VA_ARGS__,                            \
+                            __FILE__,                                  \
+                            __LINE__);
+#define WARN(MSG, ...) printf("[EddyStone: WARN]" MSG " \t[%s,%d]\r\n", \
+                            ## __VA_ARGS__,                             \
+                            __FILE__,                                   \
+                            __LINE__);
+#define ERR(MSG, ...)  printf("[EddyStone: ERR]" MSG " \t[%s,%d]\r\n", \
+                            ## __VA_ARGS__,                            \
+                            __FILE__,                                  \
+                            __LINE__);
+#else // if 0
+#define DBG(x, ...) //wait_us(10);
+#define WARN(x, ...) //wait_us(10);
+#define ERR(x, ...)
+#endif // if 0
+
+#if 0
+#define INFO(x, ...)  printf("[EddyStone: INFO]"x " \t[%s,%d]\r\n", \
+                             ## __VA_ARGS__,                        \
+                             __FILE__,                              \
+                             __LINE__);
+#else // if 0
+#define INFO(x, ...)
+#endif // if 0
+
+/**
+* @class Eddystone
+* @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
+* See https://github.com/google/eddystone
+*
+*/
+class EddystoneService
+{
+public:
+    enum FrameTypes {
+        NONE,
+        url,
+        uid,
+        tlm
+    };
+
+    static const int SERVICE_DATA_MAX = 31;             // Maximum size of service data in ADV packets
+
+    // There are currently 3 subframes defined, URI, UID, and TLM
+#define EDDYSTONE_MAX_FRAMETYPE 3
+    void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t);
+    static const int URI_DATA_MAX = 18;
+    typedef uint8_t  UriData_t[URI_DATA_MAX];
+    CircularBuffer<FrameTypes, EDDYSTONE_MAX_FRAMETYPE> overflow;
+
+    // UID Frame Type subfields
+    static const int UID_NAMESPACEID_SIZE = 10;
+    typedef uint8_t  UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
+    static const int UID_INSTANCEID_SIZE = 6;
+    typedef uint8_t  UIDInstanceID_t[UID_INSTANCEID_SIZE];
+
+    // Eddystone Frame Type ID
+    static const uint8_t FRAME_TYPE_UID = 0x00;
+    static const uint8_t FRAME_TYPE_URL = 0x10;
+    static const uint8_t FRAME_TYPE_TLM = 0x20;
+
+    static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
+    static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
+
+    /**
+     *  Set Eddystone UID Frame information.
+     *
+     *  @param[in] power       TX Power in dB measured at 0 meters from the device. Range of -100 to +20 dB.
+     *  @param[in] namespaceID 10B namespace ID
+     *  @param[in] instanceID  6B instance ID
+     *  @param[in] RFU         2B of RFU, initialized to 0x0000 and not broadcast, included for future reference.
+     */
+    void setUIDFrameData(int8_t           power,
+                         UIDNamespaceID_t namespaceID,
+                         UIDInstanceID_t  instanceID,
+                         float            uidAdvPeriodIn,
+                         uint16_t         RFU = 0x0000) {
+        if (0.0f == uidAdvPeriodIn) {
+            uidIsSet = false;
+            return;
+        }
+        if (power > 20) {
+            power = 20;
+        }
+        if (power < -100) {
+            power = -100;
+        }
+
+        defaultUidPower = power;
+        memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
+        memcpy(defaultUidInstanceID,  instanceID,  UID_INSTANCEID_SIZE);
+        uidRFU       = (uint16_t)RFU; // this is probably bad form, but it doesn't really matter yet.
+        uidAdvPeriod = uidAdvPeriodIn;
+        uidIsSet     = true;          // set toggle to advertise UID frames
+    }
+
+    /*
+    *  Construct UID frame from private variables
+    *  @param[in/out] Data pointer to array to store constructed frame in
+    *  @param[in] maxSize number of bytes left in array, effectively how much empty space is available to write to
+    *  @return number of bytes used. negative number indicates error message.
+    */
+    unsigned constructUIDFrame(uint8_t *Data, uint8_t maxSize) {
+        unsigned index = 0;
+
+        Data[index++] = FRAME_TYPE_UID;                     // 1B  Type
+
+        if (defaultUidPower > 20) {
+            defaultUidPower = 20;                           // enforce range of vaild values.
+        }
+        if (defaultUidPower < -100) {
+            defaultUidPower = -100;
+        }
+        Data[index++] = defaultUidPower;                    // 1B  Power @ 0meter
+
+        DBG("UID NamespaceID = '0x");
+        for (size_t x = 0; x < UID_NAMESPACEID_SIZE; x++) { // 10B Namespace ID
+            Data[index++] = defaultUidNamespaceID[x];
+            DBG("%x,", defaultUidNamespaceID[x]);
+        }
+        DBG("'\r\n");
+
+        DBG("UID InstanceID = '0x");
+        for (size_t x = 0; x< UID_INSTANCEID_SIZE; x++) {   // 6B  Instance ID
+            Data[index++] = defaultUidInstanceID[x];
+            DBG("%x,", defaultUidInstanceID[x]);
+        }
+        DBG("'\r\n");
+
+        if (0 != uidRFU) {                                  // 2B RFU, include if non-zero, otherwise ignore
+            Data[index++] = (uint8_t)(uidRFU >> 0);
+            Data[index++] = (uint8_t)(uidRFU >> 8);
+        }
+        DBG("construcUIDFrame %d, %d", maxSize, index);
+        return index;
+    }
+
+    /**
+     *  Set Eddystone URL Frame information.
+     *  @param[in] power          TX Power in dB measured at 0 meters from the device.
+     *  @param[in] url            URL to encode
+     *  @param[in] urlAdvPeriodIn How long to advertise the URL frame (measured in # of adv periods)
+     *  @return false on success, true on failure.
+     */
+    bool setURLFrameData(int8_t power, const char *urlIn, float urlAdvPeriodIn) {
+        if (0.0f == urlAdvPeriodIn) {
+            urlIsSet = false;
+            return false;
+        }
+        encodeURL(urlIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
+        if (defaultUriDataLength > URI_DATA_MAX) {
+            return true;                                        // error, URL is too big
+        }
+        defaultUrlPower = power;
+        urlAdvPeriod = urlAdvPeriodIn;
+        urlIsSet     = true;
+        return false;
+    }
+
+    /**
+     *  Set Eddystone URL Frame information.
+     *  @param[in] power              TX Power in dB measured at 0 meters from the device.
+     *  @param[in] encodedUrlIn       Encoded URL
+     *  @param[in] encodedUrlInLength Length of the encoded URL
+     *  @param[in] urlAdvPeriodIn     How long to advertise the URL frame (measured in # of adv periods)
+     *  @return false on success, true on failure.
+     */
+    bool setURLFrameEncodedData(int8_t power, const char *encodedUrlIn, uint8_t encodedUrlInLength, float urlAdvPeriodIn) {
+        if (0.0f == urlAdvPeriodIn) {
+            urlIsSet = false;
+            return false;
+        }
+        memcpy(defaultUriData, encodedUrlIn, encodedUrlInLength);
+        if (defaultUriDataLength > URI_DATA_MAX) {
+            return true;                                        // error, URL is too big
+        }
+        defaultUrlPower      = power;
+        defaultUriDataLength = encodedUrlInLength;
+        urlAdvPeriod         = urlAdvPeriodIn;
+        urlIsSet             = true;
+        return false;
+    }
+
+    /*
+    *  Construct URL frame from private variables
+    *  @param[in/out] Data pointer to array to store constructed frame in
+    *  @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
+    *  @return number of bytes used. negative number indicates error message.
+    */
+    int constructURLFrame(uint8_t *Data, uint8_t maxSize) {
+        int index = 0;
+        Data[index++] = FRAME_TYPE_URL;                     // 1B  Type
+        Data[index++] = defaultUrlPower;                    // 1B  TX Power
+        for (int x = 0; x < defaultUriDataLength; x++) {    // 18B of URL Prefix + encoded URL
+            Data[index++] = defaultUriData[x];
+        }
+        DBG("constructURLFrame: %d, %d", maxSize, index);
+        return index;
+    }
+
+    /*
+    *  Set Eddystone TLM Frame information.
+    *  @param[in] Version    of the TLM beacon data format
+    *  @param[in] advPeriod  how often to advertise the TLM frame for (in minutes)
+    *  @param batteryVoltage in milivolts
+    *  @param beaconTemp     in 8.8 floating point notation
+    *
+    */
+    void setTLMFrameData(uint8_t  version        = 0,
+                         float    advPeriod      = 60.0f,
+                         uint16_t batteryVoltage = 0,
+                         uint16_t beaconTemp     = 0x8000,
+                         uint32_t pduCount       = 0,
+                         uint32_t timeSinceBoot  = 0) {
+        if (0.0f == advPeriod) {
+            tlmIsSet = false;
+            return;
+        }
+        TlmVersion        = version;
+        TlmBatteryVoltage = batteryVoltage;
+        TlmBeaconTemp     = beaconTemp;
+        TlmPduCount       = pduCount;      // reset
+        TlmTimeSinceBoot  = timeSinceBoot; // reset
+        TlmAdvPeriod      = advPeriod;
+        tlmIsSet          = true;          // TLM Data has been enabled
+    }
+
+    /*
+    *  Construct TLM frame from private variables
+    *  @param[in/out] Data pointer to array to store constructed frame in
+    *  @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
+    *  @return number of bytes used. negative number indicates error message.
+    */
+    int constructTLMFrame(uint8_t *Data, uint8_t maxSize) {
+        uint32_t now = timeSinceBootTimer.read_ms();
+        TlmTimeSinceBoot += (now - lastBootTimerRead) / 100;
+        lastBootTimerRead = now;
+
+        int index = 0;
+        Data[index++] = FRAME_TYPE_TLM;                    // Eddystone frame type = Telemetry
+        Data[index++] = TlmVersion;                        // TLM Version Number
+        Data[index++] = (uint8_t)(TlmBatteryVoltage >> 8); // Battery Voltage[0]
+        Data[index++] = (uint8_t)(TlmBatteryVoltage >> 0); // Battery Voltage[1]
+        Data[index++] = (uint8_t)(TlmBeaconTemp >> 8);     // Beacon Temp[0]
+        Data[index++] = (uint8_t)(TlmBeaconTemp >> 0);     // Beacon Temp[1]
+        Data[index++] = (uint8_t)(TlmPduCount >> 24);      // PDU Count [0]
+        Data[index++] = (uint8_t)(TlmPduCount >> 16);      // PDU Count [1]
+        Data[index++] = (uint8_t)(TlmPduCount >> 8);       // PDU Count [2]
+        Data[index++] = (uint8_t)(TlmPduCount >> 0);       // PDU Count [3]
+        Data[index++] = (uint8_t)(TlmTimeSinceBoot >> 24); // Time Since Boot [0]
+        Data[index++] = (uint8_t)(TlmTimeSinceBoot >> 16); // Time Since Boot [1]
+        Data[index++] = (uint8_t)(TlmTimeSinceBoot >> 8);  // Time Since Boot [2]
+        Data[index++] = (uint8_t)(TlmTimeSinceBoot >> 0);  // Time Since Boot [3]
+        DBG("constructURLFrame: %d, %d", maxSize, index);
+        return index;
+    }
+
+    /*
+    *  Update the TLM frame battery voltage value
+    *  @param[in] voltagemv Voltage to update the TLM field battery voltage with (in mV)
+    *  @return nothing
+    */
+    void updateTlmBatteryVoltage(uint16_t voltagemv) {
+        TlmBatteryVoltage = voltagemv;
+    }
+
+    /*
+    *  Update the TLM frame beacon temperature
+    *  @param[in] temp Temperature of beacon (in 8.8fpn)
+    *  @return nothing
+    */
+    void updateTlmBeaconTemp(uint16_t temp) {
+        TlmBeaconTemp = temp;
+    }
+
+    /*
+    *  Update the TLM frame PDU Count field
+    *  @param[in] pduCount Number of Advertisiting frames sent since powerup
+    *  @return nothing
+    */
+    void updateTlmPduCount(uint32_t pduCount) {
+        TlmPduCount = pduCount;
+    }
+
+    /*
+    *  Update the TLM frame Time since boot in 0.1s incriments
+    *  @param[in] timeSinceBoot Time since boot in 0.1s incriments
+    *  @return nothing
+    */
+    void updateTlmTimeSinceBoot(uint32_t timeSinceBoot) {
+        TlmTimeSinceBoot = timeSinceBoot;
+    }
+
+    /*
+    * Update advertising data
+    * @return true on success, false on failure
+    */
+    bool updateAdvPacket(uint8_t serviceData[], unsigned serviceDataLen) {
+        // Fields from the Service
+        DBG("Updating AdvFrame: %d", serviceDataLen);
+
+        ble.clearAdvertisingPayload();
+        ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+        ble.setAdvertisingInterval(100);
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_EDDYSTONE, sizeof(BEACON_EDDYSTONE));
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
+
+
+        return true;
+    }
+
+    /*
+    *   State machine for switching out frames.
+    *   This function is called by the radioNotificationCallback when a frame needs to get swapped out.
+    *   This function exists because of time constraints in the radioNotificationCallback, so it is effectively
+    *   broken up into two functions.
+    */
+    void swapOutFrames(FrameTypes frameType) {
+        uint8_t  serviceData[SERVICE_DATA_MAX];
+        unsigned serviceDataLen = 0;
+        //hard code in the eddystone UUID
+        serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
+        serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
+
+        // if certain frames are not enabled, then skip them. Worst case TLM is always enabled
+        switch (frameType) {
+            case tlm:
+                // TLM frame
+                if (tlmIsSet) {
+                    DBG("Swapping in TLM Frame: version=%x, Batt=%d, Temp = %d, PDUCnt = %d, TimeSinceBoot=%d",
+                        TlmVersion,
+                        TlmBatteryVoltage,
+                        TlmBeaconTemp,
+                        TlmPduCount,
+                        TlmTimeSinceBoot);
+                    serviceDataLen += constructTLMFrame(serviceData + serviceDataLen, 20);
+                    DBG("\t Swapping in TLM Frame: len=%d", serviceDataLen);
+                    updateAdvPacket(serviceData, serviceDataLen);
+                }
+                break;
+            case url:
+                // URL Frame
+                if (urlIsSet) {
+                    DBG("Swapping in URL Frame: Power: %d", defaultUrlPower);
+                    serviceDataLen += constructURLFrame(serviceData + serviceDataLen, 20);
+                    DBG("\t Swapping in URL Frame: len=%d ", serviceDataLen);
+                    updateAdvPacket(serviceData, serviceDataLen);
+                    //switchFlag = false;
+                }
+                break;
+            case uid:
+                // UID Frame
+                if (uidIsSet) {
+                    DBG("Swapping in UID Frame: Power: %d", defaultUidPower);
+                    serviceDataLen += constructUIDFrame(serviceData + serviceDataLen, 20);
+                    DBG("\t Swapping in UID Frame: len=%d", serviceDataLen);
+                    updateAdvPacket(serviceData, serviceDataLen);
+                    //switchFlag = false;
+                }
+                break;
+            default:
+                ERR("You have not initialized a Frame yet, please initialize one before starting a beacon");
+                ERR("uidIsSet = %d, urlIsSet = %d, tlmIsSet = %d", uidIsSet, urlIsSet, tlmIsSet);
+        }
+    }
+
+    /*
+    * Callback to swap in URL frame
+    */
+    void urlCallback(void) {
+        DBG("urlCallback");
+        if (false == advLock) {
+            advLock = true;
+            DBG("advLock = url")
+            frameIndex = url;
+            swapOutFrames(frameIndex);
+            ble.startAdvertising();
+        } else {
+            // Someone else is broadcasting, toss it into the overflow buffer to retransmit when free
+            INFO("URI(%d) cannot complete, %d is currently broadcasting", url, frameIndex);
+            FrameTypes x = url;
+            overflow.push(x);
+        }
+    }
+
+    /*
+    * Callback to swap in UID frame
+    */
+    void uidCallback(void) {
+        DBG("uidCallback");
+        if (false == advLock) {
+            advLock = true;
+            DBG("advLock = uid")
+            frameIndex = uid;
+            swapOutFrames(frameIndex);
+            ble.startAdvertising();
+        } else {
+            // Someone else is broadcasting, toss it into the overflow buffer to retransmit when free
+            INFO("UID(%d) cannot complete, %d is currently broadcasting", uid, frameIndex);
+            FrameTypes x = uid; // have to do this to satisfy cont vs volatile keywords... sigh...
+            overflow.push(x);
+        }
+    }
+
+    /*
+    * Callback to swap in TLM frame
+    */
+    void tlmCallback(void) {
+        DBG("tlmCallback");
+        if (false == advLock) {
+            // OK to broadcast
+            advLock = true;
+            DBG("advLock = tlm")
+            frameIndex = tlm;
+            swapOutFrames(frameIndex);
+            ble.startAdvertising();
+        } else {
+            // Someone else is broadcasting, toss it into the overflow buffer to retransmit when free
+            INFO("TLM(%d) cannot complete, %d is currently broadcasting", tlm, frameIndex);
+            FrameTypes x = tlm;
+            overflow.push(x);
+        }
+    }
+
+    void stopAdvCallback(void) {
+        if (overflow.empty()) {
+            // if nothing left to transmit, stop
+            ble.stopAdvertising();
+            advLock = false; // unlock lock
+        } else {
+            // transmit other packets at current time index
+            FrameTypes x = NONE;
+            overflow.pop(x);
+            INFO("Re-Transmitting %d", x);
+            swapOutFrames(x);
+        }
+    }
+
+    /*
+    *  Callback from onRadioNotification(), used to update the PDUCounter and process next state.
+    */
+#define EDDYSTONE_SWAPFRAME_DELAYMS 1
+    void radioNotificationCallback(bool radioActive) {
+        // Update PDUCount
+        TlmPduCount++;
+        // True just before an frame is sent, false just after a frame is sent
+        if (radioActive) {
+            // Do Nothing
+        } else {
+            // Packet has been sent, disable advertising
+            stopAdv.attach_us(this, &EddystoneService::stopAdvCallback, 1);
+        }
+    }
+
+    /*
+    *   This function explicityly sets the parameters used by the Eddystone beacon.
+    *   this function should be used in leu of the config service.
+    *
+    *   @param bleIn ble object used to broadcast eddystone information
+    *   @param beaconPeriodus is how often ble broadcasts are mde, in mili seconds
+    *   @param txPowerLevel sets the broadcasting power level.
+    *
+    */
+    EddystoneService(BLEDevice &bleIn,
+                     uint16_t   beaconPeriodus = 100,
+                     uint8_t    txPowerIn      = 0) :
+        ble(bleIn),
+        advPeriodus(beaconPeriodus),
+        txPower(txPowerIn),
+        advLock(false),
+        frameIndex(NONE) {
+    }
+
+    /*
+    * @breif this function starts eddystone advertising based on configured frames.
+    */
+    void start(void) {
+        // Initialize Frame transition, start with URL to pass eddystone validator app on first try
+        if (urlIsSet) {
+            frameIndex = url;
+            urlTicker.attach(this, &EddystoneService::urlCallback, (float) advPeriodus / 1000.0f);
+            DBG("attached urlCallback every %d seconds", urlAdvPeriod);
+        }
+        if (uidIsSet) {
+            frameIndex = uid;
+            uidTicker.attach(this, &EddystoneService::uidCallback, uidAdvPeriod);
+            DBG("attached uidCallback every %d seconds", uidAdvPeriod);
+        }
+        if (tlmIsSet) {
+            frameIndex = tlm;
+            // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset
+            updateTlmPduCount(0);
+            updateTlmTimeSinceBoot(0);
+            lastBootTimerRead = 0;
+            timeSinceBootTimer.start();
+            tlmTicker.attach(this, &EddystoneService::tlmCallback, TlmAdvPeriod);
+            DBG("attached tlmCallback every %d seconds", TlmAdvPeriod);
+        }
+        if (NONE == frameIndex) {
+            error("No Frames were Initialized! Please initialize a frame before starting an eddystone beacon.");
+        }
+        //uidRFU = 0;
+
+        ble.setTxPower(txPower);
+        ble.gap().onRadioNotification(this, &EddystoneService::radioNotificationCallback);
+    }
+
+private:
+
+    // Eddystone Variables
+    BLEDevice           &ble;
+    uint16_t            advPeriodus;
+    uint8_t             txPower;
+    Timer               timeSinceBootTimer;
+    volatile uint32_t   lastBootTimerRead;
+    volatile bool       advLock;
+    volatile FrameTypes frameIndex;
+    Timeout             stopAdv;
+
+
+    // URI Frame Variables
+    uint8_t             defaultUriDataLength;
+    UriData_t           defaultUriData;
+    int8_t              defaultUrlPower;
+    bool                urlIsSet;       // flag that enables / disable URI Frames
+    float               urlAdvPeriod;   // how long the url frame will be advertised for
+    Ticker              urlTicker;
+
+    // UID Frame Variables
+    UIDNamespaceID_t    defaultUidNamespaceID;
+    UIDInstanceID_t     defaultUidInstanceID;
+    int8_t              defaultUidPower;
+    uint16_t            uidRFU;
+    bool                uidIsSet;       // flag that enables / disable UID Frames
+    float               uidAdvPeriod;   // how long the uid frame will be advertised for
+    Ticker              uidTicker;
+
+    // TLM Frame Variables
+    uint8_t             TlmVersion;
+    volatile uint16_t   TlmBatteryVoltage;
+    volatile uint16_t   TlmBeaconTemp;
+    volatile uint32_t   TlmPduCount;
+    volatile uint32_t   TlmTimeSinceBoot;
+    bool                tlmIsSet;          // flag that enables / disables TLM frames
+    float               TlmAdvPeriod;      // number of minutes between adv frames
+    Ticker              tlmTicker;
+
+public:
+    /*
+     *  Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
+     */
+    static void encodeURL(const char *uriDataIn, UriData_t uriDataOut, uint8_t &sizeofURIDataOut) {
+        DBG("Encode URL = %s", uriDataIn);
+        const char  *prefixes[] = {
+            "http://www.",
+            "https://www.",
+            "http://",
+            "https://",
+        };
+        const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
+        const char  *suffixes[]   = {
+            ".com/",
+            ".org/",
+            ".edu/",
+            ".net/",
+            ".info/",
+            ".biz/",
+            ".gov/",
+            ".com",
+            ".org",
+            ".edu",
+            ".net",
+            ".info",
+            ".biz",
+            ".gov"
+        };
+        const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
+
+        sizeofURIDataOut = 0;
+        memset(uriDataOut, 0, sizeof(UriData_t));
+
+        if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) {
+            return;
+        }
+
+        /*
+         * handle prefix
+         */
+        for (unsigned i = 0; i < NUM_PREFIXES; i++) {
+            size_t prefixLen = strlen(prefixes[i]);
+            if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
+                uriDataOut[sizeofURIDataOut++]  = i;
+                uriDataIn                      += prefixLen;
+                break;
+            }
+        }
+
+        /*
+         * handle suffixes
+         */
+        while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) {
+            /* check for suffix match */
+            unsigned i;
+            for (i = 0; i < NUM_SUFFIXES; i++) {
+                size_t suffixLen = strlen(suffixes[i]);
+                if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
+                    uriDataOut[sizeofURIDataOut++]  = i;
+                    uriDataIn                      += suffixLen;
+                    break; /* from the for loop for checking against suffixes */
+                }
+            }
+            /* This is the default case where we've got an ordinary character which doesn't match a suffix. */
+            INFO("Encoding URI: No Suffix Found");
+            if (i == NUM_SUFFIXES) {
+                uriDataOut[sizeofURIDataOut++] = *uriDataIn;
+                ++uriDataIn;
+            }
+        }
+    }
+};
+
+#endif  // SERVICES_EDDYSTONEBEACON_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/EnvironmentalService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,106 @@
+/* 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 __BLE_ENVIRONMENTAL_SERVICE_H__
+#define __BLE_ENVIRONMENTAL_SERVICE_H__
+
+#include "ble/BLE.h"
+
+/**
+* @class EnvironmentalService
+* @brief BLE Environmental Service. This service provides temperature, humidity and pressure measurement.
+* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml
+* Temperature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature.xml
+* Humidity: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.humidity.xml
+* Pressure: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.pressure.xml
+*/
+class EnvironmentalService {
+public:
+    typedef int16_t  TemperatureType_t;
+    typedef uint16_t HumidityType_t;
+    typedef uint32_t PressureType_t;
+
+    /**
+     * @brief   EnvironmentalService constructor.
+     * @param   ble Reference to BLE device.
+     * @param   temperature_en Enable this characteristic.
+     * @param   humidity_en Enable this characteristic.
+     * @param   pressure_en Enable this characteristic.
+     */
+    EnvironmentalService(BLE& _ble) :
+        ble(_ble),
+        temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, &temperature),
+        humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, &humidity),
+        pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, &pressure)
+    {
+        static bool serviceAdded = false; /* We should only ever need to add the information service once. */
+        if (serviceAdded) {
+            return;
+        }
+
+        GattCharacteristic *charTable[] = { &humidityCharacteristic,
+                                            &pressureCharacteristic,
+                                            &temperatureCharacteristic };
+
+        GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.gattServer().addService(environmentalService);
+        serviceAdded = true;
+    }
+
+    /**
+     * @brief   Update humidity characteristic.
+     * @param   newHumidityVal New humidity measurement.
+     */
+    void updateHumidity(HumidityType_t newHumidityVal)
+    {
+        humidity = (HumidityType_t) (newHumidityVal * 100);
+        ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, sizeof(HumidityType_t));
+    }
+
+    /**
+     * @brief   Update pressure characteristic.
+     * @param   newPressureVal New pressure measurement.
+     */
+    void updatePressure(PressureType_t newPressureVal)
+    {
+        pressure = (PressureType_t) (newPressureVal * 10);
+        ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, sizeof(PressureType_t));
+    }
+
+    /**
+     * @brief   Update temperature characteristic.
+     * @param   newTemperatureVal New temperature measurement.
+     */
+    void updateTemperature(float newTemperatureVal)
+    {
+        temperature = (TemperatureType_t) (newTemperatureVal * 100);
+        ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, sizeof(TemperatureType_t));
+    }
+
+private:
+    BLE& ble;
+
+    TemperatureType_t temperature;
+    HumidityType_t    humidity;
+    PressureType_t    pressure;
+
+    ReadOnlyGattCharacteristic<TemperatureType_t> temperatureCharacteristic;
+    ReadOnlyGattCharacteristic<HumidityType_t>    humidityCharacteristic;
+    ReadOnlyGattCharacteristic<PressureType_t>    pressureCharacteristic;
+};
+
+#endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/HealthThermometerService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,150 @@
+/* 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 __BLE_HEALTH_THERMOMETER_SERVICE_H__
+#define __BLE_HEALTH_THERMOMETER_SERVICE_H__
+
+#include "ble/BLE.h"
+
+/**
+* @class HealthThermometerService
+* @brief BLE Health Thermometer Service. This service provides the location of the thermometer and the temperature.
+* Service:  https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml
+* Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml
+* Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml
+*/
+class HealthThermometerService {
+public:
+    /**
+    * @enum Sensor Location.
+    * @brief Location of sensor on the body.
+    */
+    enum SensorLocation_t {
+        LOCATION_ARMPIT = 1,    /*!< Armpit. */
+        LOCATION_BODY,          /*!< Body. */
+        LOCATION_EAR,           /*!< Ear. */
+        LOCATION_FINGER,        /*!< Finger. */
+        LOCATION_GI_TRACT,      /*!< GI tract */
+        LOCATION_MOUTH,         /*!< Mouth. */
+        LOCATION_RECTUM,        /*!< Rectum. */
+        LOCATION_TOE,           /*!< Toe. */
+        LOCATION_EAR_DRUM,      /*!< Eardrum. */
+    };
+
+public:
+    /**
+     * @brief Add the Health Thermometer Service to an existing BLE object, initialize with temperature and location.
+     * @param[ref] _ble         Reference to the BLE device.
+     * @param[in] initialTemp  Initial value in celsius.
+     * @param[in] _location
+     */
+    HealthThermometerService(BLE &_ble, float initialTemp, uint8_t _location) :
+        ble(_ble),
+        valueBytes(initialTemp),
+        tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+        tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, &_location) {
+
+        GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, };
+        GattService         hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *));
+
+        ble.addService(hrmService);
+    }
+
+    /**
+    * @brief Update the temperature being broadcast.
+    *
+    * @param[in] temperature
+    *                   Floating point value of the temperature.
+    *
+    */
+    void updateTemperature(float temperature) {
+        if (ble.getGapState().connected) {
+            valueBytes.updateTemperature(temperature);
+            ble.gattServer().write(tempMeasurement.getValueHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes));
+        }
+    }
+
+    /**
+     * @brief Update the location.
+     * @param loc
+     *        New location value.
+     */
+    void updateLocation(SensorLocation_t loc) {
+        ble.gattServer().write(tempLocation.getValueHandle(), reinterpret_cast<uint8_t *>(&loc), sizeof(uint8_t));
+    }
+
+private:
+    /* Private internal representation for the bytes used to work with the vaulue of the temperature characteristic. */
+    struct TemperatureValueBytes {
+        static const unsigned OFFSET_OF_FLAGS    = 0;
+        static const unsigned OFFSET_OF_VALUE    = OFFSET_OF_FLAGS + sizeof(uint8_t);
+        static const unsigned SIZEOF_VALUE_BYTES = sizeof(uint8_t) + sizeof(float);
+
+        static const unsigned TEMPERATURE_UNITS_FLAG_POS = 0;
+        static const unsigned TIMESTAMP_FLAG_POS         = 1;
+        static const unsigned TEMPERATURE_TYPE_FLAG_POS  = 2;
+
+        static const uint8_t  TEMPERATURE_UNITS_CELSIUS    = 0;
+        static const uint8_t  TEMPERATURE_UNITS_FAHRENHEIT = 1;
+
+        TemperatureValueBytes(float initialTemperature) : bytes() {
+            /* Assumption: temperature values are expressed in celsius */
+            bytes[OFFSET_OF_FLAGS] =  (TEMPERATURE_UNITS_CELSIUS << TEMPERATURE_UNITS_FLAG_POS) |
+                                      (false << TIMESTAMP_FLAG_POS) |
+                                      (false << TEMPERATURE_TYPE_FLAG_POS);
+            updateTemperature(initialTemperature);
+        }
+
+        void updateTemperature(float temp) {
+            uint32_t temp_ieee11073 = quick_ieee11073_from_float(temp);
+            memcpy(&bytes[OFFSET_OF_VALUE], &temp_ieee11073, sizeof(float));
+        }
+
+        uint8_t       *getPointer(void) {
+            return bytes;
+        }
+
+        const uint8_t *getPointer(void) const {
+            return bytes;
+        }
+
+private:
+        /**
+         * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
+         * @param temperature The temperature as a float.
+         * @return The temperature in 11073-20601 FLOAT-Type format.
+         */
+        uint32_t quick_ieee11073_from_float(float temperature) {
+            uint8_t  exponent = 0xFE; //Exponent is -2
+            uint32_t mantissa = (uint32_t)(temperature * 100);
+
+            return (((uint32_t)exponent) << 24) | mantissa;
+        }
+
+private:
+        /* First byte: 8-bit flags. Second field is a float holding the temperature value. */
+        /* See https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */
+        uint8_t bytes[SIZEOF_VALUE_BYTES];
+    };
+
+protected:
+    BLE                                               &ble;
+    TemperatureValueBytes                              valueBytes;
+    ReadOnlyGattCharacteristic<TemperatureValueBytes>  tempMeasurement;
+    ReadOnlyGattCharacteristic<uint8_t>                tempLocation;
+};
+
+#endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/HeartRateService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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 __BLE_HEART_RATE_SERVICE_H__
+#define __BLE_HEART_RATE_SERVICE_H__
+
+#include "ble/BLE.h"
+
+/**
+* @class HeartRateService
+* @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor and the heart rate in beats per minute.
+* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml
+* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
+* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml
+*/
+class HeartRateService {
+public:
+    /**
+    * @enum SensorLocation
+    * @brief Location of the heart rate sensor on body.
+    */
+    enum {
+        LOCATION_OTHER = 0, /*!< Other location. */
+        LOCATION_CHEST,     /*!< Chest. */
+        LOCATION_WRIST,     /*!< Wrist. */
+        LOCATION_FINGER,    /*!< Finger. */
+        LOCATION_HAND,      /*!< Hand. */
+        LOCATION_EAR_LOBE,  /*!< Earlobe. */
+        LOCATION_FOOT,      /*!< Foot. */
+    };
+
+public:
+    /**
+     * @brief Constructor with 8-bit HRM Counter value.
+     *
+     * @param[ref] _ble
+     *               Reference to the underlying BLE.
+     * @param[in] hrmCounter (8-bit)
+     *               Initial value for the HRM counter.
+     * @param[in] location
+     *               Sensor's location.
+     */
+    HeartRateService(BLE &_ble, uint8_t hrmCounter, uint8_t location) :
+        ble(_ble),
+        valueBytes(hrmCounter),
+        hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
+                valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
+                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+        hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location),
+        controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) {
+        setupService();
+    }
+
+    /**
+     * @brief Constructor with a 16-bit HRM Counter value.
+     *
+     * @param[in] _ble
+     *               Reference to the underlying BLE.
+     * @param[in] hrmCounter (8-bit)
+     *               Initial value for the HRM counter.
+     * @param[in] location
+     *               Sensor's location.
+     */
+    HeartRateService(BLE &_ble, uint16_t hrmCounter, uint8_t location) :
+        ble(_ble),
+        valueBytes(hrmCounter),
+        hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
+                valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
+                GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+        hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location),
+        controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) {
+        setupService();
+    }
+
+    /**
+     * @brief Set a new 8-bit value for the heart rate.
+     *
+     * @param[in] hrmCounter
+     *                  Heart rate in BPM.
+     */
+    void updateHeartRate(uint8_t hrmCounter) {
+        valueBytes.updateHeartRate(hrmCounter);
+        ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
+    }
+
+    /**
+     * Set a new 16-bit value for the heart rate.
+     *
+     * @param[in] hrmCounter
+     *                  Heart rate in BPM.
+     */
+    void updateHeartRate(uint16_t hrmCounter) {
+        valueBytes.updateHeartRate(hrmCounter);
+        ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
+    }
+
+    /**
+     * This callback allows the heart rate service to receive updates to the
+     * controlPoint characteristic.
+     *
+     * @param[in] params
+     *     Information about the characterisitc being updated.
+     */
+    virtual void onDataWritten(const GattWriteCallbackParams *params) {
+        if (params->handle == controlPoint.getValueAttribute().getHandle()) {
+            /* Do something here if the new value is 1; else you can override this method by
+             * extending this class.
+             * @NOTE: If you are extending this class, be sure to also call
+             * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in
+             * your constructor.
+             */
+        }
+    }
+
+protected:
+    void setupService(void) {
+        GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint};
+        GattService         hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(hrmService);
+        ble.onDataWritten(this, &HeartRateService::onDataWritten);
+    }
+
+protected:
+    /* Private internal representation for the bytes used to work with the value of the heart rate characteristic. */
+    struct HeartRateValueBytes {
+        static const unsigned MAX_VALUE_BYTES  = 3; /* Flags, and up to two bytes for heart rate. */
+        static const unsigned FLAGS_BYTE_INDEX = 0;
+
+        static const unsigned VALUE_FORMAT_BITNUM = 0;
+        static const uint8_t  VALUE_FORMAT_FLAG   = (1 << VALUE_FORMAT_BITNUM);
+
+        HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() {
+            updateHeartRate(hrmCounter);
+        }
+
+        HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() {
+            updateHeartRate(hrmCounter);
+        }
+
+        void updateHeartRate(uint8_t hrmCounter) {
+            valueBytes[FLAGS_BYTE_INDEX]    &= ~VALUE_FORMAT_FLAG;
+            valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
+        }
+
+        void updateHeartRate(uint16_t hrmCounter) {
+            valueBytes[FLAGS_BYTE_INDEX]    |= VALUE_FORMAT_FLAG;
+            valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
+            valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
+        }
+
+        uint8_t       *getPointer(void) {
+            return valueBytes;
+        }
+
+        const uint8_t *getPointer(void) const {
+            return valueBytes;
+        }
+
+        unsigned       getNumValueBytes(void) const {
+            return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
+        }
+
+    private:
+        /* First byte: 8-bit values, no extra info. Second byte: uint8_t HRM value */
+        /* See https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
+        uint8_t valueBytes[MAX_VALUE_BYTES];
+    };
+
+protected:
+    BLE                 &ble;
+
+    HeartRateValueBytes  valueBytes;
+    uint8_t              controlPointValue;
+
+    GattCharacteristic                   hrmRate;
+    ReadOnlyGattCharacteristic<uint8_t>  hrmLocation;
+    WriteOnlyGattCharacteristic<uint8_t> controlPoint;
+};
+
+#endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/LinkLossService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,103 @@
+/* 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 __BLE_LINK_LOSS_SERVICE_H__
+#define __BLE_LINK_LOSS_SERVICE_H__
+
+#include "ble/Gap.h"
+
+/**
+* @class LinkLossService
+* @brief This service defines behavior when a link is lost between two devices.
+* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.link_loss.xml
+* Alertness Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.alert_level.xml
+*/
+class LinkLossService {
+public:
+    enum AlertLevel_t {
+        NO_ALERT   = 0,
+        MILD_ALERT = 1,
+        HIGH_ALERT = 2
+    };
+
+    typedef void (* callback_t)(AlertLevel_t level);
+
+    /**
+     * @param[ref] ble
+     *               BLE object for the underlying controller.
+     */
+    LinkLossService(BLE &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) :
+        ble(bleIn),
+        alertLevel(levelIn),
+        callback(callbackIn),
+        alertLevelChar(GattCharacteristic::UUID_ALERT_LEVEL_CHAR, reinterpret_cast<uint8_t *>(&alertLevel)) {
+        static bool serviceAdded = false; /* We should only ever add one LinkLoss service. */
+        if (serviceAdded) {
+            return;
+        }
+
+        GattCharacteristic *charTable[] = {&alertLevelChar};
+        GattService         linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.gattServer().addService(linkLossService);
+        serviceAdded = true;
+
+        ble.gap().onDisconnection(this, &LinkLossService::onDisconnectionFilter);
+        ble.gattServer().onDataWritten(this, &LinkLossService::onDataWritten);
+    }
+
+    /**
+     * Update the callback.
+     */
+    void setCallback(callback_t newCallback) {
+        callback = newCallback;
+    }
+
+    /**
+     * Update alertness level.
+     */
+    void setAlertLevel(AlertLevel_t newLevel) {
+        alertLevel = newLevel;
+    }
+
+protected:
+    /**
+     * This callback allows receiving updates to the AlertLevel characteristic.
+     *
+     * @param[in] params
+     *     Information about the characterisitc being updated.
+     */
+    virtual void onDataWritten(const GattWriteCallbackParams *params) {
+        if (params->handle == alertLevelChar.getValueHandle()) {
+            alertLevel = *reinterpret_cast<const AlertLevel_t *>(params->data);
+        }
+    }
+
+    void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) {
+        if (alertLevel != NO_ALERT) {
+            callback(alertLevel);
+        }
+    }
+
+protected:
+    BLE          &ble;
+    AlertLevel_t  alertLevel;
+    callback_t    callback;
+
+    ReadWriteGattCharacteristic<uint8_t> alertLevelChar;
+};
+
+#endif /* __BLE_LINK_LOSS_SERVICE_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/UARTService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,206 @@
+/* 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 __BLE_UART_SERVICE_H__
+#define __BLE_UART_SERVICE_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+#include "mbed-drivers/mbed.h"
+#include "mbed-drivers/Stream.h"
+#else
+#include "mbed.h"
+#include "Stream.h"
+#endif
+
+#include "ble/UUID.h"
+#include "ble/BLE.h"
+
+extern const uint8_t  UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint16_t UARTServiceShortUUID;
+extern const uint16_t UARTServiceTXCharacteristicShortUUID;
+extern const uint16_t UARTServiceRXCharacteristicShortUUID;
+
+extern const uint8_t  UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t  UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID];
+
+extern const uint8_t  UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t  UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
+
+/**
+* @class UARTService.
+* @brief BLE Service to enable UART over BLE.
+*/
+class UARTService {
+public:
+    /**< Maximum length of data (in bytes) that the UART service module can transmit to the peer. */
+    static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (BLE_GATT_MTU_SIZE_DEFAULT - 3);
+
+public:
+
+    /**
+    * @param[ref] ble
+    *               BLE object for the underlying controller.
+    */
+    UARTService(BLE &_ble) :
+        ble(_ble),
+        receiveBuffer(),
+        sendBuffer(),
+        sendBufferIndex(0),
+        numBytesReceived(0),
+        receiveBufferIndex(0),
+        txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN,
+                         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
+        rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) {
+        GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic};
+        GattService         uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(uartService);
+        ble.onDataWritten(this, &UARTService::onDataWritten);
+    }
+
+    /**
+     * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
+     */
+    uint16_t getTXCharacteristicHandle() {
+        return txCharacteristic.getValueAttribute().getHandle();
+    }
+
+    /**
+     * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
+     */
+    uint16_t getRXCharacteristicHandle() {
+        return rxCharacteristic.getValueAttribute().getHandle();
+    }
+
+    /**
+     * We attempt to collect bytes before pushing them to the UART RX
+     * characteristic; writing to the RX characteristic then generates
+     * notifications for the client. Updates made in quick succession to a
+     * notification-generating characteristic result in data being buffered
+     * in the Bluetooth stack as notifications are sent out. The stack has
+     * its limits for this buffering - typically a small number under 10.
+     * Collecting data into the sendBuffer buffer helps mitigate the rate of
+     * updates. But we shouldn't buffer a large amount of data before updating
+     * the characteristic, otherwise the client needs to turn around and make
+     * a long read request; this is because notifications include only the first
+     * 20 bytes of the updated data.
+     *
+     * @param  buffer The received update.
+     * @param  length Number of characters to be appended.
+     * @return        Number of characters appended to the rxCharacteristic.
+     */
+    size_t write(const void *_buffer, size_t length) {
+        size_t         origLength = length;
+        const uint8_t *buffer     = static_cast<const uint8_t *>(_buffer);
+
+        if (ble.getGapState().connected) {
+            unsigned bufferIndex = 0;
+            while (length) {
+                unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex;
+                unsigned bytesToCopy                = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer;
+
+                /* Copy bytes into sendBuffer. */
+                memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy);
+                length          -= bytesToCopy;
+                sendBufferIndex += bytesToCopy;
+                bufferIndex     += bytesToCopy;
+
+                /* Have we collected enough? */
+                if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) ||
+                    // (sendBuffer[sendBufferIndex - 1] == '\r')          ||
+                    (sendBuffer[sendBufferIndex - 1] == '\n')) {
+                    ble.gattServer().write(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex);
+                    sendBufferIndex = 0;
+                }
+            }
+        }
+
+        return origLength;
+    }
+
+    /**
+     * Helper function to write out strings.
+     * @param  str The received string.
+     * @return     Number of characters appended to the rxCharacteristic.
+     */
+    size_t writeString(const char *str) {
+        return write(str, strlen(str));
+    }
+
+    /**
+     * Override for Stream::_putc().
+     * @param  c
+     *         This function writes the character c, cast to an unsigned char, to stream.
+     * @return
+     *     The character written as an unsigned char cast to an int or EOF on error.
+     */
+    int _putc(int c) {
+        return (write(&c, 1) == 1) ? 1 : EOF;
+    }
+
+    /**
+     * Override for Stream::_getc().
+     * @return
+     *     The character read.
+     */
+    int _getc() {
+        if (receiveBufferIndex == numBytesReceived) {
+            return EOF;
+        }
+
+        return receiveBuffer[receiveBufferIndex++];
+    }
+
+protected:
+    /**
+     * This callback allows the UART service to receive updates to the
+     * txCharacteristic. The application should forward the call to this
+     * function from the global onDataWritten() callback handler; if that's
+     * not used, this method can be used as a callback directly.
+     */
+    void onDataWritten(const GattWriteCallbackParams *params) {
+        if (params->handle == getTXCharacteristicHandle()) {
+            uint16_t bytesRead = params->len;
+            if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) {
+                numBytesReceived   = bytesRead;
+                receiveBufferIndex = 0;
+                memcpy(receiveBuffer, params->data, numBytesReceived);
+            }
+        }
+    }
+
+protected:
+    BLE                &ble;
+
+    uint8_t             receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive
+                                                                       *   inbound data before forwarding it to the
+                                                                       *   application. */
+
+    uint8_t             sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN];    /**< The local buffer into which outbound data is
+                                                                       *   accumulated before being pushed to the
+                                                                       *   rxCharacteristic. */
+    uint8_t             sendBufferIndex;
+    uint8_t             numBytesReceived;
+    uint8_t             receiveBufferIndex;
+
+    GattCharacteristic  txCharacteristic; /**< From the point of view of the external client, this is the characteristic
+                                           *   they'd write into in order to communicate with this application. */
+    GattCharacteristic  rxCharacteristic; /**< From the point of view of the external client, this is the characteristic
+                                           *   they'd read from in order to receive the bytes transmitted by this
+                                           *   application. */
+};
+
+#endif /* #ifndef __BLE_UART_SERVICE_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/URIBeaconConfigService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,472 @@
+/* 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 SERVICES_URIBEACONCONFIGSERVICE_H_
+#define SERVICES_URIBEACONCONFIGSERVICE_H_
+
+#include "ble/BLE.h"
+
+#ifdef YOTTA_CFG_MBED_OS
+#include "mbed-drivers/mbed.h"
+#else
+#include "mbed.h"
+#endif
+
+extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID];
+
+extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)];
+
+/**
+* @class URIBeaconConfigService
+* @brief UriBeacon Configuration Service. Can be used to set URL, adjust power levels, and set flags.
+* See http://uribeacon.org
+*
+*/
+class URIBeaconConfigService {
+  public:
+    /**
+     * @brief Transmission power modes for UriBeacon.
+     */
+    static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode. */
+    static const uint8_t TX_POWER_MODE_LOW    = 1; /*!< Low TX power mode. */
+    static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode. */
+    static const uint8_t TX_POWER_MODE_HIGH   = 3; /*!< High TX power mode. */
+    static const unsigned NUM_POWER_MODES     = 4; /*!< Number of power modes defined. */
+
+    static const int ADVERTISING_INTERVAL_MSEC = 1000;  // Advertising interval for config service.
+    static const int SERVICE_DATA_MAX = 31;             // Maximum size of service data in ADV packets.
+
+    typedef uint8_t Lock_t[16];               /* 128 bits. */
+    typedef int8_t PowerLevels_t[NUM_POWER_MODES];
+
+    static const int URI_DATA_MAX = 18;
+    typedef uint8_t  UriData_t[URI_DATA_MAX];
+
+    struct Params_t {
+        Lock_t        lock;
+        uint8_t       uriDataLength;
+        UriData_t     uriData;
+        uint8_t       flags;
+        PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels.
+        uint8_t       txPowerMode;    // Firmware power levels used with setTxPower().
+        uint16_t      beaconPeriod;
+    };
+
+    /**
+     * @param[ref]    ble
+     *                    BLE object for the underlying controller.
+     * @param[in/out] paramsIn
+     *                    Reference to application-visible beacon state, loaded
+     *                    from persistent storage at startup.
+     * @paramsP[in]   resetToDefaultsFlag
+     *                    Applies to the state of the 'paramsIn' parameter.
+     *                    If true, it indicates that paramsIn is potentially
+     *                    un-initialized, and default values should be used
+     *                    instead. Otherwise, paramsIn overrides the defaults.
+     * @param[in]     defaultUriDataIn
+     *                    Default un-encoded URI. Applies only if the resetToDefaultsFlag is true.
+     * @param[in]     defaultAdvPowerLevelsIn
+     *                    Default power-levels array. Applies only if the resetToDefaultsFlag is true.
+     */
+    URIBeaconConfigService(BLE          &bleIn,
+                           Params_t      &paramsIn,
+                           bool          resetToDefaultsFlag,
+                           const char   *defaultURIDataIn,
+                           PowerLevels_t &defaultAdvPowerLevelsIn) :
+        ble(bleIn),
+        params(paramsIn),
+        defaultUriDataLength(),
+        defaultUriData(),
+        defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
+        initSucceeded(false),
+        resetFlag(),
+        lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState),
+        lockChar(UUID_LOCK_CHAR, &params.lock),
+        uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
+                    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
+        unlockChar(UUID_UNLOCK_CHAR, &params.lock),
+        flagsChar(UUID_FLAGS_CHAR, &params.flags),
+        advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, &params.advPowerLevels),
+        txPowerModeChar(UUID_TX_POWER_MODE_CHAR, &params.txPowerMode),
+        beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, &params.beaconPeriod),
+        resetChar(UUID_RESET_CHAR, &resetFlag) {
+
+        encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength);
+        if (defaultUriDataLength > URI_DATA_MAX) {
+            return;
+        }
+
+        if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) {
+            resetToDefaultsFlag = true;
+        }
+        if (resetToDefaultsFlag) {
+            resetToDefaults();
+        } else {
+            updateCharacteristicValues();
+        }
+
+        lockedState = isLocked();
+
+        lockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::lockAuthorizationCallback);
+        unlockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::unlockAuthorizationCallback);
+        uriDataChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::uriDataWriteAuthorizationCallback);
+        flagsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>);
+        advPowerLevelsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<PowerLevels_t>);
+        txPowerModeChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::powerModeAuthorizationCallback);
+        beaconPeriodChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint16_t>);
+        resetChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>);
+
+        static GattCharacteristic *charTable[] = {
+            &lockedStateChar, &lockChar, &unlockChar, &uriDataChar,
+            &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar
+        };
+
+        GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+        ble.addService(configService);
+        ble.onDataWritten(this, &URIBeaconConfigService::onDataWrittenCallback);
+
+        setupURIBeaconConfigAdvertisements(); /* Set up advertising for the config service. */
+
+        initSucceeded = true;
+    }
+
+    bool configuredSuccessfully(void) const {
+        return initSucceeded;
+    }
+
+    /* Start out by advertising the config service for a limited time after
+     * startup. Then switch to the normal non-connectible beacon functionality.
+     */
+    void setupURIBeaconConfigAdvertisements()
+    {
+        const char DEVICE_NAME[] = "mUriBeacon Config";
+
+        ble.gap().clearAdvertisingPayload();
+
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+
+        // UUID is in different order in the ADV frame (!)
+        uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
+        for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
+            reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
+        }
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID));
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
+        ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME));
+        ble.gap().accumulateScanResponse(GapAdvertisingData::TX_POWER_LEVEL,
+                                         reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]),
+                                         sizeof(uint8_t));
+
+        ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]);
+        ble.gap().setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
+        ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+        ble.gap().setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
+    }
+
+    /* Helper function to switch to the non-connectible normal mode for UriBeacon. This gets called after a timeout. */
+    void setupURIBeaconAdvertisements()
+    {
+        /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
+        ble.shutdown();
+        ble.init();
+
+        // Fields from the service.
+        unsigned beaconPeriod                                 = params.beaconPeriod;
+        unsigned txPowerMode                                  = params.txPowerMode;
+        unsigned uriDataLength                                = params.uriDataLength;
+        URIBeaconConfigService::UriData_t &uriData            = params.uriData;
+        URIBeaconConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels;
+        uint8_t flags                                         = params.flags;
+
+        extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* Forward declaration; necessary to avoid a circular dependency. */
+        saveURIBeaconConfigParams(&params);
+
+        ble.gap().clearAdvertisingPayload();
+        ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]);
+        ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+        ble.gap().setAdvertisingInterval(beaconPeriod);
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID, sizeof(BEACON_UUID));
+
+        uint8_t serviceData[SERVICE_DATA_MAX];
+        unsigned serviceDataLen = 0;
+        serviceData[serviceDataLen++] = BEACON_UUID[0];
+        serviceData[serviceDataLen++] = BEACON_UUID[1];
+        serviceData[serviceDataLen++] = flags;
+        serviceData[serviceDataLen++] = advPowerLevels[txPowerMode];
+        for (unsigned j = 0; j < uriDataLength; j++) {
+            serviceData[serviceDataLen++] = uriData[j];
+        }
+        ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
+    }
+
+  private:
+    // True if the lock bits are non-zero.
+    bool isLocked() {
+        Lock_t testLock;
+        memset(testLock, 0, sizeof(Lock_t));
+        return memcmp(params.lock, testLock, sizeof(Lock_t));
+    }
+
+    /*
+     * This callback is invoked when a GATT client attempts to modify any of the
+     * characteristics of this service. These attempts are also applied to
+     * the internal state of this service object.
+     */
+    void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) {
+        uint16_t handle = writeParams->handle;
+
+        if (handle == lockChar.getValueHandle()) {
+            // Validated earlier,
+            memcpy(params.lock, writeParams->data, sizeof(Lock_t));
+            // Use isLocked() in case bits are being set to all zeros.
+            lockedState = isLocked();
+        } else if (handle == unlockChar.getValueHandle()) {
+            // Validated earlier.
+            memset(params.lock, 0, sizeof(Lock_t));
+            lockedState = false;
+        } else if (handle == uriDataChar.getValueHandle()) {
+            params.uriDataLength = writeParams->len;
+            memcpy(params.uriData, writeParams->data, params.uriDataLength);
+        } else if (handle == flagsChar.getValueHandle()) {
+            params.flags = *(writeParams->data);
+        } else if (handle == advPowerLevelsChar.getValueHandle()) {
+            memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
+        } else if (handle == txPowerModeChar.getValueHandle()) {
+            params.txPowerMode = *(writeParams->data);
+        } else if (handle == beaconPeriodChar.getValueHandle()) {
+            params.beaconPeriod = *((uint16_t *)(writeParams->data));
+
+            /* Remap beaconPeriod to within permissible bounds if necessary. */
+            if (params.beaconPeriod != 0) {
+                bool paramsUpdated = false;
+                if (params.beaconPeriod < ble.gap().getMinAdvertisingInterval()) {
+                    params.beaconPeriod = ble.gap().getMinAdvertisingInterval();
+                    paramsUpdated = true;
+                } else if (params.beaconPeriod > ble.gap().getMaxAdvertisingInterval()) {
+                    params.beaconPeriod = ble.gap().getMaxAdvertisingInterval();
+                    paramsUpdated = true;
+                }
+                if (paramsUpdated) {
+                    ble.gattServer().write(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
+                }
+            }
+        } else if (handle == resetChar.getValueHandle()) {
+            resetToDefaults();
+        }
+    }
+
+    /*
+     * Reset the default values.
+     */
+    void resetToDefaults(void) {
+        lockedState             = false;
+        memset(params.lock, 0, sizeof(Lock_t));
+        memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
+        params.uriDataLength    = defaultUriDataLength;
+        params.flags            = 0;
+        memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
+        params.txPowerMode      = TX_POWER_MODE_LOW;
+        params.beaconPeriod     = 1000;
+        updateCharacteristicValues();
+    }
+
+    /*
+     * Internal helper function used to update the GATT database following any
+     * change to the internal state of the service object.
+     */
+    void updateCharacteristicValues(void) {
+        ble.gattServer().write(lockedStateChar.getValueHandle(), &lockedState, 1);
+        ble.gattServer().write(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
+        ble.gattServer().write(flagsChar.getValueHandle(), &params.flags, 1);
+        ble.gattServer().write(beaconPeriodChar.getValueHandle(),
+                                      reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
+        ble.gattServer().write(txPowerModeChar.getValueHandle(), &params.txPowerMode, 1);
+        ble.gattServer().write(advPowerLevelsChar.getValueHandle(),
+                                      reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
+    }
+
+protected:
+    void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(Lock_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+
+    void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (!lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        } else if (authParams->len != sizeof(Lock_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(uint8_t)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+    template <typename T>
+    void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
+        if (lockedState) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
+        } else if (authParams->len != sizeof(T)) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
+        } else if (authParams->offset != 0) {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
+        } else {
+            authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
+        }
+    }
+
+protected:
+    BLE           &ble;
+    Params_t      &params;
+
+    size_t        defaultUriDataLength;   // Default value that is restored on reset.
+    UriData_t     defaultUriData;         // Default value that is restored on reset.
+    PowerLevels_t &defaultAdvPowerLevels; // Default value that is restored on reset.
+
+    uint8_t       lockedState;
+    bool          initSucceeded;
+    uint8_t       resetFlag;
+
+    ReadOnlyGattCharacteristic<uint8_t>        lockedStateChar;
+    WriteOnlyGattCharacteristic<Lock_t>        lockChar;
+    GattCharacteristic                         uriDataChar;
+    WriteOnlyGattCharacteristic<Lock_t>        unlockChar;
+    ReadWriteGattCharacteristic<uint8_t>       flagsChar;
+    ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar;
+    ReadWriteGattCharacteristic<uint8_t>       txPowerModeChar;
+    ReadWriteGattCharacteristic<uint16_t>      beaconPeriodChar;
+    WriteOnlyGattCharacteristic<uint8_t>       resetChar;
+
+public:
+    /*
+     *  Encode a human-readable URI into the binary format defined by the UriBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
+     */
+    static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) {
+        const char *prefixes[] = {
+            "http://www.",
+            "https://www.",
+            "http://",
+            "https://",
+            "urn:uuid:"
+        };
+        const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
+        const char *suffixes[] = {
+            ".com/",
+            ".org/",
+            ".edu/",
+            ".net/",
+            ".info/",
+            ".biz/",
+            ".gov/",
+            ".com",
+            ".org",
+            ".edu",
+            ".net",
+            ".info",
+            ".biz",
+            ".gov"
+        };
+        const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
+
+        sizeofURIDataOut = 0;
+        memset(uriDataOut, 0, sizeof(UriData_t));
+
+        if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) {
+            return;
+        }
+
+        /*
+         * handle prefix
+         */
+        for (unsigned i = 0; i < NUM_PREFIXES; i++) {
+            size_t prefixLen = strlen(prefixes[i]);
+            if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
+                uriDataOut[sizeofURIDataOut++]  = i;
+                uriDataIn                      += prefixLen;
+                break;
+            }
+        }
+
+        /*
+         * Handle suffixes.
+         */
+        while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) {
+            /* check for suffix match */
+            unsigned i;
+            for (i = 0; i < NUM_SUFFIXES; i++) {
+                size_t suffixLen = strlen(suffixes[i]);
+                if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
+                    uriDataOut[sizeofURIDataOut++]  = i;
+                    uriDataIn                      += suffixLen;
+                    break; /* From the for loop for checking against suffixes. */
+                }
+            }
+            /* This is the default case where we've got an ordinary character that doesn't match a suffix. */
+            if (i == NUM_SUFFIXES) {
+                uriDataOut[sizeofURIDataOut++] = *uriDataIn;
+                ++uriDataIn;
+            }
+        }
+    }
+};
+
+#endif  // SERVICES_URIBEACONCONFIGSERVICE_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/ble/services/iBeacon.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,75 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __BLE_IBEACON_H__
+#define __BLE_IBEACON_H__
+
+#include "core_cmInstr.h"
+#include "ble/BLE.h"
+
+/**
+* @class iBeacon
+* @brief iBeacon Service. This sets up a device to broadcast advertising packets to mimic an iBeacon.
+*/
+class iBeacon
+{
+public:
+    typedef const uint8_t LocationUUID_t[16];
+
+    union Payload {
+        uint8_t raw[25];
+        struct {
+            uint16_t companyID;
+            uint8_t ID;
+            uint8_t len;
+            uint8_t proximityUUID[16];
+            uint16_t majorNumber;
+            uint16_t minorNumber;
+            uint8_t txPower;
+        };
+
+        Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) :
+            companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower)
+        {
+            memcpy(proximityUUID, uuid, sizeof(LocationUUID_t));
+        }
+    };
+
+public:
+    iBeacon(BLE            &_ble,
+            LocationUUID_t  uuid,
+            uint16_t        majNum,
+            uint16_t        minNum,
+            uint8_t         txP    = 0xC8,
+            uint16_t        compID = 0x004C) :
+        ble(_ble), data(uuid, majNum, minNum, txP, compID)
+    {
+        // Generate the 0x020106 part of the iBeacon Prefix.
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
+        // Generate the 0x1AFF part of the iBeacon Prefix.
+        ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw));
+
+        // Set advertising type.
+        ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+    }
+
+protected:
+    BLE     &ble;
+    Payload  data;
+};
+
+typedef iBeacon iBeaconService; /* This type-alias is deprecated. Please use iBeacon directly. This alias may be dropped from a future release. */
+
+#endif //__BLE_IBEACON_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/module.json	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+{
+  "name": "ble",
+  "version": "2.5.0",
+  "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.",
+  "keywords": [
+    "Bluetooth",
+    "BLE",
+    "mbed",
+    "mbed-official"
+  ],
+  "author": "Rohit Grover",
+  "repository": {
+    "url": "https://github.com/ARMmbed/ble.git",
+    "type": "git"
+  },
+  "homepage": "https://developer.mbed.org/teams/Bluetooth-Low-Energy/",
+  "licenses": [
+    {
+      "url": "https://spdx.org/licenses/Apache-2.0",
+      "type": "Apache-2.0"
+    }
+  ],
+  "dependencies": {},
+  "targetDependencies": {
+    "st-ble-shield": {
+      "x-nucleo-idb0xa1": "^2.0.0"
+    },
+    "nrf51822": {
+      "ble-nrf51822": "^2.2.8"
+    },
+    "cordio": {
+      "ble-wicentric": "~0.0.4"
+    },
+    "mbed-classic": {
+      "mbed-classic": "~0.0.1"
+    },
+    "mbed-os": {
+      "mbed-drivers": "*",
+      "compiler-polyfill": "^1.2.1"
+    }
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/BLE.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,229 @@
+/* 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 "ble/BLE.h"
+#include "ble/BLEInstanceBase.h"
+
+#if defined(TARGET_OTA_ENABLED)
+#include "ble/services/DFUService.h"
+#endif
+
+ble_error_t
+BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback)
+{
+    ble_error_t err = transport->init(instanceID, callback);
+    if (err != BLE_ERROR_NONE) {
+        return err;
+    }
+
+    /* Platforms enabled for DFU should introduce the DFU Service into
+     * applications automatically. */
+#if defined(TARGET_OTA_ENABLED)
+    //static DFUService dfu(*this); // defined static so that the object remains alive
+#endif // TARGET_OTA_ENABLED
+
+    return BLE_ERROR_NONE;
+}
+
+/**
+ * BLE::Instance() and BLE constructor rely upon a static array of initializers
+ * to create actual BLE transport instances. A description of these instances
+ * and initializers is supposed to be put in some .json file contributing to
+ * yotta's configuration (typically in the target definition described by
+ * target.json). Here's a sample:
+ *
+ *  "config": {
+ *    ...
+ *    "ble_instances": {
+ *      "count": 1,
+ *      "0" : {
+ *        "initializer" : "createBLEInstance"
+ *      }
+ *    }
+ *    ...
+ *  }
+ *
+ * The following macros result in translating the above config into a static
+ * array: instanceConstructors.
+ */
+#ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
+#define CONCATENATE(A, B) A ## B
+#define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */
+
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
+/* ... add more of the above if ever needed */
+
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
+#elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
+/*
+ * The following applies when building without yotta. By default BLE_API provides
+ * a trivial initializer list containing a single constructor: createBLEInstance.
+ * This may be overridden.
+ */
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
+#endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
+
+typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
+static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
+#ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
+    INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
+#else
+    INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
+#endif
+};
+
+BLE &
+BLE::Instance(InstanceID_t id)
+{
+    static BLE *singletons[NUM_INSTANCES];
+    if (id < NUM_INSTANCES) {
+        if (singletons[id] == NULL) {
+            singletons[id] = new BLE(id); /* This object will never be freed. */
+        }
+
+        return *singletons[id];
+    }
+
+    /* we come here only in the case of a bad interfaceID. */
+    static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
+    return badSingleton;
+}
+
+BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport()
+{
+    static BLEInstanceBase *transportInstances[NUM_INSTANCES];
+
+    if (instanceID < NUM_INSTANCES) {
+        if (!transportInstances[instanceID]) {
+            transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
+        }
+        transport = transportInstances[instanceID];
+    } else {
+        transport = NULL;
+    }
+}
+
+bool BLE::hasInitialized(void) const
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->hasInitialized();
+}
+
+ble_error_t BLE::shutdown(void)
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->shutdown();
+}
+
+const char *BLE::getVersion(void)
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getVersion();
+}
+
+const Gap &BLE::gap() const
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGap();
+}
+
+Gap &BLE::gap()
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGap();
+}
+
+const GattServer& BLE::gattServer() const
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGattServer();
+}
+
+GattServer& BLE::gattServer()
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGattServer();
+}
+
+const GattClient& BLE::gattClient() const
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGattClient();
+}
+
+GattClient& BLE::gattClient()
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getGattClient();
+}
+
+const SecurityManager& BLE::securityManager() const
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getSecurityManager();
+}
+
+SecurityManager& BLE::securityManager()
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    return transport->getSecurityManager();
+}
+
+void BLE::waitForEvent(void)
+{
+    if (!transport) {
+        error("bad handle to underlying transport");
+    }
+
+    transport->waitForEvent();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/DiscoveredCharacteristic.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
+ */
+
+#include "ble/DiscoveredCharacteristic.h"
+#include "ble/GattClient.h"
+
+ble_error_t
+DiscoveredCharacteristic::read(uint16_t offset) const
+{
+    if (!props.read()) {
+        return BLE_ERROR_OPERATION_NOT_PERMITTED;
+    }
+
+    if (!gattc) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    return gattc->read(connHandle, valueHandle, offset);
+}
+
+struct OneShotReadCallback {
+    static void launch(GattClient* client, Gap::Handle_t connHandle,
+                       GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) {
+        OneShotReadCallback* oneShot = new OneShotReadCallback(client, connHandle, handle, cb);
+        oneShot->attach();
+        // delete will be made when this callback is called
+    }
+
+private:
+    OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle,
+                        GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) :
+        _client(client),
+        _connHandle(connHandle),
+        _handle(handle),
+        _callback(cb) { }
+
+    void attach() {
+        _client->onDataRead(makeFunctionPointer(this, &OneShotReadCallback::call));
+    }
+
+    void call(const GattReadCallbackParams* params) {
+        // verifiy that it is the right characteristic on the right connection
+        if (params->connHandle == _connHandle && params->handle == _handle) {
+            _callback(params);
+            _client->onDataRead().detach(makeFunctionPointer(this, &OneShotReadCallback::call));
+            delete this;
+        }
+    }
+
+    GattClient* _client;
+    Gap::Handle_t _connHandle;
+    GattAttribute::Handle_t _handle;
+    GattClient::ReadCallback_t _callback;
+};
+
+ble_error_t DiscoveredCharacteristic::read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const {
+    ble_error_t error = read(offset);
+    if (error) {
+        return error;
+    }
+
+    OneShotReadCallback::launch(gattc, connHandle, valueHandle, onRead);
+
+    return error;
+}
+
+ble_error_t
+DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const
+{
+    if (!props.write()) {
+        return BLE_ERROR_OPERATION_NOT_PERMITTED;
+    }
+
+    if (!gattc) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value);
+}
+
+ble_error_t
+DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const
+{
+    if (!props.writeWoResp()) {
+        return BLE_ERROR_OPERATION_NOT_PERMITTED;
+    }
+
+    if (!gattc) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value);
+}
+
+struct OneShotWriteCallback {
+    static void launch(GattClient* client, Gap::Handle_t connHandle,
+                       GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) {
+        OneShotWriteCallback* oneShot = new OneShotWriteCallback(client, connHandle, handle, cb);
+        oneShot->attach();
+        // delete will be made when this callback is called
+    }
+
+private:
+    OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle,
+                        GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) :
+        _client(client),
+        _connHandle(connHandle),
+        _handle(handle),
+        _callback(cb) { }
+
+    void attach() {
+        _client->onDataWritten(makeFunctionPointer(this, &OneShotWriteCallback::call));
+    }
+
+    void call(const GattWriteCallbackParams* params) {
+        // verifiy that it is the right characteristic on the right connection
+        if (params->connHandle == _connHandle && params->handle == _handle) {
+            _callback(params);
+            _client->onDataWritten().detach(makeFunctionPointer(this, &OneShotWriteCallback::call));
+            delete this;
+        }
+    }
+
+    GattClient* _client;
+    Gap::Handle_t _connHandle;
+    GattAttribute::Handle_t _handle;
+    GattClient::WriteCallback_t _callback;
+};
+
+ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onRead) const {
+    ble_error_t error = write(length, value);
+    if (error) {
+        return error;
+    }
+
+    OneShotWriteCallback::launch(gattc, connHandle, valueHandle, onRead);
+
+    return error;
+}
+
+ble_error_t DiscoveredCharacteristic::discoverDescriptors(
+    const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& onCharacteristicDiscovered, 
+    const CharacteristicDescriptorDiscovery::TerminationCallback_t& onTermination) const {
+
+    if(!gattc) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    ble_error_t err = gattc->discoverCharacteristicDescriptors(
+        *this, onCharacteristicDiscovered, onTermination
+    );
+
+    return err;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/GapScanningParams.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
+ */
+
+#include "ble/Gap.h"
+#include "ble/GapScanningParams.h"
+
+GapScanningParams::GapScanningParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) :
+    _interval(MSEC_TO_SCAN_DURATION_UNITS(interval)),
+    _window(MSEC_TO_SCAN_DURATION_UNITS(window)),
+    _timeout(timeout),
+    _activeScanning(activeScanning) {
+    /* stay within limits */
+    if (_interval < SCAN_INTERVAL_MIN) {
+        _interval = SCAN_INTERVAL_MIN;
+    }
+    if (_interval > SCAN_INTERVAL_MAX) {
+        _interval = SCAN_INTERVAL_MAX;
+    }
+    if (_window < SCAN_WINDOW_MIN) {
+        _window = SCAN_WINDOW_MIN;
+    }
+    if (_window > SCAN_WINDOW_MAX) {
+        _window = SCAN_WINDOW_MAX;
+    }
+}
+
+ble_error_t
+GapScanningParams::setInterval(uint16_t newIntervalInMS)
+{
+    uint16_t newInterval = MSEC_TO_SCAN_DURATION_UNITS(newIntervalInMS);
+    if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) {
+        _interval = newInterval;
+        return BLE_ERROR_NONE;
+    }
+
+    return BLE_ERROR_PARAM_OUT_OF_RANGE;
+}
+
+ble_error_t
+GapScanningParams::setWindow(uint16_t newWindowInMS)
+{
+    uint16_t newWindow = MSEC_TO_SCAN_DURATION_UNITS(newWindowInMS);
+    if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) {
+        _window   = newWindow;
+        return BLE_ERROR_NONE;
+    }
+
+    return BLE_ERROR_PARAM_OUT_OF_RANGE;
+}
+
+ble_error_t
+GapScanningParams::setTimeout(uint16_t newTimeout)
+{
+    _timeout  = newTimeout;
+    return BLE_ERROR_NONE;
+}
+
+void
+GapScanningParams::setActiveScanning(bool activeScanning)
+{
+    _activeScanning = activeScanning;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/services/DFUService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,44 @@
+/* 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 TARGET_NRF51822 /* DFU only supported on nrf51 platforms */
+
+#include "ble/services/DFUService.h"
+
+const uint8_t              DFUServiceBaseUUID[] = {
+    0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0xEF, 0xDE,
+    0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint16_t             DFUServiceShortUUID                      = 0x1530;
+const uint16_t             DFUServiceControlCharacteristicShortUUID = 0x1531;
+const uint16_t             DFUServicePacketCharacteristicShortUUID  = 0x1532;
+
+const uint8_t              DFUServiceUUID[] = {
+    0x00, 0x00, (uint8_t)(DFUServiceShortUUID >> 8), (uint8_t)(DFUServiceShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+    0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint8_t              DFUServiceControlCharacteristicUUID[] = {
+    0x00, 0x00, (uint8_t)(DFUServiceControlCharacteristicShortUUID >> 8), (uint8_t)(DFUServiceControlCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+    0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint8_t              DFUServicePacketCharacteristicUUID[] = {
+    0x00, 0x00, (uint8_t)(DFUServicePacketCharacteristicShortUUID >> 8), (uint8_t)(DFUServicePacketCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+    0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+
+DFUService::ResetPrepare_t DFUService::handoverCallback = NULL;
+
+#endif /* #ifdef TARGET_NRF51822 */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/services/UARTService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,41 @@
+/* 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 "ble/services/UARTService.h"
+
+const uint8_t  UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID] = {
+    0x6E, 0x40, 0x00, 0x00, 0xB5, 0xA3, 0xF3, 0x93,
+    0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint16_t UARTServiceShortUUID                 = 0x0001;
+const uint16_t UARTServiceTXCharacteristicShortUUID = 0x0002;
+const uint16_t UARTServiceRXCharacteristicShortUUID = 0x0003;
+const uint8_t  UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID] = {
+    0x6E, 0x40, (uint8_t)(UARTServiceShortUUID >> 8), (uint8_t)(UARTServiceShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+    0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint8_t  UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID] = {
+    0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0,
+    0x93, 0xF3, 0xA3, 0xB5, (uint8_t)(UARTServiceShortUUID & 0xFF), (uint8_t)(UARTServiceShortUUID >> 8), 0x40, 0x6E
+};
+const uint8_t  UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] = {
+    0x6E, 0x40, (uint8_t)(UARTServiceTXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceTXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+    0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint8_t  UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] = {
+    0x6E, 0x40, (uint8_t)(UARTServiceRXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceRXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+    0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/BLE_API/source/services/URIBeaconConfigService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,35 @@
+/* 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 "ble/services/URIBeaconConfigService.h"
+
+#define UUID_URI_BEACON(FIRST, SECOND) {                         \
+        0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba,       \
+        0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8,          \
+}
+
+const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID]    = UUID_URI_BEACON(0x20, 0x80);
+const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID]       = UUID_URI_BEACON(0x20, 0x81);
+const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]             = UUID_URI_BEACON(0x20, 0x82);
+const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]           = UUID_URI_BEACON(0x20, 0x83);
+const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID]         = UUID_URI_BEACON(0x20, 0x84);
+const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID]            = UUID_URI_BEACON(0x20, 0x85);
+const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86);
+const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID]    = UUID_URI_BEACON(0x20, 0x87);
+const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID]    = UUID_URI_BEACON(0x20, 0x88);
+const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID]            = UUID_URI_BEACON(0x20, 0x89);
+
+const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/LICENSE	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/README.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,39 @@
+# microbit-dal
+
+The core set of drivers, mechanisms and types that make up the micro:bit runtime.
+
+## Overview
+
+The micro:bit runtime provides an easy to use environment for programming the BBC micro:bit in the C/C++ language, written by Lancaster University. It contains device drivers for all the hardware capabilities of the micro:bit, and also a suite of runtime mechanisms to make programming the micro:bit easier and more flexible. These range from control of the LED matrix display to peer-to-peer radio communication and secure Bluetooth Low Energy services. The micro:bit runtime is proudly built on the ARM mbed and Nordic nrf51 platforms.
+
+In addition to supporting development in C/C++, the runtime is also designed specifically to support higher level languages provided by our partners that target the micro:bit. It is currently used as a support library for all the languages on the BBC www.microbit.co.uk website, including the Microsoft Block Editor, Microsoft Touch Develop, Code Kingdoms JavaScript and Micropython languages.
+
+## Links
+
+[micro:bit runtime docs](http://lancaster-university.github.io/microbit-docs/) | [uBit](https://github.com/lancaster-university/microbit) |  [samples](https://github.com/lancaster-university/microbit-samples)
+
+## Build Environments
+
+| Build Environment | Documentation |
+| ------------- |-------------|
+| ARM mbed online | http://lancaster-university.github.io/microbit-docs/online-toolchains/#mbed |
+| yotta  | http://lancaster-university.github.io/microbit-docs/offline-toolchains/#yotta |
+
+
+
+## Hello World!
+
+```cpp
+#include "MicroBitDisplay.h"
+
+MicroBitDisplay display;
+
+int main()
+{
+    display.scroll("Hello world!");
+}
+```
+
+## BBC Community Guidelines
+
+[BBC Community Guidelines](https://www.microbit.co.uk/help#sect_cg)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/ExternalEvents.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,41 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef EXTERNAL_EVENTS_H
+#define EXTERNAL_EVENTS_H
+
+/**
+  * This header file contains IDs and event codes use for Bluetooth communication.
+  */
+
+#define MICROBIT_ID_BLE             1000
+#define MICROBIT_ID_BLE_UART        1200
+
+#define MICROBIT_BLE_EVT_CONNECTED      1
+#define MICROBIT_BLE_EVT_DISCONNECTED   2
+
+#include "MESEvents.h"
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MESEvents.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,117 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MES_EVENTS_H
+#define MES_EVENTS_H
+
+//
+// MicroBit Event Service Event ID's and values
+//
+
+//
+// Events that master devices respond to:
+//
+#define MES_REMOTE_CONTROL_ID               1001
+#define MES_REMOTE_CONTROL_EVT_PLAY         1
+#define MES_REMOTE_CONTROL_EVT_PAUSE        2
+#define MES_REMOTE_CONTROL_EVT_STOP         3
+#define MES_REMOTE_CONTROL_EVT_NEXTTRACK    4
+#define MES_REMOTE_CONTROL_EVT_PREVTRACK    5
+#define MES_REMOTE_CONTROL_EVT_FORWARD      6
+#define MES_REMOTE_CONTROL_EVT_REWIND       7
+#define MES_REMOTE_CONTROL_EVT_VOLUMEUP     8
+#define MES_REMOTE_CONTROL_EVT_VOLUMEDOWN   9
+
+
+#define MES_CAMERA_ID                       1002
+#define MES_CAMERA_EVT_LAUNCH_PHOTO_MODE    1
+#define MES_CAMERA_EVT_LAUNCH_VIDEO_MODE    2
+#define MES_CAMERA_EVT_TAKE_PHOTO           3
+#define MES_CAMERA_EVT_START_VIDEO_CAPTURE  4
+#define MES_CAMERA_EVT_STOP_VIDEO_CAPTURE   5
+#define MES_CAMERA_EVT_STOP_PHOTO_MODE      6
+#define MES_CAMERA_EVT_STOP_VIDEO_MODE      7
+#define MES_CAMERA_EVT_TOGGLE_FRONT_REAR    8
+
+
+#define MES_ALERTS_ID                       1004
+#define MES_ALERT_EVT_DISPLAY_TOAST         1
+#define MES_ALERT_EVT_VIBRATE               2
+#define MES_ALERT_EVT_PLAY_SOUND            3
+#define MES_ALERT_EVT_PLAY_RINGTONE         4
+#define MES_ALERT_EVT_FIND_MY_PHONE         5
+#define MES_ALERT_EVT_ALARM1                6
+#define MES_ALERT_EVT_ALARM2                7
+#define MES_ALERT_EVT_ALARM3                8
+#define MES_ALERT_EVT_ALARM4                9
+#define MES_ALERT_EVT_ALARM5                10
+#define MES_ALERT_EVT_ALARM6                11
+
+//
+// Events that master devices generate:
+//
+#define MES_SIGNAL_STRENGTH_ID              1101
+#define MES_SIGNAL_STRENGTH_EVT_NO_BAR      1
+#define MES_SIGNAL_STRENGTH_EVT_ONE_BAR     2
+#define MES_SIGNAL_STRENGTH_EVT_TWO_BAR     3
+#define MES_SIGNAL_STRENGTH_EVT_THREE_BAR   4
+#define MES_SIGNAL_STRENGTH_EVT_FOUR_BAR    5
+
+
+#define MES_DEVICE_INFO_ID                  1103
+#define MES_DEVICE_ORIENTATION_LANDSCAPE    1
+#define MES_DEVICE_ORIENTATION_PORTRAIT     2
+#define MES_DEVICE_GESTURE_NONE             3
+#define MES_DEVICE_GESTURE_DEVICE_SHAKEN    4
+#define MES_DEVICE_DISPLAY_OFF              5
+#define MES_DEVICE_DISPLAY_ON               6
+#define MES_DEVICE_INCOMING_CALL            7
+#define MES_DEVICE_INCOMING_MESSAGE         8
+
+
+#define MES_DPAD_CONTROLLER_ID              1104
+#define MES_DPAD_BUTTON_A_DOWN              1
+#define MES_DPAD_BUTTON_A_UP                2
+#define MES_DPAD_BUTTON_B_DOWN              3
+#define MES_DPAD_BUTTON_B_UP                4
+#define MES_DPAD_BUTTON_C_DOWN              5
+#define MES_DPAD_BUTTON_C_UP                6
+#define MES_DPAD_BUTTON_D_DOWN              7
+#define MES_DPAD_BUTTON_D_UP                8
+#define MES_DPAD_BUTTON_1_DOWN              9
+#define MES_DPAD_BUTTON_1_UP                10
+#define MES_DPAD_BUTTON_2_DOWN              11
+#define MES_DPAD_BUTTON_2_UP                12
+#define MES_DPAD_BUTTON_3_DOWN              13
+#define MES_DPAD_BUTTON_3_UP                14
+#define MES_DPAD_BUTTON_4_DOWN              15
+#define MES_DPAD_BUTTON_4_UP                16
+
+//
+// Events that typically use radio broadcast:
+//
+#define MES_BROADCAST_GENERAL_ID            2000
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitAccelerometerService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,83 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_ACCELEROMETER_SERVICE_H
+#define MICROBIT_ACCELEROMETER_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitAccelerometer.h"
+#include "EventModel.h"
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitAccelerometerServiceUUID[];
+extern const uint8_t  MicroBitAccelerometerServiceDataUUID[];
+extern const uint8_t  MicroBitAccelerometerServicePeriodUUID[];
+
+
+/**
+  * Class definition for a MicroBit BLE Accelerometer Service.
+  * Provides access to live accelerometer data via Bluetooth, and provides basic configuration options.
+  */
+class MicroBitAccelerometerService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the AccelerometerService
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _accelerometer An instance of MicroBitAccelerometer.
+      */
+    MicroBitAccelerometerService(BLEDevice &_ble, MicroBitAccelerometer &_acclerometer);
+
+
+    private:
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+     * Accelerometer update callback
+     */
+    void accelerometerUpdate(MicroBitEvent e);
+
+    // Bluetooth stack we're running on.
+    BLEDevice           	&ble;
+	MicroBitAccelerometer	&accelerometer;
+
+    // memory for our 8 bit control characteristics.
+    uint16_t            accelerometerDataCharacteristicBuffer[3];
+    uint16_t            accelerometerPeriodCharacteristicBuffer;
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t accelerometerDataCharacteristicHandle;
+    GattAttribute::Handle_t accelerometerPeriodCharacteristicHandle;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitBLEManager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,215 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_BLE_MANAGER_H
+#define MICROBIT_BLE_MANAGER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+/*
+ * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+#if !defined (__arm)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+#include "ble/BLE.h"
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined (__arm)
+#pragma GCC diagnostic pop
+#endif
+
+#include "ble/services/DeviceInformationService.h"
+#include "MicroBitDFUService.h"
+#include "MicroBitEventService.h"
+#include "MicroBitLEDService.h"
+#include "MicroBitAccelerometerService.h"
+#include "MicroBitMagnetometerService.h"
+#include "MicroBitButtonService.h"
+#include "MicroBitIOPinService.h"
+#include "MicroBitTemperatureService.h"
+#include "ExternalEvents.h"
+#include "MicroBitButton.h"
+#include "MicroBitStorage.h"
+
+#define MICROBIT_BLE_PAIR_REQUEST               0x01
+#define MICROBIT_BLE_PAIR_COMPLETE              0x02
+#define MICROBIT_BLE_PAIR_PASSCODE              0x04
+#define MICROBIT_BLE_PAIR_SUCCESSFUL            0x08
+
+#define MICROBIT_BLE_PAIRING_TIMEOUT	        90
+#define MICROBIT_BLE_POWER_LEVELS               8
+#define MICROBIT_BLE_MAXIMUM_BONDS              4
+#define MICROBIT_BLE_ENABLE_BONDING 	        true
+
+extern const int8_t MICROBIT_BLE_POWER_LEVEL[];
+
+struct BLESysAttribute
+{
+    uint8_t         sys_attr[8];
+};
+
+struct BLESysAttributeStore
+{
+    BLESysAttribute sys_attrs[MICROBIT_BLE_MAXIMUM_BONDS];
+};
+
+/**
+  * Class definition for the MicroBitBLEManager.
+  *
+  */
+class MicroBitBLEManager : MicroBitComponent
+{
+    public:
+
+	// The mbed abstraction of the BlueTooth Low Energy (BLE) hardware
+    BLEDevice                       *ble;
+
+    //an instance of MicroBitStorage used to store sysAttrs from softdevice
+    MicroBitStorage* storage;
+
+    /**
+     * Constructor.
+     *
+     * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
+     *
+     * @param _storage an instance of MicroBitStorage used to persist sys attribute information. (This is required for compatability with iOS).
+     *
+     * @note The BLE stack *cannot*  be brought up in a static context (the software simply hangs or corrupts itself).
+     * Hence, the init() member function should be used to initialise the BLE stack.
+     */
+    MicroBitBLEManager(MicroBitStorage& _storage);
+
+    /**
+     * Constructor.
+     *
+     * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
+     *
+     * @note The BLE stack *cannot*  be brought up in a static context (the software simply hangs or corrupts itself).
+     * Hence, the init() member function should be used to initialise the BLE stack.
+     */
+    MicroBitBLEManager();
+
+    /**
+      * Post constructor initialisation method as the BLE stack cannot be brought
+      * up in a static context.
+      *
+      * @param deviceName The name used when advertising
+      * @param serialNumber The serial number exposed by the device information service
+      * @param messageBus An instance of an EventModel, used during pairing.
+      * @param enableBonding If true, the security manager enabled bonding.
+      *
+      * @code
+      * bleManager.init(uBit.getName(), uBit.getSerial(), uBit.messageBus, true);
+      * @endcode
+      */
+    void init(ManagedString deviceName, ManagedString serialNumber, EventModel& messageBus, bool enableBonding);
+
+    /**
+     * Change the output power level of the transmitter to the given value.
+     *
+     * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
+     *
+     * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
+     *
+     * @code
+     * // maximum transmission power.
+     * bleManager.setTransmitPower(7);
+     * @endcode
+     */
+    int setTransmitPower(int power);
+
+    /**
+     * Enter pairing mode. This is mode is called to initiate pairing, and to enable FOTA programming
+     * of the micro:bit in cases where BLE is disabled during normal operation.
+     *
+     * @param display An instance of MicroBitDisplay used when displaying pairing information.
+     * @param authorizationButton The button to use to authorise a pairing request.
+     *
+     * @code
+     * // initiate pairing mode
+     * bleManager.pairingMode(uBit.display, uBit.buttonA);
+     * @endcode
+     */
+    void pairingMode(MicroBitDisplay &display, MicroBitButton &authorisationButton);
+
+    /**
+     * When called, the micro:bit will begin advertising for a predefined period,
+     * MICROBIT_BLE_ADVERTISING_TIMEOUT seconds to bonded devices.
+     */
+    void advertise();
+
+    /**
+     * Determines the number of devices currently bonded with this micro:bit.
+     * @return The number of active bonds.
+     */
+    int getBondCount();
+
+	/**
+	 * A request to pair has been received from a BLE device.
+     * If we're in pairing mode, display the passkey to the user.
+     * Also, purge the bonding table if it has reached capacity.
+     *
+     * @note for internal use only.
+	 */
+	void pairingRequested(ManagedString passKey);
+
+	/**
+	 * A pairing request has been sucessfully completed.
+	 * If we're in pairing mode, display a success or failure message.
+     *
+     * @note for internal use only.
+	 */
+	void pairingComplete(bool success);
+
+	/**
+     * Periodic callback in thread context.
+     * We use this here purely to safely issue a disconnect operation after a pairing operation is complete.
+	 */
+	void idleTick();
+
+    private:
+
+	/**
+	 * Displays the device's ID code as a histogram on the provided MicroBitDisplay instance.
+     *
+     * @param display The display instance used for displaying the histogram.
+	 */
+	void showNameHistogram(MicroBitDisplay &display);
+
+	int				pairingStatus;
+	ManagedString	passKey;
+	ManagedString	deviceName;
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitButtonService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,80 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_BUTTON_SERVICE_H
+#define MICROBIT_BUTTON_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "EventModel.h"
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitButtonServiceUUID[];
+extern const uint8_t  MicroBitButtonAServiceDataUUID[];
+extern const uint8_t  MicroBitButtonBServiceDataUUID[];
+
+
+/**
+  * Class definition for a MicroBit BLE Button Service.
+  * Provides access to live button data via BLE, and provides basic configuration options.
+  */
+class MicroBitButtonService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the ButtonService
+      * @param _ble The instance of a BLE device that we're running on.
+      */
+    MicroBitButtonService(BLEDevice &_ble);
+
+
+    private:
+
+    /**
+     * Button A update callback
+     */
+    void buttonAUpdate(MicroBitEvent e);
+
+    /**
+     * Button B update callback
+     */
+    void buttonBUpdate(MicroBitEvent e);
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+
+    // memory for our 8 bit control characteristics.
+    uint8_t            buttonADataCharacteristicBuffer;
+    uint8_t            buttonBDataCharacteristicBuffer;
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t buttonADataCharacteristicHandle;
+    GattAttribute::Handle_t buttonBDataCharacteristicHandle;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitDFUService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,103 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_DFU_SERVICE_H
+#define MICROBIT_DFU_SERVICE_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitEvent.h"
+
+// MicroBit ControlPoint OpCodes
+// Requests transfer to the Nordic DFU bootloader.
+#define MICROBIT_DFU_OPCODE_START_DFU       1
+
+// visual ID code constants
+#define MICROBIT_DFU_HISTOGRAM_WIDTH        5
+#define MICROBIT_DFU_HISTOGRAM_HEIGHT       5
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitDFUServiceUUID[];
+extern const uint8_t  MicroBitDFUServiceControlCharacteristicUUID[];
+extern const uint8_t  MicroBitDFUServiceFlashCodeCharacteristicUUID[];
+
+// Handle on the memory resident Nordic bootloader.
+extern "C" void bootloader_start(void);
+
+/**
+  * Class definition for a MicroBit Device Firmware Update loader.
+  * This service allows hexes to be flashed remotely from another Bluetooth
+  * device.
+  */
+class MicroBitDFUService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Initialise the Device Firmware Update service.
+      * @param _ble The instance of a BLE device that we're running on.
+      */
+    MicroBitDFUService(BLEDevice &_ble);
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    virtual void onDataWritten(const GattWriteCallbackParams *params);
+
+    private:
+
+    // State of paiting process.
+    bool authenticated;
+    bool flashCodeRequested;
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+
+    // memory for our 8 bit control characteristic.
+    uint8_t             controlByte;
+
+    // BLE pairing name of this device, encoded as an integer.
+    uint32_t            flashCode;
+
+    GattAttribute::Handle_t microBitDFUServiceControlCharacteristicHandle;
+    GattAttribute::Handle_t microBitDFUServiceFlashCodeCharacteristicHandle;
+
+    // Displays the device's ID code as a histogram on the LED matrix display.
+    void showNameHistogram();
+
+    // Displays an acknowledgement on the LED matrix display.
+    void showTick();
+
+    // Update BLE characteristic to release our flash code.
+    void releaseFlashCode();
+
+    // Event handlers for button clicks.
+    void onButtonA(MicroBitEvent e);
+    void onButtonB(MicroBitEvent e);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitEventService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,111 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_EVENT_SERVICE_H
+#define MICROBIT_EVENT_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitEvent.h"
+#include "EventModel.h"
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitEventServiceUUID[];
+extern const uint8_t  MicroBitEventServiceMicroBitEventCharacteristicUUID[];
+extern const uint8_t  MicroBitEventServiceClientEventCharacteristicUUID[];
+extern const uint8_t  MicroBitEventServiceMicroBitRequirementsCharacteristicUUID[];
+extern const uint8_t  MicroBitEventServiceClientRequirementsCharacteristicUUID[];
+
+struct EventServiceEvent
+{
+    uint16_t    type;
+    uint16_t    reason;
+};
+
+
+/**
+  * Class definition for a MicroBit BLE Event Service.
+  * Provides a BLE gateway onto an Event Model.
+  */
+class MicroBitEventService : public MicroBitComponent
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the EventService
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _messageBus An instance of an EventModel which events will be mirrored from.
+      */
+    MicroBitEventService(BLEDevice &_ble, EventModel &_messageBus);
+
+    /**
+     * Periodic callback from MicroBit scheduler.
+     * If we're no longer connected, remove any registered Message Bus listeners.
+     */
+    virtual void idleTick();
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+      * Callback. Invoked when any events are sent on the microBit message bus.
+      */
+    void onMicroBitEvent(MicroBitEvent evt);
+
+    /**
+      * Read callback on microBitRequirements characteristic.
+      *
+      * Used to iterate through the events that the code on this micro:bit is interested in.
+      */
+    void onRequirementsRead(GattReadAuthCallbackParams *params);
+
+    private:
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+	EventModel	        &messageBus;
+
+    // memory for our event characteristics.
+    EventServiceEvent   clientEventBuffer;
+    EventServiceEvent   microBitEventBuffer;
+    EventServiceEvent   microBitRequirementsBuffer;
+    EventServiceEvent   clientRequirementsBuffer;
+
+    // handles on this service's characterisitics.
+    GattAttribute::Handle_t microBitEventCharacteristicHandle;
+    GattAttribute::Handle_t clientRequirementsCharacteristicHandle;
+    GattAttribute::Handle_t clientEventCharacteristicHandle;
+    GattCharacteristic *microBitRequirementsCharacteristic;
+
+    // Message bus offset last sent to the client...
+    uint16_t messageBusListenerOffset;
+
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitIOPinService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,143 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_IO_PIN_SERVICE_H
+#define MICROBIT_IO_PIN_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitIO.h"
+
+#define MICROBIT_IO_PIN_SERVICE_PINCOUNT       19
+#define MICROBIT_IO_PIN_SERVICE_DATA_SIZE      10
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitIOPinServiceUUID[];
+extern const uint8_t  MicroBitIOPinServiceADConfigurationUUID[];
+extern const uint8_t  MicroBitIOPinServiceIOConfigurationUUID[];
+extern const uint8_t  MicroBitIOPinServiceDataUUID[];
+extern MicroBitPin * const MicroBitIOPins[];
+
+/**
+  * Name value pair definition, as used to read and write pin values over BLE.
+  */
+struct IOData
+{
+    uint8_t     pin;
+    uint8_t     value;
+};
+
+/**
+  * Class definition for the custom MicroBit IOPin Service.
+  * Provides a BLE service to remotely read the state of the I/O Pin, and configure its behaviour.
+  */
+class MicroBitIOPinService : public MicroBitComponent
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the IOPinService
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _io An instance of MicroBitIO that this service will use to perform
+      *            I/O operations.
+      */
+    MicroBitIOPinService(BLEDevice &_ble, MicroBitIO &_io);
+
+    /**
+     * Periodic callback from MicroBit scheduler.
+     *
+     * Check if any of the pins we're watching need updating. Notify any connected
+     * device with any changes.
+     */
+    virtual void idleTick();
+
+    private:
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+     * Callback. invoked when the BLE data characteristic is read.
+     *
+     * Reads all the pins marked as inputs, and updates the data stored in the characteristic.
+     */
+    void onDataRead(GattReadAuthCallbackParams *params);
+
+    /**
+      * Determines if the given pin was configured as a digital pin by the BLE ADPinConfigurationCharacterisitic.
+      *
+      * @param i the enumeration of the pin to test
+      * @return 1 if this pin is configured as digital, 0 otherwise
+      */
+    int isDigital(int i);
+
+    /**
+      * Determines if the given pin was configured as an analog pin by the BLE ADPinConfigurationCharacterisitic.
+      *
+      * @param i the enumeration of the pin to test
+      * @return 1 if this pin is configured as analog, 0 otherwise
+      */
+    int isAnalog(int i);
+
+    /**
+      * Determines if the given pin was configured as an input by the BLE IOPinConfigurationCharacterisitic.
+      *
+      * @param i the enumeration of the pin to test
+      * @return 1 if this pin is configured as an input, 0 otherwise
+      */
+    int isInput(int i);
+
+    /**
+      * Determines if the given pin was configured as output by the BLE IOPinConfigurationCharacterisitic.
+      *
+      * @param i the enumeration of the pin to test
+      * @return 1 if this pin is configured as an output, 0 otherwise
+      */
+    int isOutput(int i);
+
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+    MicroBitIO          &io;
+
+    // memory for our 8 bit control characteristics.
+    uint32_t            ioPinServiceADCharacteristicBuffer;
+    uint32_t            ioPinServiceIOCharacteristicBuffer;
+    IOData              ioPinServiceDataCharacteristicBuffer[MICROBIT_IO_PIN_SERVICE_DATA_SIZE];
+
+    // Historic information about our pin data data.
+    uint8_t             ioPinServiceIOData[MICROBIT_IO_PIN_SERVICE_PINCOUNT];
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t ioPinServiceADCharacteristicHandle;
+    GattAttribute::Handle_t ioPinServiceIOCharacteristicHandle;
+    GattCharacteristic *ioPinServiceDataCharacteristic;
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitLEDService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,91 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_LED_SERVICE_H
+#define MICROBIT_LED_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitDisplay.h"
+
+// Defines the buffer size for scrolling text over BLE, hence also defines
+// the maximum string length that can be scrolled via the BLE service.
+#define MICROBIT_BLE_MAXIMUM_SCROLLTEXT         20
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitLEDServiceUUID[];
+extern const uint8_t  MicroBitLEDServiceMatrixUUID[];
+extern const uint8_t  MicroBitLEDServiceTextUUID[];
+extern const uint8_t  MicroBitLEDServiceScrollingSpeedUUID[];
+
+
+/**
+  * Class definition for the custom MicroBit LED Service.
+  * Provides a BLE service to remotely read and write the state of the LED display.
+  */
+class MicroBitLEDService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the LEDService
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _display An instance of MicroBitDisplay to interface with.
+      */
+    MicroBitLEDService(BLEDevice &_ble, MicroBitDisplay &_display);
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+      * Callback. Invoked when any of our attributes are read via BLE.
+      */
+    void onDataRead(GattReadAuthCallbackParams *params);
+
+    private:
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+    MicroBitDisplay     &display;
+
+    // memory for our 8 bit control characteristics.
+    uint8_t             matrixCharacteristicBuffer[5];
+    uint16_t            scrollingSpeedCharacteristicBuffer;
+    uint8_t             textCharacteristicBuffer[MICROBIT_BLE_MAXIMUM_SCROLLTEXT];
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t matrixCharacteristicHandle;
+    GattAttribute::Handle_t textCharacteristicHandle;
+    GattAttribute::Handle_t scrollingSpeedCharacteristicHandle;
+
+    // We hold a copy of the GattCharacteristic, as mbed's BLE API requires this to provide read callbacks (pity!).
+    GattCharacteristic  matrixCharacteristic;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitMagnetometerService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,91 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_MAGNETOMETER_SERVICE_H
+#define MICROBIT_MAGNETOMETER_SERVICE_H
+
+#include "ble/BLE.h"
+#include "MicroBitConfig.h"
+#include "MicroBitCompass.h"
+#include "EventModel.h"
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitMagnetometerServiceUUID[];
+extern const uint8_t  MicroBitMagnetometerServiceDataUUID[];
+extern const uint8_t  MicroBitMagnetometerServiceBearingUUID[];
+extern const uint8_t  MicroBitMagnetometerServicePeriodUUID[];
+
+
+/**
+  * Class definition for the MicroBit BLE Magnetometer Service.
+  * Provides access to live magnetometer data via BLE, and provides basic configuration options.
+  */
+class MicroBitMagnetometerService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the MagnetometerService.
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _compass An instance of MicroBitCompass to use as our Magnetometer source.
+      */
+    MicroBitMagnetometerService(BLEDevice &_ble, MicroBitCompass &_compass);
+
+    private:
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+     * Magnetometer update callback
+     */
+    void magnetometerUpdate(MicroBitEvent e);
+
+    /**
+     * Sample Period Change Needed callback.
+     * Reconfiguring the magnetometer can to a REALLY long time (sometimes even seconds to complete)
+     * So we do this in the background when necessary, through this event handler.
+     */
+    void samplePeriodUpdateNeeded(MicroBitEvent e);
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+    MicroBitCompass     &compass;
+
+    // memory for our 8 bit control characteristics.
+    int16_t             magnetometerDataCharacteristicBuffer[3];
+    uint16_t            magnetometerBearingCharacteristicBuffer;
+    uint16_t            magnetometerPeriodCharacteristicBuffer;
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t magnetometerDataCharacteristicHandle;
+    GattAttribute::Handle_t magnetometerBearingCharacteristicHandle;
+    GattAttribute::Handle_t magnetometerPeriodCharacteristicHandle;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitTemperatureService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,82 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_TEMPERATURE_SERVICE_H
+#define MICROBIT_TEMPERATURE_SERVICE_H
+
+#include "MicroBitConfig.h"
+#include "ble/BLE.h"
+#include "MicroBitThermometer.h"
+#include "EventModel.h"
+
+// UUIDs for our service and characteristics
+extern const uint8_t  MicroBitTemperatureServiceUUID[];
+extern const uint8_t  MicroBitTemperatureServiceDataUUID[];
+extern const uint8_t  MicroBitTemperatureServicePeriodUUID[];
+
+
+/**
+  * Class definition for the custom MicroBit Temperature Service.
+  * Provides a BLE service to remotely read the silicon temperature of the nRF51822.
+  */
+class MicroBitTemperatureService
+{
+    public:
+
+    /**
+      * Constructor.
+      * Create a representation of the TemperatureService
+      * @param _ble The instance of a BLE device that we're running on.
+      * @param _thermometer An instance of MicroBitThermometer to use as our temperature source.
+      */
+    MicroBitTemperatureService(BLEDevice &_ble, MicroBitThermometer &_thermometer);
+
+    /**
+      * Callback. Invoked when any of our attributes are written via BLE.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+     * Temperature update callback
+     */
+    void temperatureUpdate(MicroBitEvent e);
+
+    private:
+
+    // Bluetooth stack we're running on.
+    BLEDevice           	&ble;
+    MicroBitThermometer     &thermometer;
+
+    // memory for our 8 bit temperature characteristic.
+    int8_t             temperatureDataCharacteristicBuffer;
+    uint16_t           temperaturePeriodCharacteristicBuffer;
+
+    // Handles to access each characteristic when they are held by Soft Device.
+    GattAttribute::Handle_t temperatureDataCharacteristicHandle;
+    GattAttribute::Handle_t temperaturePeriodCharacteristicHandle;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/bluetooth/MicroBitUARTService.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,310 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_UART_SERVICE_H
+#define MICROBIT_UART_SERVICE_H
+
+#include "mbed.h"
+#include "ble/UUID.h"
+#include "ble/BLE.h"
+#include "MicroBitConfig.h"
+#include "MicroBitSerial.h"
+
+#define MICROBIT_UART_S_DEFAULT_BUF_SIZE    20
+
+#define MICROBIT_UART_S_EVT_DELIM_MATCH     1
+#define MICROBIT_UART_S_EVT_HEAD_MATCH      2
+#define MICROBIT_UART_S_EVT_RX_FULL         3
+
+/**
+  * Class definition for the custom MicroBit UART Service.
+  * Provides a BLE service that acts as a UART port, enabling the reception and transmission
+  * of an arbitrary number of bytes.
+  */
+class MicroBitUARTService
+{
+    uint8_t* rxBuffer;
+
+    uint8_t* txBuffer;
+
+    uint8_t rxBufferHead;
+    uint8_t rxBufferTail;
+    uint8_t rxBufferSize;
+
+    uint8_t txBufferSize;
+
+    uint32_t rxCharacteristicHandle;
+
+    // Bluetooth stack we're running on.
+    BLEDevice           &ble;
+
+    //delimeters used for matching on receive.
+    ManagedString delimeters;
+
+    //a variable used when a user calls the eventAfter() method.
+    int rxBuffHeadMatch;
+
+    /**
+      * A callback function for whenever a Bluetooth device writes to our TX characteristic.
+      */
+    void onDataWritten(const GattWriteCallbackParams *params);
+
+    /**
+      * An internal method that copies values from a circular buffer to a linear buffer.
+      *
+      * @param circularBuff a pointer to the source circular buffer
+      * @param circularBuffSize the size of the circular buffer
+      * @param linearBuff a pointer to the destination linear buffer
+      * @param tailPosition the tail position in the circular buffer you want to copy from
+      * @param headPosition the head position in the circular buffer you want to copy to
+      *
+      * @note this method assumes that the linear buffer has the appropriate amount of
+      *       memory to contain the copy operation
+      */
+    void circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition);
+
+    public:
+
+    /**
+     * Constructor for the UARTService.
+     * @param _ble an instance of BLEDevice
+     * @param rxBufferSize the size of the rxBuffer
+     * @param txBufferSize the size of the txBuffer
+     *
+     * @note The default size is MICROBIT_UART_S_DEFAULT_BUF_SIZE (20 bytes).
+     */
+    MicroBitUARTService(BLEDevice &_ble, uint8_t rxBufferSize = MICROBIT_UART_S_DEFAULT_BUF_SIZE, uint8_t txBufferSize = MICROBIT_UART_S_DEFAULT_BUF_SIZE);
+
+    /**
+      * Retreives a single character from our RxBuffer.
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will attempt to read a single character, and return immediately
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+      *                         event is received.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, a character or MICROBIT_NO_DATA
+      */
+    int getc(MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Places a single character into our transmission buffer,
+      *
+      * @param c the character to transmit
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
+      */
+    int putc(char c, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Copies characters into the buffer used for Transmitting to the central device.
+      *
+      * @param buf a buffer containing length number of bytes.
+      * @param length the size of the buffer.
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
+      */
+    int send(const uint8_t *buf, int length, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Copies characters into the buffer used for Transmitting to the central device.
+      *
+      * @param s the string to transmit
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+      *                    and return control to the user.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+      *                         given characters have been received by the connected
+      *                         device.
+      *
+      * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+      *         no connected device, or the connected device has not enabled indications.
+      */
+    int send(ManagedString s, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Reads a number of characters from the rxBuffer and fills user given buffer.
+      *
+      * @param buf a pointer to a buffer of len bytes.
+      * @param len the size of the user allocated buffer
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will attempt to read all available characters, and return immediately
+      *                    until the buffer limit is reached
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will first of all determine whether the given number of characters
+      *                         are available in our buffer, if not, it will set an event and sleep
+      *                         until the number of characters are avaialable.
+      *
+      * @return the number of characters digested
+      */
+    int read(uint8_t *buf, int len, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Reads a number of characters from the rxBuffer and returns them as a ManagedString
+      *
+      * @param len the number of characters to read.
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will attempt to read all available characters, and return immediately
+      *                    until the buffer limit is reached
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will first of all determine whether the given number of characters
+      *                         are available in our buffer, if not, it will set an event and sleep
+      *                         until the number of characters are avaialable.
+      *
+      * @return an empty ManagedString on error, or a ManagedString containing characters
+      */
+    ManagedString read(int len, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Reads characters until a character matches one of the given delimeters
+      *
+      * @param delimeters the number of characters to match against
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will attempt read the immediate buffer, and look for a match.
+      *                    If there isn't, an empty ManagedString will be returned.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will first of all consider the characters in the immediate buffer,
+      *                         if a match is not found, it will block on an event, fired when a
+      *                         character is matched.
+      *
+      * @return an empty ManagedString on error, or a ManagedString containing characters
+      */
+    ManagedString readUntil(ManagedString delimeters, MicroBitSerialMode mode = SYNC_SLEEP);
+
+    /**
+      * Configures an event to be fired on a match with one of the delimeters.
+      *
+      * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will configure the event and return immediately.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+      *                         event is received.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+      *
+      * @note delimeters are matched on a per byte basis.
+      */
+    int eventOn(ManagedString delimeters, MicroBitSerialMode mode = ASYNC);
+
+    /**
+      * Configures an event to be fired after "len" characters.
+      *
+      * @param len the number of characters to wait before triggering the event
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will configure the event and return immediately.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+      *                         event is received.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+      */
+    int eventAfter(int len, MicroBitSerialMode mode = ASYNC);
+
+    /**
+      * Determines if we have space in our rxBuff.
+      *
+      * @return 1 if we have space, 0 if we do not.
+      */
+    int isReadable();
+
+    /**
+      * @return The currently buffered number of bytes in our rxBuff.
+      */
+    int rxBufferedSize();
+
+    /**
+      * @return The currently buffered number of bytes in our txBuff.
+      */
+    int txBufferedSize();
+};
+
+extern const uint8_t  UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint16_t UARTServiceShortUUID;
+extern const uint16_t UARTServiceTXCharacteristicShortUUID;
+extern const uint16_t UARTServiceRXCharacteristicShortUUID;
+
+extern const uint8_t  UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t  UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID];
+
+extern const uint8_t  UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
+extern const uint8_t  UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID];
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/ErrorNo.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,86 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef ERROR_NO_H
+#define ERROR_NO_H
+
+#include "MicroBitConfig.h"
+
+/**
+  * Error codes used in the micro:bit runtime.
+  * These may be returned from functions implemented in the micro:bit runtime.
+  */
+enum ErrorCode{
+
+    // No error occurred.
+    MICROBIT_OK = 0,
+
+    // Invalid parameter given.
+    MICROBIT_INVALID_PARAMETER = -1001,
+
+    // Requested operation is unsupported.
+    MICROBIT_NOT_SUPPORTED = -1002,
+
+    // Device calibration errors
+    MICROBIT_CALIBRATION_IN_PROGRESS = -1003,
+    MICROBIT_CALIBRATION_REQUIRED = -1004,
+
+    // The requested operation could not be performed as the device has run out of some essential resource (e.g. allocated memory)
+    MICROBIT_NO_RESOURCES = -1005,
+
+    // The requested operation could not be performed as some essential resource is busy (e.g. the display)
+    MICROBIT_BUSY = -1006,
+
+    // The requested operation was cancelled before it completed.
+    MICROBIT_CANCELLED = -1007,
+
+    // I2C Communication error occured (typically I2C module on processor has locked up.)
+    MICROBIT_I2C_ERROR = -1010,
+
+    // The serial bus is currently in use by another fiber.
+    MICROBIT_SERIAL_IN_USE = -1011,
+
+    // The requested operation had no data to return.
+    MICROBIT_NO_DATA = -1012
+};
+
+/**
+  * Error codes used in the micro:bit runtime.
+  */
+enum PanicCode{
+    // PANIC Codes. These are not return codes, but are terminal conditions.
+    // These induce a panic operation, where all code stops executing, and a panic state is
+    // entered where the panic code is diplayed.
+
+    // Out out memory error. Heap storage was requested, but is not available.
+    MICROBIT_OOM = 20,
+
+    // Corruption detected in the micro:bit heap space
+    MICROBIT_HEAP_ERROR = 30,
+
+    // Dereference of a NULL pointer through the ManagedType class,
+    MICROBIT_NULL_DEREFERENCE = 40,
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/EventModel.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,430 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef EVENT_MODEL_H
+#define EVENT_MODEL_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitEvent.h"
+#include "MicroBitListener.h"
+#include "ErrorNo.h"
+
+/**
+  * Class definition for the micro:bit EventModel.
+  *
+  * It is common to need to send events from one part of a program (or system) to another.
+  * The way that these events are stored and delivered is known as an Event Model...
+  *
+  * The micro:bit can be programmed in a number of languages, and it not be good to
+  * constrain those languages to any particular event model (e.g. they may have their own already).
+  *
+  * This class defines the functionality an event model needs to have to be able to interact
+  * with events generated and/or used by the micro:bit runtime. Programmer may choose to implement
+  * such funcitonality to integrate their own event models.
+  *
+  * This is an example of a key principle in computing - ABSTRACTION. This is now part of the
+  * UK's Computing curriculum in schools... so ask your teacher about it. :-)
+  *
+  * An EventModel implementation is provided in the MicroBitMessageBus class.
+  */
+class EventModel
+{
+    public:
+
+    static EventModel *defaultEventBus;
+
+	/**
+	  * Queues the given event to be sent to all registered recipients.
+      * The method of delivery will vary depending on the underlying implementation.
+	  *
+	  * @param The event to send.
+      *
+      * @return This default implementation simply returns MICROBIT_NOT_SUPPORTED.
+	  */
+	virtual int send(MicroBitEvent evt)
+    {
+        (void) evt;
+        return MICROBIT_NOT_SUPPORTED;
+    }
+
+    /**
+     * Add the given MicroBitListener to the list of event handlers, unconditionally.
+     *
+     * @param listener The MicroBitListener to validate.
+     *
+     * @return This default implementation simply returns MICROBIT_NOT_SUPPORTED.
+     */
+    virtual int add(MicroBitListener *listener)
+    {
+        (void) listener;
+        return MICROBIT_NOT_SUPPORTED;
+    }
+
+    /**
+     * Remove the given MicroBitListener from the list of event handlers.
+     *
+     * @param listener The MicroBitListener to remove.
+     *
+     * @return This default implementation simply returns MICROBIT_NOT_SUPPORTED.
+     */
+    virtual int remove(MicroBitListener *listener)
+    {
+        (void) listener;
+        return MICROBIT_NOT_SUPPORTED;
+    }
+
+    /**
+      * Returns the MicroBitListener at the given position in the list.
+      *
+      * @param n The index of the desired MicroBitListener.
+      *
+      * @return This default implementation simply returns NULL.
+      */
+    MicroBitListener *elementAt(int n)
+    {
+        (void) n;
+        return NULL;
+    }
+
+	/**
+	  * Define the default EventModel to use for events raised and consumed by the microbit-dal runtime.
+      * The default EventModel may be changed at any time.
+      *
+	  * @param model A new instance of an EventModel to use as the default.
+      *
+      * @return MICROBIT_OK on success.
+	  *
+      * Example:
+      * @code
+      * MicroBitMessageBus b();
+      * EventModel:setDefaultEventModel(b);
+      * @endcode
+	  */
+	static int setDefaultEventModel(EventModel &model)
+    {
+        EventModel::defaultEventBus = &model;
+        return MICROBIT_OK;
+    }
+
+	/**
+	  * Register a listener function.
+      *
+      * An EventModel implementing this interface may optionally choose to override this method,
+      * if that EventModel supports asynchronous callbacks to user code, but there is no
+      * requirement to do so.
+      *
+	  * @param id The source of messages to listen for. Events sent from any other IDs will be filtered.
+	  * Use MICROBIT_ID_ANY to receive events from all components.
+	  *
+	  * @param value The value of messages to listen for. Events with any other values will be filtered.
+	  * Use MICROBIT_EVT_ANY to receive events of any value.
+	  *
+	  * @param handler The function to call when an event is received.
+      *
+      * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+      *
+      * @return MICROBIT_OK on success, or any valid error code defined in "ErrNo.h". The default implementation
+      * simply returns MICROBIT_NOT_SUPPORTED.
+	  *
+      * @code
+      * void onButtonBClicked(MicroBitEvent)
+      * {
+      * 	//do something
+      * }
+      *
+      * // call onButtonBClicked when ever a click event from buttonB is detected.
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      * @endcode
+	  */
+	int listen(int id, int value, void (*handler)(MicroBitEvent), uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS)
+    {
+        if (handler == NULL)
+            return MICROBIT_INVALID_PARAMETER;
+
+        MicroBitListener *newListener = new MicroBitListener(id, value, handler, flags);
+
+        if(add(newListener) == MICROBIT_OK)
+            return MICROBIT_OK;
+
+        delete newListener;
+
+        return MICROBIT_NOT_SUPPORTED;
+    }
+
+    /**
+	  * Register a listener function.
+      *
+      * An EventModel implementing this interface may optionally choose to override this method,
+      * if that EventModel supports asynchronous callbacks to user code, but there is no
+      * requirement to do so.
+      *
+	  * @param id The source of messages to listen for. Events sent from any other IDs will be filtered.
+	  * Use MICROBIT_ID_ANY to receive events from all components.
+	  *
+	  * @param value The value of messages to listen for. Events with any other values will be filtered.
+	  * Use MICROBIT_EVT_ANY to receive events of any value.
+	  *
+	  * @param handler The function to call when an event is received.
+      *
+      * @param arg Provide the callback with in an additional argument.
+      *
+      * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+      *
+      * @return MICROBIT_OK on success, or any valid error code defined in "ErrNo.h". The default implementation
+      * simply returns MICROBIT_NOT_SUPPORTED.
+	  *
+      * @code
+      * void onButtonBClicked(MicroBitEvent, void* data)
+      * {
+      * 	//do something
+      * }
+      *
+      * // call onButtonBClicked when ever a click event from buttonB is detected.
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      * @endcode
+	  */
+    int listen(int id, int value, void (*handler)(MicroBitEvent, void*), void* arg, uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS)
+    {
+        if (handler == NULL)
+            return MICROBIT_INVALID_PARAMETER;
+
+        MicroBitListener *newListener = new MicroBitListener(id, value, handler, arg, flags);
+
+        if(add(newListener) == MICROBIT_OK)
+            return MICROBIT_OK;
+
+        delete newListener;
+
+        return MICROBIT_NOT_SUPPORTED;
+    }
+
+	/**
+	  * Register a listener function.
+	  *
+	  * @param id The source of messages to listen for. Events sent from any other IDs will be filtered.
+	  * Use MICROBIT_ID_ANY to receive events from all components.
+	  *
+	  * @param value The value of messages to listen for. Events with any other values will be filtered.
+	  * Use MICROBIT_EVT_ANY to receive events of any value.
+	  *
+	  * @param hander The function to call when an event is received.
+      *
+      * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler or object
+      *         pointers are NULL.
+      *
+      * @code
+      * void SomeClass::onButtonBClicked(MicroBitEvent)
+      * {
+      * 	//do something
+      * }
+      *
+      * SomeClass s = new SomeClass();
+      *
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, s, &SomeClass::onButtonBClick);
+      * @endcode
+	  */
+    template <typename T>
+	int listen(uint16_t id, uint16_t value, T* object, void (T::*handler)(MicroBitEvent), uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS);
+
+
+	/**
+	  * Unregister a listener function.
+      * Listeners are identified by the Event ID, Event value and handler registered using listen().
+	  *
+	  * @param id The Event ID used to register the listener.
+	  * @param value The Event value used to register the listener.
+	  * @param handler The function used to register the listener.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler
+      *         given is NULL.
+	  *
+      * Example:
+      * @code
+      * void onButtonBClick(MicroBitEvent)
+      * {
+      * 	//do something
+      * }
+      *
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      *
+      * // the previously created listener is now ignored.
+      * uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      * @endcode
+	  */
+	int ignore(int id, int value, void (*handler)(MicroBitEvent))
+    {
+        if (handler == NULL)
+            return MICROBIT_INVALID_PARAMETER;
+
+        MicroBitListener listener(id, value, handler);
+        remove(&listener);
+
+        return MICROBIT_OK;
+    }
+
+    /**
+	  * Unregister a listener function.
+      * Listeners are identified by the Event ID, Event value and handler registered using listen().
+	  *
+	  * @param id The Event ID used to register the listener.
+	  * @param value The Event value used to register the listener.
+	  * @param handler The function used to register the listener.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler
+      *         given is NULL.
+	  *
+      * Example:
+      * @code
+      * void onButtonBClick(MicroBitEvent, void* data)
+      * {
+      * 	//do something
+      * }
+      *
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      *
+      * // the previously created listener is now ignored.
+      * uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
+      * @endcode
+	  */
+	int ignore(int id, int value, void (*handler)(MicroBitEvent, void*))
+    {
+        if (handler == NULL)
+            return MICROBIT_INVALID_PARAMETER;
+
+        MicroBitListener listener(id, value, handler, NULL);
+        remove(&listener);
+
+        return MICROBIT_OK;
+    }
+
+	/**
+	  * Unregister a listener function.
+      * Listners are identified by the Event ID, Event value and handler registered using listen().
+	  *
+	  * @param id The Event ID used to register the listener.
+	  * @param value The Event value used to register the listener.
+	  * @param handler The function used to register the listener.
+      *
+      * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler or object
+      *         pointers are NULL.
+	  *
+      * Example:
+      * @code
+      *
+      * void SomeClass::onButtonBClick()
+      * {
+      * 	//do something
+      * }
+      *
+      * SomeClass s = new SomeClass();
+      * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, s, &SomeClass::onButtonBClick);
+      *
+      * // the previously created listener is now ignored.
+      * uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, s, &SomeClass::onButtonBClick);
+      * @endcode
+	  */
+    template <typename T>
+	int ignore(uint16_t id, uint16_t value, T* object, void (T::*handler)(MicroBitEvent));
+
+};
+
+/**
+  * A registration function to allow C++ member functions (methods) to be registered as an event
+  * listener.
+  *
+  * @param id The source of messages to listen for. Events sent from any other IDs will be filtered.
+  * Use MICROBIT_ID_ANY to receive events from all components.
+  *
+  * @param value The value of messages to listen for. Events with any other values will be filtered.
+  * Use MICROBIT_EVT_ANY to receive events of any value.
+  *
+  * @param object The object on which the method should be invoked.
+  *
+  * @param handler The method to call when an event is received.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler or object
+  *         pointers are NULL.
+  */
+template <typename T>
+int EventModel::listen(uint16_t id, uint16_t value, T* object, void (T::*handler)(MicroBitEvent), uint16_t flags)
+{
+	if (object == NULL || handler == NULL)
+		return MICROBIT_INVALID_PARAMETER;
+
+	MicroBitListener *newListener = new MicroBitListener(id, value, object, handler, flags);
+
+    if(add(newListener) == MICROBIT_OK)
+        return MICROBIT_OK;
+
+    delete newListener;
+    return MICROBIT_NOT_SUPPORTED;
+}
+
+/**
+  * Unregister a listener function.
+  * Listners are identified by the Event ID, Event value and handler registered using listen().
+  *
+  * @param id The Event ID used to register the listener.
+  * @param value The Event value used to register the listener.
+  * @param handler The function used to register the listener.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER if the handler or object
+  *         pointers are NULL.
+  *
+  * Example:
+  * @code
+  *
+  * void SomeClass::onButtonBClick()
+  * {
+  * 	//do something
+  * }
+  *
+  * SomeClass s = new SomeClass();
+  * uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, s, &SomeClass::onButtonBClick);
+  *
+  * // the previously created listener is now ignored.
+  * uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, s, &SomeClass::onButtonBClick);
+  * @endcode
+  */
+template <typename T>
+int EventModel::ignore(uint16_t id, uint16_t value, T* object, void (T::*handler)(MicroBitEvent))
+{
+	if (handler == NULL)
+		return MICROBIT_INVALID_PARAMETER;
+
+	MicroBitListener listener(id, value, object, handler);
+    remove(&listener);
+
+    return MICROBIT_OK;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MemberFunctionCallback.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,114 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MEMBER_FUNCTION_CALLBACK_H
+#define MEMBER_FUNCTION_CALLBACK_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitEvent.h"
+#include "MicroBitCompat.h"
+
+/**
+  * Class definition for a MemberFunctionCallback.
+  *
+  * C++ member functions (also known as methods) have a more complex
+  * representation than normal C functions. This class allows a reference to
+  * a C++ member function to be stored then called at a later date.
+  *
+  * This class is used extensively by the MicroBitMessageBus to deliver
+  * events to C++ methods.
+  */
+class MemberFunctionCallback
+{
+    private:
+    void* object;
+    uint32_t method[4];
+    void (*invoke)(void *object, uint32_t *method, MicroBitEvent e);
+    template <typename T> static void methodCall(void* object, uint32_t*method, MicroBitEvent e);
+
+    public:
+
+    /**
+      * Constructor. Creates a MemberFunctionCallback based on a pointer to given method.
+      *
+      * @param object The object the callback method should be invooked on.
+      *
+      * @param method The method to invoke.
+      */
+    template <typename T> MemberFunctionCallback(T* object, void (T::*method)(MicroBitEvent e));
+
+    /**
+      * A comparison of two MemberFunctionCallback objects.
+      *
+      * @return true if the given MemberFunctionCallback is equivalent to this one, false otherwise.
+      */
+    bool operator==(const MemberFunctionCallback &mfc);
+
+    /**
+      * Calls the method reference held by this MemberFunctionCallback.
+      *
+      * @param e The event to deliver to the method
+      */
+    void fire(MicroBitEvent e);
+};
+
+/**
+  * Constructor. Creates a MemberFunctionCallback based on a pointer to given method.
+  *
+  * @param object The object the callback method should be invooked on.
+  *
+  * @param method The method to invoke.
+  */
+template <typename T>
+MemberFunctionCallback::MemberFunctionCallback(T* object, void (T::*method)(MicroBitEvent e))
+{
+    this->object = object;
+    memclr(this->method, sizeof(this->method));
+    memcpy(this->method, &method, sizeof(method));
+    invoke = &MemberFunctionCallback::methodCall<T>;
+}
+
+/**
+  * A template used to create a static method capable of invoking a C++ member function (method)
+  * based on the given parameters.
+  *
+  * @param object The object the callback method should be invooked on.
+  *
+  * @param method The method to invoke.
+  *
+  * @param method The MicroBitEvent to supply to the given member function.
+  */
+template <typename T>
+void MemberFunctionCallback::methodCall(void *object, uint32_t *method, MicroBitEvent e)
+{
+    T* o = (T*)object;
+    void (T::*m)(MicroBitEvent);
+    memcpy(&m, method, sizeof(m));
+
+    (o->*m)(e);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitCompat.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,111 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * This file contains functions used to maintain compatability and portability.
+  * It also contains constants that are used elsewhere in the DAL.
+  */
+
+#ifndef MICROBIT_COMPAT_H
+#define MICROBIT_COMPAT_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+#define PI 3.14159265359
+
+/**
+  * Determines the smallest of the two numbers
+  *
+  * @param a the first number
+  *
+  * @param b the second number
+  *
+  * @return The smallest of the two given values.
+  */
+inline int min(int a, int b)
+{
+    return (a < b ? a : b);
+}
+
+/**
+  * Determines the largest of the two numbers
+  *
+  * @param a the first number
+  *
+  * @param b the second number
+  *
+  * @return The larger of the two given values.
+  */
+inline int max(int a, int b)
+{
+    return (a > b ? a : b);
+}
+
+/**
+  * Sets a given area of memory to zero.
+  *
+  * @param a the pointer to the beginning of the memory to clear
+  *
+  * @param b the number of bytes to clear.
+  */
+inline void *memclr(void *a, size_t b)
+{
+    return memset(a,0,b);
+}
+
+/**
+  * Determines if the given character is a printable ASCII/UTF8 decimal digit (0..9).
+  *
+  * @param c the character to check
+  *
+  * @return true if the character is a digit, false otherwise.
+  */
+inline bool isdigit(char c)
+{
+    return (c > 47 && c < 58);
+}
+
+/**
+  * Performs an in buffer reverse of a given char array.
+  *
+  * @param s the string to reverse.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int string_reverse(char *s);
+
+/**
+  * Converts a given integer into a string representation.
+  *
+  * @param n The number to convert.
+  *
+  * @param s A pointer to the buffer where the resulting string will be stored.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int itoa(int n, char *s);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitComponent.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,146 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_COMPONENT_H
+#define MICROBIT_COMPONENT_H
+
+#include "MicroBitConfig.h"
+
+// Enumeration of core components.
+#define MICROBIT_ID_BUTTON_A            1
+#define MICROBIT_ID_BUTTON_B            2
+#define MICROBIT_ID_BUTTON_RESET        3
+#define MICROBIT_ID_ACCELEROMETER       4
+#define MICROBIT_ID_COMPASS             5
+#define MICROBIT_ID_DISPLAY             6
+
+//EDGE connector events
+#define MICROBIT_IO_PINS                20
+
+#define MICROBIT_ID_IO_P0               7           //P0 is the left most pad (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P1               8           //P1 is the middle pad (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P2               9           //P2 is the right most pad (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P3               10          //COL1 (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P4               11          //BTN_A
+#define MICROBIT_ID_IO_P5               12          //COL2 (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P6               13          //ROW2
+#define MICROBIT_ID_IO_P7               14          //ROW1
+#define MICROBIT_ID_IO_P8               15          //PIN 18
+#define MICROBIT_ID_IO_P9               16          //ROW3
+#define MICROBIT_ID_IO_P10              17          //COL3 (ANALOG/DIGITAL)
+#define MICROBIT_ID_IO_P11              18          //BTN_B
+#define MICROBIT_ID_IO_P12              19          //PIN 20
+#define MICROBIT_ID_IO_P13              20          //SCK
+#define MICROBIT_ID_IO_P14              21          //MISO
+#define MICROBIT_ID_IO_P15              22          //MOSI
+#define MICROBIT_ID_IO_P16              23          //PIN 16
+#define MICROBIT_ID_IO_P19              24          //SCL
+#define MICROBIT_ID_IO_P20              25          //SDA
+
+#define MICROBIT_ID_BUTTON_AB           26          // Button A+B multibutton
+#define MICROBIT_ID_GESTURE             27          // Gesture events
+
+#define MICROBIT_ID_THERMOMETER         28
+#define MICROBIT_ID_RADIO               29
+#define MICROBIT_ID_RADIO_DATA_READY    30
+#define MICROBIT_ID_MULTIBUTTON_ATTACH  31
+#define MICROBIT_ID_SERIAL              32
+
+#define MICROBIT_ID_MESSAGE_BUS_LISTENER            1021          // Message bus indication that a handler for a given ID has been registered.
+#define MICROBIT_ID_NOTIFY_ONE                      1022          // Notfication channel, for general purpose synchronisation
+#define MICROBIT_ID_NOTIFY                          1023          // Notfication channel, for general purpose synchronisation
+
+// Universal flags used as part of the status field
+#define MICROBIT_COMPONENT_RUNNING		0x01
+
+
+/**
+  * Class definition for MicroBitComponent.
+  *
+  * All components should inherit from this class.
+  *
+  * If a component requires regular updates, then that component can be added to the 
+  * to the systemTick and/or idleTick queues. This provides a simple, extensible mechanism
+  * for code that requires periodic/occasional background processing but does not warrant
+  * the complexity of maintaining its own thread. 
+  *
+  * Two levels of support are available. 
+  *
+  * systemTick() provides a periodic callback during the
+  * micro:bit's system timer interrupt. This provides a guaranteed periodic callback, but in interrupt context
+  * and is suitable for code with lightweight processing requirements, but strict time constraints.
+  * 
+  * idleTick() provides a periodic callback whenever the scheduler is idle. This provides occasional, callbacks
+  * in the main thread context, but with no guarantees of frequency. This is suitable for non-urgent background tasks.
+  *
+  * Components wishing to use these facilities should override the systemTick and/or idleTick functions defined here, and
+  * register their components using system_timer_add_component() fiber_add_idle_component() respectively.
+  *
+  */
+class MicroBitComponent
+{
+    protected:
+
+    uint16_t id;                    // Event Bus ID of this component
+    uint8_t status;                 // Component defined state.
+
+    public:
+
+    /**
+      * The default constructor of a MicroBitComponent
+      */
+    MicroBitComponent()
+    {
+        this->id = 0;
+        this->status = 0;
+    }
+
+    /**
+      * The system timer will call this member function once the component has been added to
+      * the array of system components using system_timer_add_component. This callback
+      * will be in interrupt context.
+      */
+    virtual void systemTick()
+    {
+    }
+
+    /**
+      * The idle thread will call this member function once the component has been added to the array
+      * of idle components using fiber_add_idle_component. 
+      */
+    virtual void idleTick()
+    {
+    }
+
+    /**
+      * If you have added your component to the idle or system tick component arrays,
+      * you must remember to remove your component from them if your component is destructed.
+      */
+    virtual ~MicroBitComponent()
+    {
+    }
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitConfig.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,387 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Compile time configuration options for the micro:bit runtime.
+  */
+
+#ifndef MICROBIT_CONFIG_H
+#define MICROBIT_CONFIG_H
+
+#include "mbed.h"
+#include "yotta_cfg_mappings.h"
+
+//
+// Memory configuration
+//
+
+// The start address of usable RAM memory.
+#ifndef MICROBIT_SRAM_BASE
+#define MICROBIT_SRAM_BASE                      0x20000008
+#endif
+
+// Physical address of the top of SRAM.
+#ifndef MICROBIT_SRAM_END
+#define MICROBIT_SRAM_END                       0x20004000
+#endif
+
+// The end address of memory normally reserved for Soft Device.
+#ifndef MICROBIT_SD_LIMIT
+#define MICROBIT_SD_LIMIT                       0x20002000
+#endif
+
+// The physical address in memory of the Soft Device GATT table.
+#ifndef MICROBIT_SD_GATT_TABLE_START
+#define MICROBIT_SD_GATT_TABLE_START            0x20001900
+#endif
+
+// Physical address of the top of the system stack (on mbed-classic this is the top of SRAM)
+#ifndef CORTEX_M0_STACK_BASE
+#define CORTEX_M0_STACK_BASE                    MICROBIT_SRAM_END
+#endif
+
+// Amount of memory reserved for the stack at the end of memory (bytes).
+#ifndef MICROBIT_STACK_SIZE
+#define MICROBIT_STACK_SIZE                     2048
+#endif
+
+// Physical address of the end of mbed heap space.
+#ifndef MICROBIT_HEAP_END
+#define MICROBIT_HEAP_END                       (CORTEX_M0_STACK_BASE - MICROBIT_STACK_SIZE)
+#endif
+
+// Enables or disables the MicroBitHeapllocator. Note that if disabled, no reuse of the SRAM normally
+// reserved for SoftDevice is possible, and out of memory condition will no longer be trapped...
+// i.e. panic() will no longer be triggered on memory full conditions.
+#ifndef MICROBIT_HEAP_ALLOCATOR
+#define MICROBIT_HEAP_ALLOCATOR                 1
+#endif
+
+// Block size used by the allocator in bytes.
+// n.b. Currently only 32 bits (4 bytes) is supported.
+#ifndef MICROBIT_HEAP_BLOCK_SIZE
+#define MICROBIT_HEAP_BLOCK_SIZE                4
+#endif
+
+// The proportion of SRAM available on the mbed heap to reserve for the micro:bit heap.
+#ifndef MICROBIT_NESTED_HEAP_SIZE
+#define MICROBIT_NESTED_HEAP_SIZE               0.75
+#endif
+
+// If defined, reuse any unused SRAM normally reserved for SoftDevice (Nordic's memory resident BLE stack) as heap memory.
+// The amount of memory reused depends upon whether or not BLE is enabled using MICROBIT_BLE_ENABLED.
+// Set '1' to enable.
+#ifndef MICROBIT_HEAP_REUSE_SD
+#define MICROBIT_HEAP_REUSE_SD                  1
+#endif
+
+// The amount of memory allocated to Soft Device to hold its BLE GATT table.
+// For standard S110 builds, this should be word aligned and in the range 0x300 - 0x700.
+// Any unused memory will be automatically reclaimed as HEAP memory if both MICROBIT_HEAP_REUSE_SD and MICROBIT_HEAP_ALLOCATOR are enabled.
+#ifndef MICROBIT_SD_GATT_TABLE_SIZE
+#define MICROBIT_SD_GATT_TABLE_SIZE             0x300
+#endif
+
+//
+// Fiber scheduler configuration
+//
+
+// Scheduling quantum (milliseconds)
+// Also used to drive the micro:bit runtime system ticker.
+#ifndef SYSTEM_TICK_PERIOD_MS
+#define SYSTEM_TICK_PERIOD_MS                   6
+#endif
+
+//
+// Message Bus:
+// Default behaviour for event handlers, if not specified in the listen() call
+//
+// Permissable values are:
+//   MESSAGE_BUS_LISTENER_REENTRANT
+//   MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY
+//   MESSAGE_BUS_LISTENER_DROP_IF_BUSY
+//   MESSAGE_BUS_LISTENER_IMMEDIATE
+
+#ifndef EVENT_LISTENER_DEFAULT_FLAGS
+#define EVENT_LISTENER_DEFAULT_FLAGS            MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY
+#endif
+
+//
+// Maximum event queue depth. If a queue exceeds this depth, further events will be dropped.
+// Used to prevent message queues growing uncontrollably due to badly behaved user code and causing panic conditions.
+//
+#ifndef MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH
+#define MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH    10
+#endif
+
+//
+// Core micro:bit services
+//
+
+// To reduce memory cost and complexity, the micro:bit allows components to register for
+// periodic callback events during interrupt context, which occur every scheduling quantum (FIBER_TICK_PERIOD_MS)
+// This defines the maximum size of interrupt callback list.
+#ifndef MICROBIT_SYSTEM_COMPONENTS
+#define MICROBIT_SYSTEM_COMPONENTS              10
+#endif
+
+// To reduce memory cost and complexity, the micro:bit allows components to register for
+// periodic callback events when the processor is idle.
+// This defines the maximum size of the idle callback list.
+#ifndef MICROBIT_IDLE_COMPONENTS
+#define MICROBIT_IDLE_COMPONENTS                6
+#endif
+
+//
+// BLE options
+//
+// The BLE stack is very memory hungry. Each service can therefore be compiled in or out
+// by enabling/disabling the options below.
+//
+// n.b. The minimum set of services to enable over the air programming of the device will
+// still be brought up in pairing mode regardless of the settings below.
+//
+
+// Enable/Disable BLE during normal operation.
+// Set '1' to enable.
+#ifndef MICROBIT_BLE_ENABLED
+#define MICROBIT_BLE_ENABLED                    1
+#endif
+
+// Enable/Disable BLE pairing mode mode at power up.
+// Set '1' to enable.
+#ifndef MICROBIT_BLE_PAIRING_MODE
+#define MICROBIT_BLE_PAIRING_MODE               1
+#endif
+
+// Enable/Disable the use of private resolvable addresses.
+// Set '1' to enable.
+// n.b. This is known to be a feature that suffers compatibility issues with many BLE central devices.
+#ifndef MICROBIT_BLE_PRIVATE_ADDRESSES
+#define MICROBIT_BLE_PRIVATE_ADDRESSES          0
+#endif
+
+// Convenience option to enable / disable BLE security entirely
+// Open BLE links are not secure, but commonly used during the development of BLE services
+// Set '1' to disable all secuity
+#ifndef MICROBIT_BLE_OPEN
+#define MICROBIT_BLE_OPEN                       0
+#endif
+
+// Configure for open BLE operation if so configured
+#if (MICROBIT_BLE_OPEN == 1)
+#define MICROBIT_BLE_SECURITY_LEVEL             SECURITY_MODE_ENCRYPTION_OPEN_LINK
+#define MICROBIT_BLE_WHITELIST                  0
+#define MICROBIT_BLE_ADVERTISING_TIMEOUT        0
+#define MICROBIT_BLE_DEFAULT_TX_POWER           6
+#endif
+
+
+// Define the default, global BLE security requirements for MicroBit BLE services
+// May be one of the following options (see mbed's SecurityManager class implementaiton detail)
+// SECURITY_MODE_ENCRYPTION_OPEN_LINK:      No bonding, encryption, or whitelisting required.
+// SECURITY_MODE_ENCRYPTION_NO_MITM:        Bonding, encyption and whitelisting but no passkey.
+// SECURITY_MODE_ENCRYPTION_WITH_MITM:      Bonding, encrytion and whitelisting with passkey authentication.
+//
+#ifndef MICROBIT_BLE_SECURITY_LEVEL
+#define MICROBIT_BLE_SECURITY_LEVEL             SECURITY_MODE_ENCRYPTION_WITH_MITM
+#endif
+
+// Enable/Disable the use of BLE whitelisting.
+// If enabled, the micro:bit will only respond to connection requests from
+// known, bonded devices.
+#ifndef MICROBIT_BLE_WHITELIST
+#define MICROBIT_BLE_WHITELIST                  1
+#endif
+
+// Define the period of time for which the BLE stack will advertise (seconds)
+// Afer this period, advertising will cease. Set to '0' for no timeout (always advertise).
+#ifndef MICROBIT_BLE_ADVERTISING_TIMEOUT
+#define MICROBIT_BLE_ADVERTISING_TIMEOUT        0
+#endif
+
+// Defines default power level of the BLE radio transmitter.
+// Valid values are in the range 0..7 inclusive, with 0 being the lowest power and 7 the highest power.
+// Based on trials undertaken by the BBC, the radio is normally set to its lowest power level
+// to best protect children's privacy.
+#ifndef MICROBIT_BLE_DEFAULT_TX_POWER
+#define MICROBIT_BLE_DEFAULT_TX_POWER           0
+#endif
+
+// Enable/Disable BLE Service: MicroBitDFU
+// This allows over the air programming during normal operation.
+// Set '1' to enable.
+#ifndef MICROBIT_BLE_DFU_SERVICE
+#define MICROBIT_BLE_DFU_SERVICE                1
+#endif
+
+// Enable/Disable BLE Service: MicroBitEventService
+// This allows routing of events from the micro:bit message bus over BLE.
+// Set '1' to enable.
+#ifndef MICROBIT_BLE_EVENT_SERVICE
+#define MICROBIT_BLE_EVENT_SERVICE              1
+#endif
+
+// Enable/Disable BLE Service: MicroBitDeviceInformationService
+// This enables the standard BLE device information service.
+// Set '1' to enable.
+#ifndef MICROBIT_BLE_DEVICE_INFORMATION_SERVICE
+#define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE 1
+#endif
+
+//
+// Accelerometer options
+//
+
+// Enable this to read 10 bits of data from the acclerometer.
+// Otherwise, 8 bits are used.
+// Set '1' to enable.
+#ifndef USE_ACCEL_LSB
+#define USE_ACCEL_LSB                           0
+#endif
+
+//
+// Display options
+//
+
+// Selects the matrix configuration for the display driver.
+// Known, acceptable options are:
+//
+#define MICROBUG_REFERENCE_DEVICE               1
+#define MICROBIT_3X9                            2
+#define MICROBIT_SB1                            3
+#define MICROBIT_SB2                            4
+
+#ifndef MICROBIT_DISPLAY_TYPE
+#define MICROBIT_DISPLAY_TYPE                   MICROBIT_SB2
+#endif
+
+// Selects the minimum permissable brightness level for the device
+// in the region of 0 (off) to 255 (full brightness)
+#ifndef MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS
+#define MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS     1
+#endif
+
+// Selects the maximum permissable brightness level for the device
+// in the region of 0 (off) to 255 (full brightness)
+#ifndef MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS
+#define MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS     255
+#endif
+
+// Selects the default brightness for the display
+// in the region of zero (off) to 255 (full brightness)
+#ifndef MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS
+#define MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS     MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS
+#endif
+
+// Selects the default scroll speed for the display.
+// The time taken to move a single pixel (ms).
+#ifndef MICROBIT_DEFAULT_SCROLL_SPEED
+#define MICROBIT_DEFAULT_SCROLL_SPEED           120
+#endif
+
+// Selects the number of pixels a scroll will move in each quantum.
+#ifndef MICROBIT_DEFAULT_SCROLL_STRIDE
+#define MICROBIT_DEFAULT_SCROLL_STRIDE          -1
+#endif
+
+// Selects the time each character will be shown on the display during print operations.
+// The time each character is shown on the screen  (ms).
+#ifndef MICROBIT_DEFAULT_PRINT_SPEED
+#define MICROBIT_DEFAULT_PRINT_SPEED            400
+#endif
+
+//Configures the default serial mode used by serial read and send calls.
+#ifndef MICROBIT_DEFAULT_SERIAL_MODE
+#define MICROBIT_DEFAULT_SERIAL_MODE            SYNC_SLEEP
+#endif
+
+
+//
+// I/O Options
+//
+
+
+//
+// Define the default mode in which the digital input pins are configured.
+// valid options are PullDown, PullUp and PullNone.
+//
+#ifndef MICROBIT_DEFAULT_PULLMODE
+#define MICROBIT_DEFAULT_PULLMODE                PullDown
+#endif
+
+//
+// Panic options
+//
+
+// Enable this to invoke a panic on out of memory conditions.
+// Set '1' to enable.
+#ifndef MICROBIT_PANIC_HEAP_FULL
+#define MICROBIT_PANIC_HEAP_FULL                1
+#endif
+
+//
+// Debug options
+//
+
+// Enable this to route debug messages through the USB serial interface.
+// n.b. This also disables the user serial port 'uBit.serial'.
+// Set '1' to enable.
+#ifndef MICROBIT_DBG
+#define MICROBIT_DBG                            0
+#endif
+
+// Enable this to receive diagnostic messages from the heap allocator via the USB serial interface.
+// n.b. This requires MICROBIT_DBG to be defined.
+// Set '1' to enable.
+#ifndef MICROBIT_HEAP_DBG
+#define MICROBIT_HEAP_DBG                       0
+#endif
+
+// Versioning options.
+// We use semantic versioning (http://semver.org/) to identify differnet versions of the micro:bit runtime.
+// Where possible we use yotta (an ARM mbed build tool) to help us track versions.
+// if this isn't available, it can be defined manually as a configuration option.
+//
+#ifndef MICROBIT_DAL_VERSION
+#define MICROBIT_DAL_VERSION                    "unknown"
+#endif
+
+
+//
+// Helper macro used by the micro:bit runtime to determine if a boolean configuration option is set.
+//
+#define CONFIG_ENABLED(X) (X == 1)
+#define CONFIG_DISABLED(X) (X != 1)
+
+#if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR)
+#include "MicroBitHeapAllocator.h"
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_DBG)
+extern RawSerial* SERIAL_DEBUG;
+#endif
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitDevice.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,136 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+ * Device specific funcitons for the nrf51822 device.
+ *
+ * Provides a degree of platform independence for microbit-dal functionality.
+ *
+ * TODO: Determine if any of this belongs in an mbed target definition.
+ * TODO: Review microbit-dal to place all such functions here.
+ */
+#ifndef MICROBIT_DEVICE_H
+#define MICROBIT_DEVICE_H
+
+#define MICROBIT_NAME_LENGTH                    5
+#define MICROBIT_NAME_CODE_LETTERS              5
+#define MICROBIT_PANIC_ERROR_CHARS              4
+
+#include "MicroBitConfig.h"
+#include "MicroBitMatrixMaps.h"
+
+/**
+  * Determines if a BLE stack is currently running.
+  *
+  * @return true is a bluetooth stack is operational, false otherwise.
+  */
+bool ble_running();
+
+/**
+ * Derive a unique, consistent serial number of this device from internal data.
+ *
+ * @return the serial number of this device.
+ */
+uint32_t microbit_serial_number();
+
+/**
+ * Derive the friendly name for this device, based on its serial number.
+ *
+ * @return the serial number of this device.
+ */
+char* microbit_friendly_name();
+
+/**
+  * Perform a hard reset of the micro:bit.
+  */
+void microbit_reset();
+
+/**
+  * Determine the version of microbit-dal currently running.
+  * @return a pointer to a character buffer containing a representation of the semantic version number.
+  */
+const char * microbit_dal_version();
+
+/**
+  * Disables all interrupts and user processing.
+  * Displays "=(" and an accompanying status code on the default display.
+  * @param statusCode the appropriate status code, must be in the range 0-999.
+  *
+  * @code
+  * microbit_panic(20);
+  * @endcode
+  */
+void microbit_panic(int statusCode);
+
+/**
+ * Defines the length of time that the device will remain in a error state before resetting.
+ *
+ * @param iteration The number of times the error code will be displayed before resetting. Set to zero to remain in error state forever.
+ *
+ * @code
+ * microbit_panic_timeout(4);
+ * @endcode
+ */
+void microbit_panic_timeout(int iterations);
+
+/**
+  * Generate a random number in the given range.
+  * We use a simple Galois LFSR random number generator here,
+  * as a Galois LFSR is sufficient for our applications, and much more lightweight
+  * than the hardware random number generator built int the processor, which takes
+  * a long time and uses a lot of energy.
+  *
+  * KIDS: You shouldn't use this is the real world to generte cryptographic keys though...
+  * have a think why not. :-)
+  *
+  * @param max the upper range to generate a number for. This number cannot be negative.
+  *
+  * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0.
+  *
+  * @code
+  * microbit_random(200); //a number between 0 and 199
+  * @endcode
+  */
+int microbit_random(int max);
+
+/**
+  * Seed the random number generator (RNG).
+  *
+  * This function uses the NRF51822's in built cryptographic random number generator to seed a Galois LFSR.
+  * We do this as the hardware RNG is relatively high power, and is locked out by the BLE stack internally,
+  * with a less than optimal application interface. A Galois LFSR is sufficient for our
+  * applications, and much more lightweight.
+  */
+void microbit_seed_random();
+
+/**
+  * Seed the pseudo random number generator (RNG) using the given 32-bit value.
+  * This function does not use the NRF51822's in built cryptographic random number generator.
+  *
+  * @param seed The value to use as a seed.
+  */
+void microbit_seed_random(uint32_t seed);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitFiber.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,376 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Functionality definitions for the MicroBit Fiber scheduler.
+  *
+  * This lightweight, non-preemptive scheduler provides a simple threading mechanism for two main purposes:
+  *
+  * 1) To provide a clean abstraction for application languages to use when building async behaviour (callbacks).
+  * 2) To provide ISR decoupling for EventModel events generated in an ISR context.
+  *
+  * TODO: Consider a split mode scheduler, that monitors used stack size, and maintains a dedicated, persistent
+  * stack for any long lived fibers with large stack
+  */
+#ifndef MICROBIT_FIBER_H
+#define MICROBIT_FIBER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitEvent.h"
+#include "EventModel.h"
+
+// Fiber Scheduler Flags
+#define MICROBIT_SCHEDULER_RUNNING	     	0x01
+
+// Fiber Flags
+#define MICROBIT_FIBER_FLAG_FOB             0x01
+#define MICROBIT_FIBER_FLAG_PARENT          0x02
+#define MICROBIT_FIBER_FLAG_CHILD           0x04
+#define MICROBIT_FIBER_FLAG_DO_NOT_PAGE     0x08
+
+/**
+  *  Thread Context for an ARM Cortex M0 core.
+  *
+  * This is probably overkill, but the ARMCC compiler uses a lot register optimisation
+  * in its calling conventions, so better safe than sorry!
+  */
+struct Cortex_M0_TCB
+{
+    uint32_t R0;
+    uint32_t R1;
+    uint32_t R2;
+    uint32_t R3;
+    uint32_t R4;
+    uint32_t R5;
+    uint32_t R6;
+    uint32_t R7;
+    uint32_t R8;
+    uint32_t R9;
+    uint32_t R10;
+    uint32_t R11;
+    uint32_t R12;
+    uint32_t SP;
+    uint32_t LR;
+    uint32_t stack_base;
+};
+
+/**
+  * Representation of a single Fiber
+  */
+struct Fiber
+{
+    Cortex_M0_TCB tcb;                  // Thread context when last scheduled out.
+    uint32_t stack_bottom;              // The start address of this Fiber's stack. The stack is heap allocated, and full descending.
+    uint32_t stack_top;                 // The end address of this Fiber's stack.
+    uint32_t context;                   // Context specific information.
+    uint32_t flags;                     // Information about this fiber.
+    Fiber **queue;                      // The queue this fiber is stored on.
+    Fiber *next, *prev;                 // Position of this Fiber on the run queue.
+};
+
+extern Fiber *currentFiber;
+
+
+/**
+  * Initialises the Fiber scheduler.
+  * Creates a Fiber context around the calling thread, and adds it to the run queue as the current thread.
+  *
+  * This function must be called once only from the main thread, and before any other Fiber operation.
+  *
+  * @param _messageBus An event model, used to direct the priorities of the scheduler.
+  */
+void scheduler_init(EventModel &_messageBus);
+
+/**
+  * Determines if the fiber scheduler is operational.
+  *
+  * @return 1 if the fber scheduler is running, 0 otherwise.
+  */
+int fiber_scheduler_running();
+
+/**
+  * Exit point for all fibers.
+  *
+  * Any fiber reaching the end of its entry function will return here  for recycling.
+  */
+void release_fiber(void);
+void release_fiber(void *param);
+
+/**
+ * Launches a fiber.
+ *
+ * @param ep the entry point for the fiber.
+ *
+ * @param cp the completion routine after ep has finished execution
+ */
+void launch_new_fiber(void (*ep)(void), void (*cp)(void))
+#ifdef __GCC__
+    __attribute__((naked))
+#endif
+;
+
+/**
+ * Launches a fiber with a parameter
+ *
+ * @param ep the entry point for the fiber.
+ *
+ * @param cp the completion routine after ep has finished execution
+ *
+ * @param pm the parameter to provide to ep and cp.
+ */
+void launch_new_fiber_param(void (*ep)(void *), void (*cp)(void *), void *pm)
+#ifdef __GCC__
+    __attribute__((naked))
+#endif
+;
+
+/**
+  * Creates a new Fiber, and launches it.
+  *
+  * @param entry_fn The function the new Fiber will begin execution in.
+  *
+  * @param completion_fn The function called when the thread completes execution of entry_fn.
+  *                      Defaults to release_fiber.
+  *
+  * @return The new Fiber, or NULL if the operation could not be completed.
+  */
+Fiber *create_fiber(void (*entry_fn)(void), void (*completion_fn)(void) = release_fiber);
+
+
+/**
+  * Creates a new parameterised Fiber, and launches it.
+  *
+  * @param entry_fn The function the new Fiber will begin execution in.
+  *
+  * @param param an untyped parameter passed into the entry_fn and completion_fn.
+  *
+  * @param completion_fn The function called when the thread completes execution of entry_fn.
+  *                      Defaults to release_fiber.
+  *
+  * @return The new Fiber, or NULL if the operation could not be completed.
+  */
+Fiber *create_fiber(void (*entry_fn)(void *), void *param, void (*completion_fn)(void *) = release_fiber);
+
+
+/**
+  * Calls the Fiber scheduler.
+  * The calling Fiber will likely be blocked, and control given to another waiting fiber.
+  * Call this function to yield control of the processor when you have nothing more to do.
+  */
+void schedule();
+
+/**
+  * Blocks the calling thread for the given period of time.
+  * The calling thread will be immediateley descheduled, and placed onto a
+  * wait queue until the requested amount of time has elapsed.
+  *
+  * @param t The period of time to sleep, in milliseconds.
+  *
+  * @note the fiber will not be be made runnable until after the elapsed time, but there
+  * are no guarantees precisely when the fiber will next be scheduled.
+  */
+void fiber_sleep(unsigned long t);
+
+/**
+  * The timer callback, called from interrupt context once every SYSTEM_TICK_PERIOD_MS milliseconds.
+  * This function checks to determine if any fibers blocked on the sleep queue need to be woken up
+  * and made runnable.
+  */
+void scheduler_tick();
+
+/**
+  * Blocks the calling thread until the specified event is raised.
+  * The calling thread will be immediateley descheduled, and placed onto a
+  * wait queue until the requested event is received.
+  *
+  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
+  *
+  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
+  *
+  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
+  *
+  * @code
+  * fiber_wait_for_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+  * @endcode
+  *
+  * @note the fiber will not be be made runnable until after the event is raised, but there
+  * are no guarantees precisely when the fiber will next be scheduled.
+  */
+int fiber_wait_for_event(uint16_t id, uint16_t value);
+
+/**
+  * Configures the fiber context for the current fiber to block on an event ID
+  * and value, but does not deschedule the fiber.
+  *
+  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
+  *
+  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
+  *
+  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
+  *
+  * @code
+  * fiber_wake_on_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+  *
+  * //perform some time critical operation.
+  *
+  * //deschedule the current fiber manually, waiting for the previously configured event.
+  * schedule();
+  * @endcode
+  */
+int fiber_wake_on_event(uint16_t id, uint16_t value);
+
+/**
+  * Executes the given function asynchronously if necessary.
+  *
+  * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
+  * that complete very quickly, bringing unecessary RAM overhead.
+  *
+  * This function takes a snapshot of the current processor context, then attempts to optimistically call the given function directly.
+  * We only create an additional fiber if that function performs a block operation.
+  *
+  * @param entry_fn The function to execute.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int invoke(void (*entry_fn)(void));
+
+/**
+  * Executes the given function asynchronously if necessary, and offers the ability to provide a parameter.
+  *
+  * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
+  * that complete very quickly, bringing unecessary RAM. overhead
+  *
+  * This function takes a snapshot of the current fiber context, then attempt to optimistically call the given function directly.
+  * We only create an additional fiber if that function performs a block operation.
+  *
+  * @param entry_fn The function to execute.
+  *
+  * @param param an untyped parameter passed into the entry_fn and completion_fn.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int invoke(void (*entry_fn)(void *), void *param);
+
+/**
+  * Resizes the stack allocation of the current fiber if necessary to hold the system stack.
+  *
+  * If the stack allocation is large enough to hold the current system stack, then this function does nothing.
+  * Otherwise, the the current allocation of the fiber is freed, and a larger block is allocated.
+  *
+  * @param f The fiber context to verify.
+  *
+  * @return The stack depth of the given fiber.
+  */
+inline void verify_stack_size(Fiber *f);
+
+/**
+  * Event callback. Called from an instance of MicroBitMessageBus whenever an event is raised.
+  *
+  * This function checks to determine if any fibers blocked on the wait queue need to be woken up
+  * and made runnable due to the event.
+  *
+  * @param evt the event that has just been raised on an instance of MicroBitMessageBus.
+  */
+void scheduler_event(MicroBitEvent evt);
+
+/**
+  * Determines if any fibers are waiting to be scheduled.
+  *
+  * @return The number of fibers currently on the run queue
+  */
+int scheduler_runqueue_empty();
+
+/**
+  * Utility function to add the currenty running fiber to the given queue.
+  *
+  * Perform a simple add at the head, to avoid complexity,
+  *
+  * Queues are normally very short, so maintaining a doubly linked, sorted list typically outweighs the cost of
+  * brute force searching.
+  *
+  * @param f The fiber to add to the queue
+  *
+  * @param queue The run queue to add the fiber to.
+  */
+void queue_fiber(Fiber *f, Fiber **queue);
+
+/**
+  * Utility function to the given fiber from whichever queue it is currently stored on.
+  *
+  * @param f the fiber to remove.
+  */
+void dequeue_fiber(Fiber *f);
+
+/**
+  * Set of tasks to perform when idle.
+  * Service any background tasks that are required, and attempt a power efficient sleep.
+  */
+void idle();
+
+/**
+  * The idle task, which is called when the runtime has no fibers that require execution.
+  *
+  * This function typically calls idle().
+  */
+void idle_task();
+
+/**
+  * Adds a component to the array of idle thread components, which are processed
+  * when the run queue is empty.
+  *
+  * @param component The component to add to the array.
+  * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
+  */
+int fiber_add_idle_component(MicroBitComponent *component);
+
+/**
+  * remove a component from the array of idle thread components
+  *
+  * @param component the component to remove from the idle component array.
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  */
+int fiber_remove_idle_component(MicroBitComponent *component);
+
+/**
+  * Determines if the processor is executing in interrupt context.
+  *
+  * @return true if any the processor is currently executing any interrupt service routine. False otherwise.
+  */
+inline int inInterruptContext()
+{
+    return (((int)__get_IPSR()) & 0x003F) > 0;
+}
+
+/**
+  * Assembler Context switch routing.
+  * Defined in CortexContextSwitch.s.
+  */
+extern "C" void swap_context(Cortex_M0_TCB *from, Cortex_M0_TCB *to, uint32_t from_stack, uint32_t to_stack);
+extern "C" void save_context(Cortex_M0_TCB *tcb, uint32_t stack);
+extern "C" void save_register_context(Cortex_M0_TCB *tcb);
+extern "C" void restore_register_context(Cortex_M0_TCB *tcb);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitFont.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,100 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_FONT_H
+#define MICROBIT_FONT_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+#define MICROBIT_FONT_WIDTH 5
+#define MICROBIT_FONT_HEIGHT 5
+#define MICROBIT_FONT_ASCII_START 32
+#define MICROBIT_FONT_ASCII_END 126
+
+/**
+  * Class definition for a MicrobitFont
+  * This class represents a font that can be used by the display to render text.
+  *
+  * A MicroBitFont is 5x5.
+  * Each Row is represented by a byte in the array.
+  *
+  * Row Format:
+  *            ================================================================
+  *            | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+  *            ================================================================
+  *            |  N/A  |  N/A  |  N/A  | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 |
+  *            |  0x80 |  0x40 |  0x20 | 0x10  | 0x08  | 0x04  | 0x02  | 0x01  |
+  *
+  * Example: { 0x08, 0x08, 0x08, 0x0, 0x08 }
+  *
+  * The above will produce an exclaimation mark on the second column in form the left.
+  *
+  * We could compress further, but the complexity of decode would likely outweigh the gains.
+  */
+class MicroBitFont
+{
+    public:
+
+    static const unsigned char* defaultFont;
+    static MicroBitFont systemFont;
+
+    const unsigned char* characters;
+
+    int asciiEnd;
+
+    /**
+      * Constructor.
+      *
+      * Sets the font represented by this font object.
+      *
+      * @param font A pointer to the beginning of the new font.
+      *
+      * @param asciiEnd the char value at which this font finishes.
+      */
+    MicroBitFont(const unsigned char* font, int asciiEnd = MICROBIT_FONT_ASCII_END);
+
+    /**
+      * Default Constructor.
+      *
+      * Configures the default font for the display to use.
+      */
+    MicroBitFont();
+
+    /**
+      * Modifies the current system font to the given instance of MicroBitFont.
+      *
+      * @param font the new font that will be used to render characters on the display.
+      */
+    static void setSystemFont(MicroBitFont font);
+
+    /**
+      * Retreives the font object used for rendering characters on the display.
+      */
+    static MicroBitFont getSystemFont();
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitHeapAllocator.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,167 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * A simple 32 bit block based memory allocator. This allows one or more memory segments to
+  * be designated as heap storage, and is designed to run in a static memory area or inside the standard C
+  * heap for use by the micro:bit runtime. This is required for several reasons:
+  *
+  * 1) It reduces memory fragmentation due to the high churn sometime placed on the heap
+  * by ManagedTypes, fibers and user code. Underlying heap implentations are often have very simplistic
+  * allocation pilicies and suffer from fragmentation in prolonged use - which can cause programs to
+  * stop working after a period of time. The algorithm implemented here is simple, but highly tolerant to
+  * large amounts of churn.
+  *
+  * 2) It allows us to reuse the 8K of SRAM set aside for SoftDevice as additional heap storage
+  * when BLE is not in use.
+  *
+  * 3) It gives a simple example of how memory allocation works! :-)
+  *
+  * P.S. This is a very simple allocator, therefore not without its weaknesses. Why don't you consider
+  * what these are, and consider the tradeoffs against simplicity...
+  *
+  * @note The need for this should be reviewed in the future, if a different memory allocator is
+  * made availiable in the mbed platform.
+  *
+  * TODO: Consider caching recently freed blocks to improve allocation time.
+  */
+
+#ifndef MICROBIT_HEAP_ALLOCTOR_H
+#define MICROBIT_HEAP_ALLOCTOR_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include <new>
+
+// The maximum number of heap segments that can be created.
+#define MICROBIT_MAXIMUM_HEAPS          2
+
+// Flag to indicate that a given block is FREE/USED
+#define MICROBIT_HEAP_BLOCK_FREE		0x80000000
+
+/**
+  * Create and initialise a given memory region as for heap storage.
+  * After this is called, any future calls to malloc, new, free or delete may use the new heap.
+  * The heap allocator will attempt to allocate memory from heaps in the order that they are created.
+  * i.e. memory will be allocated from first heap created until it is full, then the second heap, and so on.
+  *
+  * @param start The start address of memory to use as a heap region.
+  *
+  * @param end The end address of memory to use as a heap region.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
+  *
+  * @note Only code that #includes MicroBitHeapAllocator.h will use this heap. This includes all micro:bit runtime
+  * code, and user code targetting the runtime. External code can choose to include this file, or
+  * simply use the standard heap.
+  */
+int microbit_create_heap(uint32_t start, uint32_t end);
+
+/**
+  * Create and initialise a heap region within the current the heap region specified
+  * by the linker script.
+  *
+  * If the requested amount is not available, then the amount requested will be reduced
+  * automatically to fit the space available.
+  *
+  * @param ratio The proportion of the underlying heap to allocate.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
+  */
+int microbit_create_nested_heap(float ratio);
+
+/**
+  * Attempt to allocate a given amount of memory from any of our configured heap areas.
+  *
+  * @param size The amount of memory, in bytes, to allocate.
+  *
+  * @return A pointer to the allocated memory, or NULL if insufficient memory is available.
+  */
+void *microbit_malloc(size_t size);
+
+
+/**
+  * Release a given area of memory from the heap.
+  *
+  * @param mem The memory area to release.
+  */
+void microbit_free(void *mem);
+
+/*
+ * Wrapper function to ensure we have an explicit handle on the heap allocator provided
+ * by our underlying platform.
+ *
+ * @param size The amount of memory, in bytes, to allocate.
+ *
+ * @return A pointer to the memory allocated. NULL if no memory is available.
+ */
+inline void *native_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+/*
+ * Wrapper function to ensure we have an explicit handle on the heap allocator provided
+ * by our underlying platform.
+ *
+ * @param p Pointer to the memory to be freed.
+ */
+inline void native_free(void *p)
+{
+    free(p);
+}
+
+/**
+  * Overrides the 'new' operator globally, and redirects calls to the micro:bit heap allocator.
+  */
+inline void* operator new(size_t size) throw(std::bad_alloc)
+{
+    return microbit_malloc(size);
+}
+
+/**
+  * Overrides the 'new' operator globally, and redirects calls to the micro:bit theap allocator.
+  */
+inline void* operator new[](size_t size) throw(std::bad_alloc)
+{
+    return microbit_malloc(size);
+}
+
+/**
+  * Overrides the 'delete' operator globally, and redirects calls to the micro:bit theap allocator.
+  */
+inline void operator delete(void *ptr) throw()
+{
+    microbit_free(ptr);
+}
+
+
+// Macros to override overrides the 'malloc' and 'delete' functions globally, and redirects calls
+// to the micro:bit theap allocator.
+
+#define malloc(X) microbit_malloc( X )
+#define free(X) microbit_free( X )
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitListener.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,169 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_LISTENER_H
+#define MICROBIT_LISTENER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitEvent.h"
+#include "MemberFunctionCallback.h"
+#include "MicroBitConfig.h"
+
+// MicroBitListener flags...
+#define MESSAGE_BUS_LISTENER_PARAMETERISED          0x0001
+#define MESSAGE_BUS_LISTENER_METHOD                 0x0002
+#define MESSAGE_BUS_LISTENER_BUSY                   0x0004
+#define MESSAGE_BUS_LISTENER_REENTRANT              0x0008
+#define MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY          0x0010
+#define MESSAGE_BUS_LISTENER_DROP_IF_BUSY           0x0020
+#define MESSAGE_BUS_LISTENER_NONBLOCKING            0x0040
+#define MESSAGE_BUS_LISTENER_URGENT                 0x0080
+#define MESSAGE_BUS_LISTENER_DELETING               0x8000
+
+#define MESSAGE_BUS_LISTENER_IMMEDIATE              (MESSAGE_BUS_LISTENER_NONBLOCKING |  MESSAGE_BUS_LISTENER_URGENT)
+
+/**
+  *	This structure defines a MicroBitListener used to invoke functions, or member
+  * functions if an instance of EventModel receives an event whose id and value
+  * match this MicroBitListener's id and value.
+  */
+struct MicroBitListener
+{
+	uint16_t		id;				// The ID of the component that this listener is interested in.
+	uint16_t 		value;			// Value this listener is interested in receiving.
+    uint16_t        flags;          // Status and configuration options codes for this listener.
+
+    union
+    {
+        void (*cb)(MicroBitEvent);
+        void (*cb_param)(MicroBitEvent, void *);
+        MemberFunctionCallback *cb_method;
+    };
+
+	void*			cb_arg;			// Optional argument to be passed to the caller.
+
+	MicroBitEvent 	            evt;
+	MicroBitEventQueueItem 	    *evt_queue;
+
+	MicroBitListener *next;
+
+	/**
+	  * Constructor.
+	  *
+	  * Create a new Message Bus Listener.
+	  *
+	  * @param id The ID of the component you want to listen to.
+	  *
+	  * @param value The event value you would like to listen to from that component
+	  *
+	  * @param handler A function pointer to call when the event is detected.
+	  *
+	  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+	  */
+	MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent), uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS);
+
+	/**
+	  * Constructor.
+	  *
+	  * Create a new Message Bus Listener, this constructor accepts an additional
+	  * parameter "arg", which is passed to the handler.
+	  *
+	  * @param id The ID of the component you want to listen to.
+	  *
+	  * @param value The event value you would like to listen to from that component
+	  *
+	  * @param handler A function pointer to call when the event is detected.
+	  *
+	  * @param arg A pointer to some data that will be given to the handler.
+	  *
+	  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+	  */
+    MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent, void *), void* arg, uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS);
+
+
+	/**
+	  * Constructor.
+	  *
+	  * Create a new Message Bus Listener, with a callback to a C++ member function.
+	  *
+	  * @param id The ID of the component you want to listen to.
+	  *
+	  * @param value The event value you would like to listen to from that component
+	  *
+	  * @param object The C++ object on which to call the event handler.
+	  *
+      * @param method The method within the C++ object to call.
+	  *
+	  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+      * to be tuned.
+	  */
+    template <typename T>
+    MicroBitListener(uint16_t id, uint16_t value, T* object, void (T::*method)(MicroBitEvent), uint16_t flags = EVENT_LISTENER_DEFAULT_FLAGS);
+
+    /**
+      * Destructor. Ensures all resources used by this listener are freed.
+      */
+    ~MicroBitListener();
+
+    /**
+      * Queues and event up to be processed.
+	  *
+      * @param e The event to queue
+      */
+    void queue(MicroBitEvent e);
+};
+
+/**
+  * Constructor.
+  *
+  * Create a new Message Bus Listener, with a callback to a C++ member function.
+  *
+  * @param id The ID of the component you want to listen to.
+  *
+  * @param value The event value you would like to listen to from that component
+  *
+  * @param object The C++ object on which to call the event handler.
+  *
+  * @param method The method within the C++ object to call.
+  *
+  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+  * to be tuned.
+  */
+template <typename T>
+MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, T* object, void (T::*method)(MicroBitEvent), uint16_t flags)
+{
+	this->id = id;
+	this->value = value;
+    this->cb_method = new MemberFunctionCallback(object, method);
+	this->cb_arg = NULL;
+    this->flags = flags | MESSAGE_BUS_LISTENER_METHOD;
+    this->evt_queue = NULL;
+	this->next = NULL;
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/MicroBitSystemTimer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,164 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Definitions for the MicroBit system timer.
+  *
+  * This module provides:
+  *
+  * 1) a concept of global system time since power up
+  * 2) a simple periodic multiplexing API for the underlying mbed implementation.
+  *
+  * The latter is useful to avoid costs associated with multiple mbed Ticker instances
+  * in microbit-dal components, as each incurs a significant additional RAM overhead (circa 80 bytes).
+  */
+
+#ifndef MICROBIT_SYSTEM_TIMER_H
+#define MICROBIT_SYSTEM_TIMER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+
+/**
+  * Initialises a system wide timer, used to drive the various components used in the runtime.
+  *
+  * This must be called before any components register to receive periodic periodic callbacks.
+  *
+  * @param timer_period The initial period between interrupts, in millseconds.
+  *
+  * @return MICROBIT_OK on success.
+  */
+int system_timer_init(int period);
+
+/**
+  * Reconfigures the system wide timer to the given period in milliseconds.
+  *
+  * @param period the new period of the timer in milliseconds
+  *
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if period < 1
+  */
+int system_timer_set_period(int period);
+
+/**
+  * Accessor to obtain the current tick period in milliseconds
+  *
+  * @return the current tick period in milliseconds
+  */
+int system_timer_get_period();
+
+/**
+  * Updates the current time in microseconds, since power on.
+  *
+  * If the mbed Timer hasn't been initialised, it will be initialised
+  * on the first call to this function.
+  */
+inline void update_time();
+
+/**
+  * Determines the time since the device was powered on.
+  *
+  * @return the current time since power on in milliseconds
+  */
+uint64_t system_timer_current_time();
+
+/**
+  * Determines the time since the device was powered on.
+  *
+  * @return the current time since power on in microseconds
+  */
+uint64_t system_timer_current_time_us();
+
+/**
+  * Timer callback. Called from interrupt context, once per period.
+  *
+  * Simply checks to determine if any fibers blocked on the sleep queue need to be woken up
+  * and made runnable.
+  */
+void system_timer_tick();
+
+/**
+  * Add a component to the array of system components. This component will then receive
+  * periodic callbacks, once every tick period in interrupt context.
+  *
+  * @param component The component to add.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the component array is full.
+  *
+  * @code
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitDisplay* display = new MicroBitDisplay();
+  *
+  * system_timer_add_component(display);
+  * @endcode
+  */
+int system_timer_add_component(MicroBitComponent *component);
+
+/**
+  * Remove a component from the array of system components. This component will no longer receive
+  * periodic callbacks.
+  *
+  * @param component The component to remove.
+  *
+  * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  *
+  * @code
+  * // heap allocated - otherwise it will be paged out!
+  * MicroBitDisplay* display = new MicroBitDisplay();
+  *
+  * system_timer_add_component(display);
+  *
+  * system_timer_remove_component(display);
+  * @endcode
+  */
+int system_timer_remove_component(MicroBitComponent *component);
+
+/**
+  * A simple C/C++ wrapper to allow periodic callbacks to standard C functions transparently.
+  */
+class MicroBitSystemTimerCallback : MicroBitComponent
+{
+    void (*fn)(void);
+
+    /**
+     * Creates an object that receives periodic callbacks from the system timer,
+     * and, in turn, calls a plain C function as provided as a parameter.
+     *
+     * @param function the function to invoke upon a systemTick.
+     */
+    public:
+    MicroBitSystemTimerCallback(void (*function)(void))
+    {
+        fn = function;
+        system_timer_add_component(this);
+    }
+
+    void systemTick()
+    {
+        fn();
+    }
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/core/NotifyEvents.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,37 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef NOTIFY_EVENTS_H
+#define NOTIFY_EVENTS_H
+
+/**
+  * This file contains events used on the general purpose Eventing channel
+  * MICROBIT_ID_NOTIFY, new events should be added here, to prevent duplication.
+  */
+#define MICROBIT_DISPLAY_EVT_FREE           1
+#define MICROBIT_SERIAL_EVT_TX_EMPTY        2
+#define MICROBIT_UART_S_EVT_TX_EMPTY        3
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/DynamicPwm.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,216 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+#ifndef MICROBIT_DYNAMIC_PWM_H
+#define MICROBIT_DYNAMIC_PWM_H
+
+#define NO_PWMS 3
+#define MICROBIT_DEFAULT_PWM_PERIOD 20000
+
+enum PwmPersistence
+{
+    PWM_PERSISTENCE_TRANSIENT = 1,
+    PWM_PERSISTENCE_PERSISTENT = 2,
+};
+
+/**
+  * Class definition for DynamicPwm.
+  *
+  * This class addresses a few issues found in the underlying libraries.
+  * This provides the ability for a neat, clean swap between PWM channels.
+  */
+class DynamicPwm : public PwmOut
+{
+    private:
+    static DynamicPwm* pwms[NO_PWMS];
+    static uint8_t lastUsed;
+    static uint16_t sharedPeriod;
+    uint8_t flags;
+    float lastValue;
+
+
+
+    /**
+      * An internal constructor used when allocating a new DynamicPwm instance.
+      *
+      * @param pin the name of the pin for the pwm to target
+      *
+      * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
+      *                    or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
+      */
+    DynamicPwm(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT);
+
+    public:
+
+    /**
+      * Redirects the pwm channel to point at a different pin.
+      *
+      * @param pin the desired pin to output a PWM wave.
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      * pwm->redirect(p0); // pwm is now produced on p0
+      * @endcode
+      */
+    void redirect(PinName pin);
+
+
+    /**
+      * Creates a new DynamicPwm instance, or reuses an existing instance that
+      * has a persistence level of PWM_PERSISTENCE_TRANSIENT.
+      *
+      * @param pin the name of the pin for the pwm to target
+      *
+      * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
+      *                    or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
+      *
+      * @return a pointer to the first available free pwm channel - or the first one that can be reallocated. If
+      *         no channels are available, NULL is returned.
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      * @endcode
+      */
+    static DynamicPwm* allocate(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT);
+
+    /**
+      * Frees this DynamicPwm instance for reuse.
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate();
+      * pwm->release();
+      * @endcode
+      */
+    void release();
+
+    /**
+      * A lightweight wrapper around the super class' write in order to capture the value
+      *
+      * @param value the duty cycle percentage in floating point format.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate();
+      * pwm->write(0.5);
+      * @endcode
+      */
+    int write(float value);
+
+    /**
+      * Retreives the PinName associated with this DynamicPwm instance.
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      *
+      * // returns the PinName n.
+      * pwm->getPinName();
+      * @endcode
+      *
+      * @note This should be used to check that the DynamicPwm instance has not
+      *       been reallocated for use in another part of a program.
+      */
+    PinName getPinName();
+
+    /**
+      * Retreives the last value that has been written to this DynamicPwm instance.
+      * in the range 0 - 1023 inclusive.
+      *
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      * pwm->write(0.5);
+      *
+      * // will return 512.
+      * pwm->getValue();
+      * @endcode
+      */
+    int getValue();
+
+    /**
+      * Retreives the current period in use by the entire PWM module in microseconds.
+      *
+      * Example:
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      * pwm->getPeriod();
+      * @endcode
+      */
+    int getPeriodUs();
+
+    /**
+      * Retreives the current period in use by the entire PWM module in milliseconds.
+      *
+      * Example:
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      * pwm->setPeriodUs(20000);
+      *
+      * // will return 20000
+      * pwm->getPeriod();
+      * @endcode
+      */
+    int getPeriod();
+
+    /**
+      * Sets the period used by the WHOLE PWM module.
+      *
+      * @param period the desired period in microseconds.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
+      *
+      * Example:
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      *
+      * // period now is 20ms
+      * pwm->setPeriodUs(20000);
+      * @endcode
+      *
+      * @note Any changes to the period will AFFECT ALL CHANNELS.
+      */
+    int setPeriodUs(int period);
+
+    /**
+      * Sets the period used by the WHOLE PWM module. Any changes to the period will AFFECT ALL CHANNELS.
+      *
+      * @param period the desired period in milliseconds.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
+      *
+      * Example:
+      * @code
+      * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+      *
+      * // period now is 20ms
+      * pwm->setPeriod(20);
+      * @endcode
+      */
+      int setPeriod(int period);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitAccelerometer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,452 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_ACCELEROMETER_H
+#define MICROBIT_ACCELEROMETER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitCoordinateSystem.h"
+#include "MicroBitI2C.h"
+
+/**
+  * Relevant pin assignments
+  */
+#define MICROBIT_PIN_ACCEL_DATA_READY          P0_28
+
+/**
+  * Status flags
+  */
+#define MICROBIT_ACCEL_PITCH_ROLL_VALID           0x02
+#define MICROBIT_ACCEL_ADDED_TO_IDLE              0x04
+
+/**
+  * I2C constants
+  */
+#define MMA8653_DEFAULT_ADDR    0x3A
+
+/**
+  * MMA8653 Register map (partial)
+  */
+#define MMA8653_STATUS          0x00
+#define MMA8653_OUT_X_MSB       0x01
+#define MMA8653_WHOAMI          0x0D
+#define MMA8653_XYZ_DATA_CFG    0x0E
+#define MMA8653_CTRL_REG1       0x2A
+#define MMA8653_CTRL_REG2       0x2B
+#define MMA8653_CTRL_REG3       0x2C
+#define MMA8653_CTRL_REG4       0x2D
+#define MMA8653_CTRL_REG5       0x2E
+
+
+/**
+  * MMA8653 constants
+  */
+#define MMA8653_WHOAMI_VAL      0x5A
+
+#define MMA8653_SAMPLE_RANGES   3
+#define MMA8653_SAMPLE_RATES    8
+
+/**
+  * Accelerometer events
+  */
+#define MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE              1
+
+/**
+  * Gesture events
+  */
+#define MICROBIT_ACCELEROMETER_EVT_NONE                     0
+#define MICROBIT_ACCELEROMETER_EVT_TILT_UP                  1
+#define MICROBIT_ACCELEROMETER_EVT_TILT_DOWN                2
+#define MICROBIT_ACCELEROMETER_EVT_TILT_LEFT                3
+#define MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT               4
+#define MICROBIT_ACCELEROMETER_EVT_FACE_UP                  5
+#define MICROBIT_ACCELEROMETER_EVT_FACE_DOWN                6
+#define MICROBIT_ACCELEROMETER_EVT_FREEFALL                 7
+#define MICROBIT_ACCELEROMETER_EVT_3G                       8
+#define MICROBIT_ACCELEROMETER_EVT_6G                       9
+#define MICROBIT_ACCELEROMETER_EVT_8G                       10
+#define MICROBIT_ACCELEROMETER_EVT_SHAKE                    11
+
+/**
+  * Gesture recogniser constants
+  */
+#define MICROBIT_ACCELEROMETER_REST_TOLERANCE               200
+#define MICROBIT_ACCELEROMETER_TILT_TOLERANCE               200
+#define MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE           400
+#define MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE              400
+#define MICROBIT_ACCELEROMETER_3G_TOLERANCE                 3072
+#define MICROBIT_ACCELEROMETER_6G_TOLERANCE                 6144
+#define MICROBIT_ACCELEROMETER_8G_TOLERANCE                 8192
+#define MICROBIT_ACCELEROMETER_GESTURE_DAMPING              5
+#define MICROBIT_ACCELEROMETER_SHAKE_DAMPING                10 
+#define MICROBIT_ACCELEROMETER_SHAKE_RTX                    30
+
+#define MICROBIT_ACCELEROMETER_REST_THRESHOLD               (MICROBIT_ACCELEROMETER_REST_TOLERANCE * MICROBIT_ACCELEROMETER_REST_TOLERANCE)
+#define MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD           (MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE * MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE)
+#define MICROBIT_ACCELEROMETER_3G_THRESHOLD                 (MICROBIT_ACCELEROMETER_3G_TOLERANCE * MICROBIT_ACCELEROMETER_3G_TOLERANCE)
+#define MICROBIT_ACCELEROMETER_6G_THRESHOLD                 (MICROBIT_ACCELEROMETER_6G_TOLERANCE * MICROBIT_ACCELEROMETER_6G_TOLERANCE)
+#define MICROBIT_ACCELEROMETER_8G_THRESHOLD                 (MICROBIT_ACCELEROMETER_8G_TOLERANCE * MICROBIT_ACCELEROMETER_8G_TOLERANCE)
+#define MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD        4
+
+struct MMA8653Sample
+{
+    int16_t         x;
+    int16_t         y;
+    int16_t         z;
+};
+
+struct MMA8653SampleRateConfig
+{
+    uint32_t        sample_period;
+    uint8_t         ctrl_reg1;
+};
+
+struct MMA8653SampleRangeConfig
+{
+    uint8_t         sample_range;
+    uint8_t         xyz_data_cfg;
+};
+
+
+extern const MMA8653SampleRangeConfig MMA8653SampleRange[];
+extern const MMA8653SampleRateConfig MMA8653SampleRate[];
+
+struct ShakeHistory
+{
+    uint16_t    shaken:1,
+                x:1,
+                y:1,
+                z:1,
+                unused,
+                impulse_3,
+                impulse_6,
+                impulse_8,
+                count:8;
+
+    uint16_t    timer;
+};
+
+/**
+ * Class definition for MicroBit Accelerometer.
+ *
+ * Represents an implementation of the Freescale MMA8653 3 axis accelerometer
+ * Also includes basic data caching and on demand activation.
+ */
+class MicroBitAccelerometer : public MicroBitComponent
+{
+    uint16_t        address;            // I2C address of this accelerometer.
+    uint16_t        samplePeriod;       // The time between samples, in milliseconds.
+    uint8_t         sampleRange;        // The sample range of the accelerometer in g.
+    MMA8653Sample   sample;             // The last sample read.
+    DigitalIn       int1;               // Data ready interrupt.
+    float           pitch;              // Pitch of the device, in radians.
+    MicroBitI2C&    i2c;                // The I2C interface to use.
+    float           roll;               // Roll of the device, in radians.
+    uint8_t         sigma;              // the number of ticks that the instantaneous gesture has been stable.
+    uint8_t         impulseSigma;       // the number of ticks since an impulse event has been generated.
+    uint16_t        lastGesture;        // the last, stable gesture recorded.
+    uint16_t        currentGesture;     // the instantaneous, unfiltered gesture detected.
+    ShakeHistory    shake;              // State information needed to detect shake events.
+
+    public:
+
+    /**
+      * Constructor.
+      * Create a software abstraction of an accelerometer.
+      *
+      * @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer.
+      *
+      * @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR.
+      *
+      * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
+      *
+      * @code
+      * MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0);
+      *
+      * MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c);
+      * @endcode
+     */
+    MicroBitAccelerometer(MicroBitI2C &_i2c, uint16_t address = MMA8653_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_ACCELEROMETER);
+
+    /**
+      * Configures the accelerometer for G range and sample rate defined
+      * in this object. The nearest values are chosen to those defined
+      * that are supported by the hardware. The instance variables are then
+      * updated to reflect reality.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
+      */
+    int configure();
+
+    /**
+      * Reads the acceleration data from the accelerometer, and stores it in our buffer.
+      * This only happens if the accelerometer indicates that it has new data via int1.
+      *
+      * On first use, this member function will attempt to add this component to the
+      * list of fiber components in order to constantly update the values stored
+      * by this object.
+      *
+      * This technique is called lazy instantiation, and it means that we do not
+      * obtain the overhead from non-chalantly adding this component to fiber components.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails.
+      */
+    int updateSample();
+
+    /**
+      * Attempts to set the sample rate of the accelerometer to the specified value (in ms).
+      *
+      * @param period the requested time between samples, in milliseconds.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
+      *
+      * @code
+      * // sample rate is now 20 ms.
+      * accelerometer.setPeriod(20);
+      * @endcode
+      *
+      * @note The requested rate may not be possible on the hardware. In this case, the
+      * nearest lower rate is chosen.
+      */
+    int setPeriod(int period);
+
+    /**
+      * Reads the currently configured sample rate of the accelerometer.
+      *
+      * @return The time between samples, in milliseconds.
+      */
+    int getPeriod();
+
+    /**
+      * Attempts to set the sample range of the accelerometer to the specified value (in g).
+      *
+      * @param range The requested sample range of samples, in g.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
+      *
+      * @code
+      * // the sample range of the accelerometer is now 8G.
+      * accelerometer.setRange(8);
+      * @endcode
+      *
+      * @note The requested range may not be possible on the hardware. In this case, the
+      * nearest lower range is chosen.
+      */
+    int setRange(int range);
+
+    /**
+      * Reads the currently configured sample range of the accelerometer.
+      *
+      * @return The sample range, in g.
+      */
+    int getRange();
+
+    /**
+      * Attempts to read the 8 bit ID from the accelerometer, this can be used for
+      * validation purposes.
+      *
+      * @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails.
+      *
+      * @code
+      * accelerometer.whoAmI();
+      * @endcode
+      */
+    int whoAmI();
+
+    /**
+      * Reads the value of the X axis from the latest update retrieved from the accelerometer.
+      *
+      * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+      *
+      * @return The force measured in the X axis, in milli-g.
+      *
+      * @code
+      * accelerometer.getX();
+      * @endcode
+      */
+    int getX(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Reads the value of the Y axis from the latest update retrieved from the accelerometer.
+      *
+      * @return The force measured in the Y axis, in milli-g.
+      *
+      * @code
+      * accelerometer.getY();
+      * @endcode
+      */
+    int getY(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Reads the value of the Z axis from the latest update retrieved from the accelerometer.
+      *
+      * @return The force measured in the Z axis, in milli-g.
+      *
+      * @code
+      * accelerometer.getZ();
+      * @endcode
+      */
+    int getZ(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
+      *
+      * @return The pitch of the device, in degrees.
+      *
+      * @code
+      * accelerometer.getPitch();
+      * @endcode
+      */
+    int getPitch();
+
+    /**
+      * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
+      *
+      * @return The pitch of the device, in radians.
+      *
+      * @code
+      * accelerometer.getPitchRadians();
+      * @endcode
+      */
+    float getPitchRadians();
+
+    /**
+      * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
+      *
+      * @return The roll of the device, in degrees.
+      *
+      * @code
+      * accelerometer.getRoll();
+      * @endcode
+      */
+    int getRoll();
+
+    /**
+      * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
+      *
+      * @return The roll of the device, in radians.
+      *
+      * @code
+      * accelerometer.getRollRadians();
+      * @endcode
+      */
+    float getRollRadians();
+
+    /**
+      * Retrieves the last recorded gesture.
+      *
+      * @return The last gesture that was detected.
+      *
+      * Example:
+      * @code
+      * MicroBitDisplay display;
+      *
+      * if (accelerometer.getGesture() == SHAKE)
+      *     display.scroll("SHAKE!");
+      * @endcode
+      */
+    uint16_t getGesture();
+
+    /**
+      * A periodic callback invoked by the fiber scheduler idle thread.
+      *
+      * Internally calls updateSample().
+      */
+    virtual void idleTick();
+
+    /**
+      * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components.
+      */
+    ~MicroBitAccelerometer();
+
+    private:
+
+    /**
+      * Issues a standard, 2 byte I2C command write to the accelerometer.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the register to write to.
+      *
+      * @param value The value to write.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed.
+      */
+    int writeCommand(uint8_t reg, uint8_t value);
+
+    /**
+      * Issues a read command, copying data into the specified buffer.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the register to access.
+      *
+      * @param buffer Memory area to read the data into.
+      *
+      * @param length The number of bytes to read.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed.
+      */
+    int readCommand(uint8_t reg, uint8_t* buffer, int length);
+
+    /**
+      * Recalculate roll and pitch values for the current sample.
+      *
+      * @note We only do this at most once per sample, as the necessary trigonemteric functions are rather
+      *       heavyweight for a CPU without a floating point unit.
+      */
+    void recalculatePitchRoll();
+
+    /**
+      * Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote
+      * stability.
+      */
+    void updateGesture();
+
+    /**
+      * A service function.
+      * It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2).
+      * It does not, however, square root the result, as this is a relatively high cost operation.
+      *
+      * This is left to application code should it be needed.
+      *
+      * @return the sum of the square of the acceleration of the device across all axes.
+      */
+    int instantaneousAccelerationSquared();
+
+    /**
+     * Service function.
+     * Determines a 'best guess' posture of the device based on instantaneous data.
+     *
+     * This makes no use of historic data, and forms this input to the filter implemented in updateGesture().
+     *
+     * @return A 'best guess' of the current posture of the device, based on instanataneous data.
+     */
+    uint16_t instantaneousPosture();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitButton.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,145 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_BUTTON_H
+#define MICROBIT_BUTTON_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitEvent.h"
+
+#define MICROBIT_PIN_BUTTON_A                   P0_17
+#define MICROBIT_PIN_BUTTON_B                   P0_26
+#define MICROBIT_PIN_BUTTON_RESET               P0_19
+
+#define MICROBIT_BUTTON_EVT_DOWN                1
+#define MICROBIT_BUTTON_EVT_UP                  2
+#define MICROBIT_BUTTON_EVT_CLICK               3
+#define MICROBIT_BUTTON_EVT_LONG_CLICK          4
+#define MICROBIT_BUTTON_EVT_HOLD                5
+#define MICROBIT_BUTTON_EVT_DOUBLE_CLICK        6
+
+#define MICROBIT_BUTTON_LONG_CLICK_TIME         1000
+#define MICROBIT_BUTTON_HOLD_TIME               1500
+
+#define MICROBIT_BUTTON_STATE                   1
+#define MICROBIT_BUTTON_STATE_HOLD_TRIGGERED    2
+#define MICROBIT_BUTTON_STATE_CLICK             4
+#define MICROBIT_BUTTON_STATE_LONG_CLICK        8
+
+#define MICROBIT_BUTTON_SIGMA_MIN               0
+#define MICROBIT_BUTTON_SIGMA_MAX               12
+#define MICROBIT_BUTTON_SIGMA_THRESH_HI         8
+#define MICROBIT_BUTTON_SIGMA_THRESH_LO         2
+#define MICROBIT_BUTTON_DOUBLE_CLICK_THRESH     50
+
+enum MicroBitButtonEventConfiguration
+{
+    MICROBIT_BUTTON_SIMPLE_EVENTS,
+    MICROBIT_BUTTON_ALL_EVENTS
+};
+
+
+/**
+  * Class definition for MicroBit Button.
+  *
+  * Represents a single, generic button on the device.
+  */
+class MicroBitButton : public MicroBitComponent
+{
+    PinName name;                                           // mbed pin name for this button.
+    DigitalIn pin;                                          // The mbed object looking after this pin at any point in time (may change!).
+
+    unsigned long downStartTime;                            // used to store the current system clock when a button down event occurs
+    uint8_t sigma;                                          // integration of samples over time. We use this for debouncing, and noise tolerance for touch sensing
+    MicroBitButtonEventConfiguration eventConfiguration;    // Do we want to generate high level event (clicks), or defer this to another service.
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create a software representation of a button.
+      *
+      * @param name the physical pin on the processor that should be used as input.
+      *
+      * @param id the ID of the new MicroBitButton object.
+      *
+      * @param eventConfiguration Configures the events that will be generated by this MicroBitButton instance.
+      *                           Defaults to MICROBIT_BUTTON_ALL_EVENTS.
+      *
+      * @param mode the configuration of internal pullups/pulldowns, as defined in the mbed PinMode class. PullNone by default.
+      *
+      * @code
+      * buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A);
+      * @endcode
+      */
+    MicroBitButton(PinName name, uint16_t id, MicroBitButtonEventConfiguration eventConfiguration = MICROBIT_BUTTON_ALL_EVENTS, PinMode mode = PullNone);
+
+    /**
+      * Tests if this Button is currently pressed.
+      *
+      * @code
+      * if(buttonA.isPressed())
+      *     display.scroll("Pressed!");
+      * @endcode
+      *
+      * @return 1 if this button is pressed, 0 otherwise.
+      */
+    int isPressed();
+
+    /**
+      * Changes the event configuration used by this button to the given MicroBitButtonEventConfiguration.
+      *
+      * All subsequent events generated by this button will then be informed by this configuraiton.
+      *
+      * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
+      *
+      * Example:
+      * @code
+      * // Configure a button to generate all possible events.
+      * buttonA.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
+      *
+      * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
+      * buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+      * @endcode
+      */
+    void setEventConfiguration(MicroBitButtonEventConfiguration config);
+
+    /**
+      * periodic callback from MicroBit system timer.
+      *
+      * Check for state change for this button, and fires various events on a state change.
+      */
+    virtual void systemTick();
+
+    /**
+      * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components.
+      */
+    ~MicroBitButton();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitCompass.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,513 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_COMPASS_H
+#define MICROBIT_COMPASS_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitCoordinateSystem.h"
+#include "MicroBitAccelerometer.h"
+#include "MicroBitStorage.h"
+
+/**
+  * Relevant pin assignments
+  */
+#define MICROBIT_PIN_COMPASS_DATA_READY          P0_29
+
+/**
+  * I2C constants
+  */
+#define MAG3110_DEFAULT_ADDR    0x1D
+
+/**
+  * MAG3110 Register map
+  */
+#define MAG_DR_STATUS 0x00
+#define MAG_OUT_X_MSB 0x01
+#define MAG_OUT_X_LSB 0x02
+#define MAG_OUT_Y_MSB 0x03
+#define MAG_OUT_Y_LSB 0x04
+#define MAG_OUT_Z_MSB 0x05
+#define MAG_OUT_Z_LSB 0x06
+#define MAG_WHOAMI    0x07
+#define MAG_SYSMOD    0x08
+#define MAG_OFF_X_MSB 0x09
+#define MAG_OFF_X_LSB 0x0A
+#define MAG_OFF_Y_MSB 0x0B
+#define MAG_OFF_Y_LSB 0x0C
+#define MAG_OFF_Z_MSB 0x0D
+#define MAG_OFF_Z_LSB 0x0E
+#define MAG_DIE_TEMP  0x0F
+#define MAG_CTRL_REG1 0x10
+#define MAG_CTRL_REG2 0x11
+
+/**
+  * Configuration options
+  */
+struct MAG3110SampleRateConfig
+{
+    uint32_t        sample_period;
+    uint8_t         ctrl_reg1;
+};
+
+extern const MAG3110SampleRateConfig MAG3110SampleRate[];
+
+#define MAG3110_SAMPLE_RATES                    11
+
+/**
+  * Compass events
+  */
+#define MICROBIT_COMPASS_EVT_CAL_REQUIRED       1               // DEPRECATED
+#define MICROBIT_COMPASS_EVT_CAL_START          2               // DEPRECATED
+#define MICROBIT_COMPASS_EVT_CAL_END            3               // DEPRECATED
+
+#define MICROBIT_COMPASS_EVT_DATA_UPDATE        4
+#define MICROBIT_COMPASS_EVT_CONFIG_NEEDED      5
+#define MICROBIT_COMPASS_EVT_CALIBRATE          6
+
+/**
+  * Status Bits
+  */
+#define MICROBIT_COMPASS_STATUS_CALIBRATED      2
+#define MICROBIT_COMPASS_STATUS_CALIBRATING     4
+#define MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE   8
+
+/**
+  * Term to convert sample data into SI units
+  */
+#define MAG3110_NORMALIZE_SAMPLE(x) (100*x)
+
+/**
+  * MAG3110 MAGIC ID value
+  * Returned from the MAG_WHO_AM_I register for ID purposes.
+  */
+#define MAG3110_WHOAMI_VAL 0xC4
+
+struct CompassSample
+{
+    int     x;
+    int     y;
+    int     z;
+
+    CompassSample()
+    {
+        this->x = 0;
+        this->y = 0;
+        this->z = 0;
+    }
+
+    CompassSample(int x, int y, int z)
+    {
+        this->x = x;
+        this->y = y;
+        this->z = z;
+    }
+
+    bool operator==(const CompassSample& other) const
+    {
+        return x == other.x && y == other.y && z == other.z;
+    }
+
+    bool operator!=(const CompassSample& other) const
+    {
+        return !(x == other.x && y == other.y && z == other.z);
+    }
+};
+
+/**
+  * Class definition for MicroBit Compass.
+  *
+  * Represents an implementation of the Freescale MAG3110 I2C Magnetmometer.
+  * Also includes basic caching, calibration and on demand activation.
+  */
+class MicroBitCompass : public MicroBitComponent
+{
+    uint16_t                address;                  // I2C address of the magnetmometer.
+    uint16_t                samplePeriod;             // The time between samples, in millseconds.
+
+    CompassSample           average;                  // Centre point of sample data.
+    CompassSample           sample;                   // The latest sample data recorded.
+    DigitalIn               int1;                     // Data ready interrupt.
+    MicroBitI2C&		    i2c;                      // The I2C interface the sensor is connected to.
+    MicroBitAccelerometer*  accelerometer;            // The accelerometer to use for tilt compensation.
+    MicroBitStorage*        storage;                  // An instance of MicroBitStorage used for persistence.
+
+    public:
+
+    /**
+      * Constructor.
+      * Create a software representation of an e-compass.
+      *
+      * @param _i2c an instance of i2c, which the compass is accessible from.
+      *
+      * @param _accelerometer an instance of the accelerometer, used for tilt compensation.
+      *
+      * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets.
+      *
+      * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * MicroBitAccelerometer accelerometer(i2c);
+      *
+      * MicroBitStorage storage;
+      *
+      * MicroBitCompass compass(i2c, accelerometer, storage);
+      * @endcode
+      */
+    MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, MicroBitStorage& _storage, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
+
+    /**
+      * Constructor.
+      * Create a software representation of an e-compass.
+      *
+      * @param _i2c an instance of i2c, which the compass is accessible from.
+      *
+      * @param _accelerometer an instance of the accelerometer, used for tilt compensation.
+      *
+      * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * MicroBitAccelerometer accelerometer(i2c);
+      *
+      * MicroBitCompass compass(i2c, accelerometer, storage);
+      * @endcode
+      */
+    MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
+
+    /**
+      * Constructor.
+      * Create a software representation of an e-compass.
+      *
+      * @param _i2c an instance of i2c, which the compass is accessible from.
+      *
+      * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets.
+      *
+      * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * MicroBitStorage storage;
+      *
+      * MicroBitCompass compass(i2c, storage);
+      * @endcode
+      */
+    MicroBitCompass(MicroBitI2C& _i2c, MicroBitStorage& _storage, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
+
+    /**
+      * Constructor.
+      * Create a software representation of an e-compass.
+      *
+      * @param _i2c an instance of i2c, which the compass is accessible from.
+      *
+      * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      *
+      * MicroBitCompass compass(i2c);
+      * @endcode
+      */
+    MicroBitCompass(MicroBitI2C& _i2c, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS);
+
+    /**
+      * Configures the compass for the sample rate defined in this object.
+      * The nearest values are chosen to those defined that are supported by the hardware.
+      * The instance variables are then updated to reflect reality.
+      *
+      * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be configured.
+      */
+    int configure();
+
+    /**
+      * Attempts to set the sample rate of the compass to the specified value (in ms).
+      *
+      * @param period the requested time between samples, in milliseconds.
+      *
+      * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be updated.
+      *
+      * @code
+      * // sample rate is now 20 ms.
+      * compass.setPeriod(20);
+      * @endcode
+      *
+      * @note The requested rate may not be possible on the hardware. In this case, the
+      * nearest lower rate is chosen.
+      */
+    int setPeriod(int period);
+
+    /**
+      * Reads the currently configured sample rate of the compass.
+      *
+      * @return The time between samples, in milliseconds.
+      */
+    int getPeriod();
+
+    /**
+      * Gets the current heading of the device, relative to magnetic north.
+      *
+      * If the compass is not calibrated, it will raise the MICROBIT_COMPASS_EVT_CALIBRATE event.
+      *
+      * Users wishing to implement their own calibration algorithms should listen for this event,
+      * using MESSAGE_BUS_LISTENER_IMMEDIATE model. This ensures that calibration is complete before
+      * the user program continues.
+      *
+      * @return the current heading, in degrees. Or MICROBIT_CALIBRATION_IN_PROGRESS if the compass is calibrating.
+      *
+      * @code
+      * compass.heading();
+      * @endcode
+      */
+    int heading();
+
+    /**
+      * Attempts to read the 8 bit ID from the magnetometer, this can be used for
+      * validation purposes.
+      *
+      * @return the 8 bit ID returned by the magnetometer, or MICROBIT_I2C_ERROR if the request fails.
+      *
+      * @code
+      * compass.whoAmI();
+      * @endcode
+      */
+    int whoAmI();
+
+    /**
+      * Reads the value of the X axis from the latest update retrieved from the magnetometer.
+      *
+      * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+      *
+      * @return The magnetic force measured in the X axis, in nano teslas.
+      *
+      * @code
+      * compass.getX();
+      * @endcode
+      */
+    int getX(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Reads the value of the Y axis from the latest update retrieved from the magnetometer.
+      *
+      * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+      *
+      * @return The magnetic force measured in the Y axis, in nano teslas.
+      *
+      * @code
+      * compass.getY();
+      * @endcode
+      */
+    int getY(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Reads the value of the Z axis from the latest update retrieved from the magnetometer.
+      *
+      * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+      *
+      * @return The magnetic force measured in the Z axis, in nano teslas.
+      *
+      * @code
+      * compass.getZ();
+      * @endcode
+      */
+    int getZ(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN);
+
+    /**
+      * Determines the overall magnetic field strength based on the latest update from the magnetometer.
+      *
+      * @return The magnetic force measured across all axis, in nano teslas.
+      *
+      * @code
+      * compass.getFieldStrength();
+      * @endcode
+      */
+    int getFieldStrength();
+
+    /**
+      * Reads the current die temperature of the compass.
+      *
+      * @return the temperature in degrees celsius, or MICROBIT_I2C_ERROR if the temperature reading could not be retreived
+      *         from the accelerometer.
+      */
+    int readTemperature();
+
+    /**
+      * Perform a calibration of the compass.
+      *
+      * This method will be called automatically if a user attempts to read a compass value when
+      * the compass is uncalibrated. It can also be called at any time by the user.
+      *
+      * The method will only return once the compass has been calibrated.
+      *
+      * @return MICROBIT_OK, MICROBIT_I2C_ERROR if the magnetometer could not be accessed,
+      * or MICROBIT_CALIBRATION_REQUIRED if the calibration algorithm failed to complete successfully.
+      *
+      * @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS
+      */
+    int calibrate();
+
+    /**
+      * Configure the compass to use the calibration data that is supplied to this call.
+      *
+      * Calibration data is comprised of the perceived zero offset of each axis of the compass.
+      *
+      * After calibration this should now take into account trimming errors in the magnetometer,
+      * and any "hard iron" offsets on the device.
+      *
+      * @param calibration A CompassSample containing the offsets for the x, y and z axis.
+      */
+    void setCalibration(CompassSample calibration);
+
+    /**
+      * Provides the calibration data currently in use by the compass.
+      *
+      * More specifically, the x, y and z zero offsets of the compass.
+      *
+      * @return calibration A CompassSample containing the offsets for the x, y and z axis.
+      */
+    CompassSample getCalibration();
+
+    /**
+      * Updates the local sample, only if the compass indicates that
+      * data is stale.
+      *
+      * @note Can be used to trigger manual updates, if the device is running without a scheduler.
+      *       Also called internally by all get[X,Y,Z]() member functions.
+      */
+    int updateSample();
+
+    /**
+      * Periodic callback from MicroBit idle thread.
+      *
+      * Calls updateSample().
+      */
+    virtual void idleTick();
+
+    /**
+      * Returns 0 or 1. 1 indicates that the compass is calibrated, zero means the compass requires calibration.
+      */
+    int isCalibrated();
+
+    /**
+      * Returns 0 or 1. 1 indicates that the compass is calibrating, zero means the compass is not currently calibrating.
+      */
+    int isCalibrating();
+
+    /**
+      * Clears the calibration held in persistent storage, and sets the calibrated flag to zero.
+      */
+    void clearCalibration();
+
+    /**
+      * Destructor for MicroBitCompass, where we deregister this instance from the array of fiber components.
+      */
+    ~MicroBitCompass();
+
+    private:
+
+    /**
+      * Issues a standard, 2 byte I2C command write to the accelerometer.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the register to write to.
+      *
+      * @param value The value to write.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed.
+      */
+    int writeCommand(uint8_t reg, uint8_t value);
+
+    /**
+      * Issues a read command, copying data into the specified buffer.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the register to access.
+      *
+      * @param buffer Memory area to read the data into.
+      *
+      * @param length The number of bytes to read.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed.
+      */
+    int readCommand(uint8_t reg, uint8_t* buffer, int length);
+
+    /**
+      * Issues a read of a given address, and returns the value.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the 16 bit register to access.
+      *
+      * @return The register value, interpreted as a 16 but signed value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed.
+      */
+    int read16(uint8_t reg);
+
+    /**
+      * Issues a read of a given address, and returns the value.
+      *
+      * Blocks the calling thread until complete.
+      *
+      * @param reg The address of the 16 bit register to access.
+      *
+      * @return The register value, interpreted as a 8 bit unsigned value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed.
+      */
+    int read8(uint8_t reg);
+
+    /**
+      * Calculates a tilt compensated bearing of the device, using the accelerometer.
+      */
+    int tiltCompensatedBearing();
+
+    /**
+      * Calculates a non-tilt compensated bearing of the device.
+      */
+    int basicBearing();
+
+    /**
+      * An initialisation member function used by the many constructors of MicroBitCompass.
+      *
+      * @param id the unique identifier for this compass instance.
+      *
+      * @param address the base address of the magnetometer on the i2c bus.
+      */
+    void init(uint16_t id, uint16_t address);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitCompassCalibrator.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,84 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_COMPASS_CALIBRATOR_H
+#define MICROBIT_COMPASS_CALIBRATOR_H
+
+#include "MicroBitConfig.h"
+#include "MicroBitCompass.h"
+#include "MicroBitAccelerometer.h"
+#include "MicroBitDisplay.h"
+
+
+/**
+  * Class definition for an interactive compass calibration algorithm.
+  *
+  * The algorithm uses an accelerometer to ensure that a broad range of sample data has been gathered
+  * from the compass module, then performs a least mean squares optimisation of the
+  * results to determine the calibration data for the compass.
+  *
+  * The LED matrix display is used to provide feedback to the user on the gestures required.
+  *
+  * This class listens for calibration requests from the compass (on the default event model),
+  * and automatically initiates a calibration sequence as necessary.
+  */
+class MicroBitCompassCalibrator
+{
+    MicroBitCompass&        compass;
+    MicroBitAccelerometer&  accelerometer;
+    MicroBitDisplay&        display;
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create an object capable of calibrating the compass.
+      *
+      * The algorithm uses an accelerometer to ensure that a broad range of sample data has been gathered
+      * from the compass module, then performs a least mean squares optimisation of the
+      * results to determine the calibration data for the compass.
+      *
+      * The LED matrix display is used to provide feedback to the user on the gestures required.
+      *
+      * @param compass The compass instance to calibrate.
+      *
+      * @param accelerometer The accelerometer to gather contextual data from.
+      *
+      * @param display The LED matrix to display user feedback on.
+      */
+    MicroBitCompassCalibrator(MicroBitCompass& _compass, MicroBitAccelerometer& _accelerometer, MicroBitDisplay& _display);
+
+    /**
+      * Performs a simple game that in parallel, calibrates the compass.
+      *
+      * This function is executed automatically when the user requests a compass bearing, and compass calibration is required.
+      *
+      * This function is, by design, synchronous and only returns once calibration is complete.
+      */
+    void calibrate(MicroBitEvent);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitDisplay.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,644 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_DISPLAY_H
+#define MICROBIT_DISPLAY_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "ManagedString.h"
+#include "MicroBitComponent.h"
+#include "MicroBitImage.h"
+#include "MicroBitFont.h"
+#include "MicroBitMatrixMaps.h"
+#include "MicroBitLightSensor.h"
+
+/**
+  * Event codes raised by MicroBitDisplay
+  */
+#define MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE         1
+#define MICROBIT_DISPLAY_EVT_LIGHT_SENSE                2
+
+//
+// Internal constants
+//
+#define MICROBIT_DISPLAY_DEFAULT_AUTOCLEAR      1
+#define MICROBIT_DISPLAY_SPACING                1
+#define MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH    8
+#define MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS    -255
+
+enum AnimationMode {
+    ANIMATION_MODE_NONE,
+    ANIMATION_MODE_STOPPED,
+    ANIMATION_MODE_SCROLL_TEXT,
+    ANIMATION_MODE_PRINT_TEXT,
+    ANIMATION_MODE_SCROLL_IMAGE,
+    ANIMATION_MODE_ANIMATE_IMAGE,
+    ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR,
+    ANIMATION_MODE_PRINT_CHARACTER
+};
+
+enum DisplayMode {
+    DISPLAY_MODE_BLACK_AND_WHITE,
+    DISPLAY_MODE_GREYSCALE,
+    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
+};
+
+enum DisplayRotation {
+    MICROBIT_DISPLAY_ROTATION_0,
+    MICROBIT_DISPLAY_ROTATION_90,
+    MICROBIT_DISPLAY_ROTATION_180,
+    MICROBIT_DISPLAY_ROTATION_270
+};
+
+/**
+  * Class definition for MicroBitDisplay.
+  *
+  * A MicroBitDisplay represents the LED matrix array on the micro:bit.
+  */
+class MicroBitDisplay : public MicroBitComponent
+{
+    uint8_t width;
+    uint8_t height;
+    uint8_t brightness;
+    uint8_t strobeRow;
+    uint8_t rotation;
+    uint8_t mode;
+    uint8_t greyscaleBitMsk;
+    uint8_t timingCount;
+    uint32_t col_mask;
+
+    Timeout renderTimer;
+    PortOut *LEDMatrix;
+
+    //
+    // State used by all animation routines.
+    //
+
+    // The animation mode that's currently running (if any)
+    volatile AnimationMode animationMode;
+
+    // The time in milliseconds between each frame update.
+    uint16_t animationDelay;
+
+    // The time in milliseconds since the frame update.
+    uint16_t animationTick;
+
+    // Stop playback of any animations
+    void stopAnimation(int delay);
+
+    //
+    // State for scrollString() method.
+    // This is a surprisingly intricate method.
+    //
+    // The text being displayed.
+    ManagedString scrollingText;
+
+    // The index of the character currently being displayed.
+    uint16_t scrollingChar;
+
+    // The number of pixels the current character has been shifted on the display.
+    uint8_t scrollingPosition;
+
+    //
+    // State for printString() method.
+    //
+    // The text being displayed. NULL if no message is scheduled for playback.
+    // We *could* get some reuse in here with the scroll* variables above,
+    // but best to keep it clean in case kids try concurrent operation (they will!),
+    // given the small RAM overhead needed to maintain orthogonality.
+    ManagedString printingText;
+
+    // The index of the character currently being displayed.
+    uint16_t printingChar;
+
+    //
+    // State for scrollImage() method.
+    //
+    // The image being displayed.
+    MicroBitImage scrollingImage;
+
+    // The number of pixels the image has been shifted on the display.
+    int16_t scrollingImagePosition;
+
+    // The number of pixels the image is shifted on the display in each quantum.
+    int8_t scrollingImageStride;
+
+    // A pointer to an instance of light sensor, if in use
+    MicroBitLightSensor* lightSensor;
+
+    // Flag to indicate if image has been rendered to screen yet (or not)
+    bool scrollingImageRendered;
+
+    const MatrixMap &matrixMap;
+
+    // Internal methods to handle animation.
+
+    /**
+      *  Periodic callback, that we use to perform any animations we have running.
+      */
+    void animationUpdate();
+
+    /**
+      *  Called by the display in an interval determined by the brightness of the display, to give an impression
+      *  of brightness.
+      */
+    void renderFinish();
+
+    /**
+      * Translates a bit mask to a bit mask suitable for the nrf PORT0 and PORT1.
+      * Brightness has two levels on, or off.
+      */
+    void render();
+
+    /**
+      * Renders the current image, and drops the fourth frame to allow for
+      * sensors that require the display to operate.
+      */
+    void renderWithLightSense();
+
+    /**
+      * Translates a bit mask into a timer interrupt that gives the appearence of greyscale.
+      */
+    void renderGreyscale();
+
+    /**
+      * Internal scrollText update method.
+      * Shift the screen image by one pixel to the left. If necessary, paste in the next char.
+      */
+    void updateScrollText();
+
+    /**
+      * Internal printText update method.
+      * Paste the next character in the string.
+      */
+    void updatePrintText();
+
+    /**
+      * Internal scrollImage update method.
+      * Paste the stored bitmap at the appropriate point.
+      */
+    void updateScrollImage();
+
+    /**
+      * Internal animateImage update method.
+      * Paste the stored bitmap at the appropriate point and stop on the last frame.
+      */
+    void updateAnimateImage();
+
+    /**
+     * Broadcasts an event onto the defult EventModel indicating that the
+     * current animation has completed.
+     */
+    void sendAnimationCompleteEvent();
+
+    /**
+      * Blocks the current fiber until the display is available (i.e. does not effect is being displayed).
+      * Animations are queued until their time to display.
+      */
+    void waitForFreeDisplay();
+
+    /**
+      * Blocks the current fiber until the current animation has finished.
+      * If the scheduler is not running, this call will essentially perform a spinning wait.
+      */
+    void fiberWait();
+
+    /**
+      * Enables or disables the display entirely, and releases the pins for other uses.
+      *
+      * @param enableDisplay true to enabled the display, or false to disable it.
+      */
+    void setEnable(bool enableDisplay);
+
+public:
+    // The mutable bitmap buffer being rendered to the LED matrix.
+    MicroBitImage image;
+
+    /**
+      * Constructor.
+      *
+      * Create a software representation the micro:bit's 5x5 LED matrix.
+      * The display is initially blank.
+      *
+      * @param id The id the display should use when sending events on the MessageBus. Defaults to MICROBIT_ID_DISPLAY.
+      *
+      * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
+      *            Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * @endcode
+      */
+    MicroBitDisplay(uint16_t id = MICROBIT_ID_DISPLAY, const MatrixMap &map = microbitMatrixMap);
+
+    /**
+      * Stops any currently running animation, and any that are waiting to be displayed.
+      */
+    void stopAnimation();
+
+    /**
+      * Frame update method, invoked periodically to strobe the display.
+      */
+    virtual void systemTick();
+
+    /**
+      * Prints the given character to the display, if it is not in use.
+      *
+      * @param c The character to display.
+      *
+      * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
+      *              or until the Displays next use.
+      *
+      * @return MICROBIT_OK, MICROBIT_BUSY is the screen is in use, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.printAsync('p');
+      * display.printAsync('p',100);
+      * @endcode
+      */
+    int printCharAsync(char c, int delay = 0);
+
+    /**
+      * Prints the given ManagedString to the display, one character at a time.
+      * Returns immediately, and executes the animation asynchronously.
+      *
+      * @param s The string to display.
+      *
+      * @param delay The time to delay between characters, in milliseconds. Must be > 0.
+      *              Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
+      *
+      * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.printAsync("abc123",400);
+      * @endcode
+      */
+    int printAsync(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
+
+    /**
+      * Prints the given image to the display, if the display is not in use.
+      * Returns immediately, and executes the animation asynchronously.
+      *
+      * @param i The image to display.
+      *
+      * @param x The horizontal position on the screen to display the image. Defaults to 0.
+      *
+      * @param y The vertical position on the screen to display the image. Defaults to 0.
+      *
+      * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
+      *
+      * @param delay The time to delay between characters, in milliseconds. Defaults to 0.
+      *
+      * @code
+      * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+      * display.print(i,400);
+      * @endcode
+      */
+    int printAsync(MicroBitImage i, int x = 0, int y = 0, int alpha = 0, int delay = 0);
+
+    /**
+      * Prints the given character to the display.
+      *
+      * @param c The character to display.
+      *
+      * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
+      *              or until the Displays next use.
+      *
+      * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.printAsync('p');
+      * display.printAsync('p',100);
+      * @endcode
+      */
+    int printChar(char c, int delay = 0);
+
+    /**
+      * Prints the given string to the display, one character at a time.
+      *
+      * Blocks the calling thread until all the text has been displayed.
+      *
+      * @param s The string to display.
+      *
+      * @param delay The time to delay between characters, in milliseconds. Defaults
+      *              to: MICROBIT_DEFAULT_PRINT_SPEED.
+      *
+      * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.print("abc123",400);
+      * @endcode
+      */
+    int print(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
+
+    /**
+      * Prints the given image to the display.
+      * Blocks the calling thread until all the image has been displayed.
+      *
+      * @param i The image to display.
+      *
+      * @param x The horizontal position on the screen to display the image. Defaults to 0.
+      *
+      * @param y The vertical position on the screen to display the image. Defaults to 0.
+      *
+      * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
+      *
+      * @param delay The time to display the image for, or zero to show the image forever. Defaults to 0.
+      *
+      * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+      * display.print(i,400);
+      * @endcode
+      */
+    int print(MicroBitImage i, int x = 0, int y = 0, int alpha = 0, int delay = 0);
+
+    /**
+      * Scrolls the given string to the display, from right to left.
+      * Returns immediately, and executes the animation asynchronously.
+      *
+      * @param s The string to display.
+      *
+      * @param delay The time to delay between characters, in milliseconds. Defaults
+      *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+      *
+      * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.scrollAsync("abc123",100);
+      * @endcode
+      */
+    int scrollAsync(ManagedString s, int delay = MICROBIT_DEFAULT_SCROLL_SPEED);
+
+    /**
+      * Scrolls the given image across the display, from right to left.
+      * Returns immediately, and executes the animation asynchronously.
+      *
+      * @param image The image to display.
+      *
+      * @param delay The time between updates, in milliseconds. Defaults
+      *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+      *
+      * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
+      *
+      * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+      * display.scrollAsync(i,100,1);
+      * @endcode
+      */
+    int scrollAsync(MicroBitImage image, int delay = MICROBIT_DEFAULT_SCROLL_SPEED, int stride = MICROBIT_DEFAULT_SCROLL_STRIDE);
+
+    /**
+      * Scrolls the given string across the display, from right to left.
+      * Blocks the calling thread until all text has been displayed.
+      *
+      * @param s The string to display.
+      *
+      * @param delay The time to delay between characters, in milliseconds. Defaults
+      *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+      *
+      * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * display.scroll("abc123",100);
+      * @endcode
+      */
+    int scroll(ManagedString s, int delay = MICROBIT_DEFAULT_SCROLL_SPEED);
+
+    /**
+      * Scrolls the given image across the display, from right to left.
+      * Blocks the calling thread until all the text has been displayed.
+      *
+      * @param image The image to display.
+      *
+      * @param delay The time between updates, in milliseconds. Defaults
+      *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+      *
+      * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
+      *
+      * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+      * display.scroll(i,100,1);
+      * @endcode
+      */
+    int scroll(MicroBitImage image, int delay = MICROBIT_DEFAULT_SCROLL_SPEED, int stride = MICROBIT_DEFAULT_SCROLL_STRIDE);
+
+    /**
+      * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
+      * Returns immediately.
+      *
+      * @param image The image to display.
+      *
+      * @param delay The time to delay between each update of the display, in milliseconds.
+      *
+      * @param stride The number of pixels to shift by in each update.
+      *
+      * @param startingPosition the starting position on the display for the animation
+      *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
+      *
+      * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
+      *
+      * @return MICROBIT_OK, MICROBIT_BUSY if the screen is in use, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const int heart_w = 10;
+      * const int heart_h = 5;
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
+      *
+      * MicroBitImage i(heart_w,heart_h,heart);
+      * display.animateAsync(i,100,5);
+      * @endcode
+      */
+    int animateAsync(MicroBitImage image, int delay, int stride, int startingPosition = MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS, int autoClear = MICROBIT_DISPLAY_DEFAULT_AUTOCLEAR);
+
+    /**
+      * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
+      * Blocks the calling thread until the animation is complete.
+      *
+      *
+      * @param delay The time to delay between each update of the display, in milliseconds.
+      *
+      * @param stride The number of pixels to shift by in each update.
+      *
+      * @param startingPosition the starting position on the display for the animation
+      *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
+      *
+      * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
+      *
+      * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const int heart_w = 10;
+      * const int heart_h = 5;
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
+      *
+      * MicroBitImage i(heart_w,heart_h,heart);
+      * display.animate(i,100,5);
+      * @endcode
+      */
+    int animate(MicroBitImage image, int delay, int stride, int startingPosition = MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS, int autoClear = MICROBIT_DISPLAY_DEFAULT_AUTOCLEAR);
+
+    /**
+      * Configures the brightness of the display.
+      *
+      * @param b The brightness to set the brightness to, in the range 0 - 255.
+      *
+      * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER
+      *
+      * @code
+      * display.setBrightness(255); //max brightness
+      * @endcode
+      */
+    int setBrightness(int b);
+
+    /**
+      * Configures the mode of the display.
+      *
+      * @param mode The mode to swap the display into. One of: DISPLAY_MODE_GREYSCALE,
+      *             DISPLAY_MODE_BLACK_AND_WHITE, DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
+      *
+      * @code
+      * display.setDisplayMode(DISPLAY_MODE_GREYSCALE); //per pixel brightness
+      * @endcode
+      */
+    void setDisplayMode(DisplayMode mode);
+
+    /**
+      * Retrieves the mode of the display.
+      *
+      * @return the current mode of the display
+      */
+    int getDisplayMode();
+
+    /**
+      * Fetches the current brightness of this display.
+      *
+      * @return the brightness of this display, in the range 0..255.
+      *
+      * @code
+      * display.getBrightness(); //the current brightness
+      * @endcode
+      */
+    int getBrightness();
+
+    /**
+      * Rotates the display to the given position.
+      *
+      * Axis aligned values only.
+      *
+      * @code
+      * display.rotateTo(MICROBIT_DISPLAY_ROTATION_180); //rotates 180 degrees from original orientation
+      * @endcode
+      */
+    void rotateTo(DisplayRotation position);
+
+    /**
+      * Enables the display, should only be called if the display is disabled.
+      *
+      * @code
+      * display.enable(); //Enables the display mechanics
+      * @endcode
+      *
+      * @note Only enables the display if the display is currently disabled.
+      */
+    void enable();
+
+    /**
+      * Disables the display, which releases control of the GPIO pins used by the display,
+      * which are exposed on the edge connector.
+      *
+      * @code
+      * display.disable(); //disables the display
+      * @endcode
+      *
+      * @note Only disables the display if the display is currently enabled.
+      */
+    void disable();
+
+    /**
+      * Clears the display of any remaining pixels.
+      *
+      * `display.image.clear()` can also be used!
+      *
+      * @code
+      * display.clear(); //clears the display
+      * @endcode
+      */
+    void clear();
+
+    /**
+      * Updates the font that will be used for display operations.
+	  *
+      * @param font the new font that will be used to render characters.
+      *
+      * @note DEPRECATED! Please use MicroBitFont::setSystemFont() instead.
+      */
+    void setFont(MicroBitFont font);
+
+    /**
+      * Retrieves the font object used for rendering characters on the display.
+	  *
+      * @note DEPRECATED! Please use MicroBitFont::getSystemFont() instead.
+      */
+    MicroBitFont getFont();
+
+    /**
+      * Captures the bitmap currently being rendered on the display.
+      *
+      * @return a MicroBitImage containing the captured data.
+      */
+    MicroBitImage screenShot();
+
+    /**
+      * Gives a representative figure of the light level in the current environment
+      * where are micro:bit is situated.
+      *
+      * Internally, it constructs an instance of a MicroBitLightSensor if not already configured
+      * and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
+      *
+      * This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
+      * that the display does not suffer from artifacts.
+      *
+      * @return an indicative light level in the range 0 - 255.
+      *
+      * @note this will return 0 on the first call to this method, a light reading
+      * will be available after the display has activated the light sensor for the
+      * first time.
+      */
+    int readLightLevel();
+
+    /**
+      * Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
+      */
+    ~MicroBitDisplay();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitI2C.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,107 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_I2C_H
+#define MICROBIT_I2C_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+#define MICROBIT_I2C_MAX_RETRIES 9
+
+/**
+  * Class definition for MicroBitI2C.
+  *
+  * Presents a wrapped mbed call to capture failed I2C operations caused by a known silicon bug in the nrf51822.
+  * Attempts to automatically reset and restart the I2C hardware if this case is detected.
+  *
+  * For reference see PAN56 in:
+  *
+  * https://www.nordicsemi.com/eng/nordic/Products/nRF51822/PAN-nRF51822/24634
+  *
+  * v2.0 through to v2.4
+  */
+class MicroBitI2C : public I2C
+{
+    uint8_t retries;
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create an instance of MicroBitI2C for I2C communication.
+      *
+      * @param sda the Pin to be used for SDA
+      *
+      * @param scl the Pin to be used for SCL
+      *
+      * @code
+      * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+      * @endcode
+      *
+      * @note This class presents a wrapped mbed call to capture failed I2C operations caused by a known silicon bug in the nrf51822.
+      * Attempts to automatically reset and restart the I2C hardware if this case is detected.
+      * \par
+      * For reference see PAN56 in:
+      * \par
+      * https://www.nordicsemi.com/eng/nordic/Products/nRF51822/PAN-nRF51822/24634
+      * \par
+      * v2.0 through to v2.4
+      */
+    MicroBitI2C(PinName sda, PinName scl);
+
+    /**
+      * Performs a complete read transaction. The bottom bit of the address is forced to 1 to indicate a read.
+      *
+      * @param address 8-bit I2C slave address [ addr | 1 ]
+      *
+      * @param data A pointer to a byte buffer used for storing retrieved data.
+      *
+      * @param length Number of bytes to read.
+      *
+      * @param repeated if true, stop is not sent at the end. Defaults to false.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved read failure is detected.
+      */
+    int read(int address, char *data, int length, bool repeated = false);
+
+    /**
+      * Performs a complete write transaction. The bottom bit of the address is forced to 0 to indicate a write.
+      *
+      * @param address 8-bit I2C slave address [ addr | 0 ]
+      *
+      * @param data A pointer to a byte buffer containing the data to write.
+      *
+      * @param length Number of bytes to write
+      *
+      * @param repeated if true, stop is not sent at the end. Defaults to false.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved write failure is detected.
+      */
+    int write(int address, const char *data, int length, bool repeated = false);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitIO.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,81 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_IO_H
+#define MICROBIT_IO_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitPin.h"
+
+/**
+  * Class definition for MicroBit IO.
+  *
+  * Represents a collection of all I/O pins on the edge connector.
+  */
+class MicroBitIO
+{
+    public:
+
+	MicroBitPin			 pin[0];
+	MicroBitPin          P0;
+    MicroBitPin          P1;
+    MicroBitPin          P2;
+    MicroBitPin          P3;
+    MicroBitPin          P4;
+    MicroBitPin          P5;
+    MicroBitPin          P6;
+    MicroBitPin          P7;
+    MicroBitPin          P8;
+    MicroBitPin          P9;
+    MicroBitPin          P10;
+    MicroBitPin          P11;
+    MicroBitPin          P12;
+    MicroBitPin          P13;
+    MicroBitPin          P14;
+    MicroBitPin          P15;
+    MicroBitPin          P16;
+    MicroBitPin          P19;
+    MicroBitPin          P20;
+
+    /**
+      * Constructor.
+      *
+      * Create a representation of all given I/O pins on the edge connector
+      *
+      * Accepts a sequence of unique ID's used to distinguish events raised
+      * by MicroBitPin instances on the default EventModel.
+      */
+    MicroBitIO(int ID_P0, int ID_P1, int ID_P2,
+               int ID_P3, int ID_P4, int ID_P5,
+               int ID_P6, int ID_P7, int ID_P8,
+               int ID_P9, int ID_P10,int ID_P11,
+               int ID_P12,int ID_P13,int ID_P14,
+               int ID_P15,int ID_P16,int ID_P19,
+               int ID_P20);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitLightSensor.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,137 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_LIGHT_SENSOR_H
+#define MICROBIT_LIGHT_SENSOR_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "EventModel.h"
+#include "MicroBitMatrixMaps.h"
+
+#define MICROBIT_LIGHT_SENSOR_CHAN_NUM      3
+#define MICROBIT_LIGHT_SENSOR_AN_SET_TIME   4000
+#define MICROBIT_LIGHT_SENSOR_TICK_PERIOD   5
+
+#define MICROBIT_LIGHT_SENSOR_MAX_VALUE     338
+#define MICROBIT_LIGHT_SENSOR_MIN_VALUE     75
+
+/**
+  * Class definition for MicroBitLightSensor.
+  *
+  * This is an object that interleaves light sensing with MicroBitDisplay.
+  */
+class MicroBitLightSensor
+{
+
+    //contains the results from each section of the display
+    int results[MICROBIT_LIGHT_SENSOR_CHAN_NUM];
+
+    //holds the current channel (also used to index the results array)
+    uint8_t chan;
+
+    //a Timeout which triggers our analogReady() call
+    Timeout analogTrigger;
+
+    //a pointer the currently sensed pin, represented as an AnalogIn
+    AnalogIn* sensePin;
+
+    const MatrixMap &matrixMap;
+
+    /**
+      * After the startSensing method has been called, this method will be called
+      * MICROBIT_LIGHT_SENSOR_AN_SET_TIME after.
+      *
+      * It will then read from the currently selected channel using the AnalogIn
+      * that was configured in the startSensing method.
+      */
+    void analogReady();
+
+    /**
+      * Forcibly disables the AnalogIn, otherwise it will remain in possession
+      * of the GPIO channel it is using, meaning that the display will not be
+      * able to use a channel (COL).
+      *
+      * This is required as per PAN 3, details of which can be found here:
+      *
+      * https://www.nordicsemi.com/eng/nordic/download_resource/24634/5/88440387
+      */
+    void analogDisable();
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create a representation of the light sensor.
+      *
+      * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
+      *            Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
+      */
+    MicroBitLightSensor(const MatrixMap &map);
+
+    /**
+      * This method returns a summed average of the three sections of the display.
+      *
+      * A section is defined as:
+      *  ___________________
+      * | 1 |   | 2 |   | 3 |
+      * |___|___|___|___|___|
+      * |   |   |   |   |   |
+      * |___|___|___|___|___|
+      * | 2 |   | 3 |   | 1 |
+      * |___|___|___|___|___|
+      * |   |   |   |   |   |
+      * |___|___|___|___|___|
+      * | 3 |   | 1 |   | 2 |
+      * |___|___|___|___|___|
+      *
+      * Where each number represents a different section on the 5 x 5 matrix display.
+      *
+      * @return returns a value in the range 0 - 255 where 0 is dark, and 255
+      * is very bright
+      */
+    int read();
+
+    /**
+      * The method that is invoked by sending MICROBIT_DISPLAY_EVT_LIGHT_SENSE
+      * using the id MICROBIT_ID_DISPLAY.
+      *
+      * @note this can be manually driven by calling this member function, with
+      *       a MicroBitEvent using the CREATE_ONLY option of the MicroBitEvent
+      *       constructor.
+      */
+    void startSensing(MicroBitEvent);
+
+    /**
+      * A destructor for MicroBitLightSensor.
+      *
+      * The destructor removes the listener, used by MicroBitLightSensor from the default EventModel.
+      */
+    ~MicroBitLightSensor();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitMatrixMaps.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,160 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Definition of the LED Matrix maps supported.
+  * Each map represents the layou of a different device.
+  *
+  * Ensure only one of these is selected.
+  */
+
+#ifndef MICROBIT_MATRIX_MAPS_H
+#define MICROBIT_MATRIX_MAPS_H
+
+#include "MicroBitConfig.h"
+#include "mbed.h"
+
+#define NO_CONN 0
+
+/**
+  * Provides the mapping from Matrix ROW/COL to a linear X/Y buffer.
+  * It's arranged such that matrixMap[col, row] provides the [x,y] screen co-ord.
+  */
+
+struct MatrixPoint
+{
+    uint8_t x;
+    uint8_t y;
+};
+
+/**
+  * This struct presumes rows and columns are arranged contiguously...
+  */
+struct MatrixMap
+{
+    int         width;                      // The physical width of the LED matrix, in pixels.
+    int         height;                     // The physical height of the LED matrix, in pixels.
+    int         rows;                       // The number of drive pins connected to LEDs.
+    int         columns;                    // The number of sink pins connected to the LEDs.
+
+    PinName     rowStart;                   // ID of the first drive pin.
+    PinName     columnStart;                // ID of the first sink pink.
+
+    const MatrixPoint *map;                 // Table mapping logical LED positions to physical positions.
+};
+
+/*
+ * Dimensions for well known micro:bit LED configurations
+ */
+#define MICROBIT_DISPLAY_WIDTH                  5
+#define MICROBIT_DISPLAY_HEIGHT                 5
+#define MICROBIT_DISPLAY_ROW1                   p13
+#define MICROBIT_DISPLAY_COL1                   p4
+
+
+#if MICROBIT_DISPLAY_TYPE == MICROBUG_REFERENCE_DEVICE
+
+#define MICROBIT_DISPLAY_COLUMN_COUNT           5
+#define MICROBIT_DISPLAY_ROW_COUNT              5
+
+    const MatrixPoint microbitDisplayMap[MICROBIT_DISPLAY_ROW_COUNT * MICROBIT_DISPLAY_COLUMN_COUNT] =
+    {
+        {0,0},{0,1},{0,2},{0,3},{0,4},
+        {1,0},{1,1},{1,2},{1,3},{1,4},
+        {2,0},{2,1},{2,2},{2,3},{2,4},
+        {3,0},{3,1},{3,2},{3,3},{3,4},
+        {4,0},{4,1},{4,2},{4,3},{4,4}
+    };
+
+#endif
+
+#if MICROBIT_DISPLAY_TYPE == MICROBIT_3X9
+
+#define MICROBIT_DISPLAY_COLUMN_COUNT       9
+#define MICROBIT_DISPLAY_ROW_COUNT          3
+
+    const MatrixPoint microbitDisplayMap[MICROBIT_DISPLAY_ROW_COUNT * MICROBIT_DISPLAY_COLUMN_COUNT] =
+    {
+        {0,4},{0,3},{1,1},
+        {1,4},{4,2},{0,1},
+        {2,4},{3,2},{4,0},
+        {3,4},{2,2},{3,0},
+        {4,4},{1,2},{2,0},
+        {4,3},{0,2},{1,0},
+        {3,3},{4,1},{0,0},
+        {2,3},{3,1},{NO_CONN,NO_CONN},
+        {1,3},{2,1},{NO_CONN,NO_CONN}
+    };
+
+#endif
+
+#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB1
+
+#define MICROBIT_DISPLAY_COLUMN_COUNT       3
+#define MICROBIT_DISPLAY_ROW_COUNT          9
+
+    const MatrixPoint microbitDisplayMap[MICROBIT_DISPLAY_ROW_COUNT * MICROBIT_DISPLAY_COLUMN_COUNT] =
+    {
+        {0,4},{1,4},{2,4},{3,4},{4,4},{4,3},{3,3},{2,3},{1,3},
+        {0,3},{4,2},{3,2},{2,2},{1,2},{0,2},{4,1},{3,1},{2,1},
+        {1,1},{0,1},{4,0},{3,0},{2,0},{1,0},{0,0},{NO_CONN,NO_CONN},{NO_CONN,NO_CONN}
+    };
+
+#endif
+
+#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB2
+
+#define MICROBIT_DISPLAY_COLUMN_COUNT       9
+#define MICROBIT_DISPLAY_ROW_COUNT          3
+
+    const MatrixPoint microbitDisplayMap[MICROBIT_DISPLAY_ROW_COUNT * MICROBIT_DISPLAY_COLUMN_COUNT] =
+    {
+        {0,0},{4,2},{2,4},
+        {2,0},{0,2},{4,4},
+        {4,0},{2,2},{0,4},
+        {4,3},{1,0},{0,1},
+        {3,3},{3,0},{1,1},
+        {2,3},{3,4},{2,1},
+        {1,3},{1,4},{3,1},
+        {0,3},{NO_CONN,NO_CONN},{4,1},
+        {1,2},{NO_CONN,NO_CONN},{3,2}
+    };
+
+#endif
+
+//ROW1 and COL1 are defined in mbed classic:
+//https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/PinNames.h
+const MatrixMap microbitMatrixMap =
+{
+    MICROBIT_DISPLAY_WIDTH,
+    MICROBIT_DISPLAY_HEIGHT,
+    MICROBIT_DISPLAY_ROW_COUNT,
+    MICROBIT_DISPLAY_COLUMN_COUNT,
+    MICROBIT_DISPLAY_ROW1,
+    MICROBIT_DISPLAY_COL1,
+    microbitDisplayMap
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitMessageBus.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,181 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_MESSAGE_BUS_H
+#define MICROBIT_MESSAGE_BUS_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitEvent.h"
+#include "MicroBitListener.h"
+#include "EventModel.h"
+
+/**
+  * Class definition for the MicroBitMessageBus.
+  *
+  * The MicroBitMessageBus is the common mechanism to deliver asynchronous events on the
+  * MicroBit platform. It serves a number of purposes:
+  *
+  * 1) It provides an eventing abstraction that is independent of the underlying substrate.
+  *
+  * 2) It provides a mechanism to decouple user code from trusted system code
+  *    i.e. the basis of a message passing nano kernel.
+  *
+  * 3) It allows a common high level eventing abstraction across a range of hardware types.e.g. buttons, BLE...
+  *
+  * 4) It provides a mechanim for extensibility - new devices added via I/O pins can have OO based
+  *    drivers and communicate via the message bus with minima impact on user level languages.
+  *
+  * 5) It allows for the possiblility of event / data aggregation, which in turn can save energy.
+  *
+  * It has the following design principles:
+  *
+  * 1) Maintain a low RAM footprint where possible
+  *
+  * 2) Make few assumptions about the underlying platform, but allow optimizations where possible.
+  */
+class MicroBitMessageBus : public EventModel, public MicroBitComponent
+{
+    public:
+
+	/**
+	  * Default constructor.
+      *
+      * Adds itself as a fiber component, and also configures itself to be the
+      * default EventModel if defaultEventBus is NULL.
+	  */
+    MicroBitMessageBus();
+
+	/**
+	  * Queues the given event to be sent to all registered recipients.
+	  *
+	  * @param evt The event to send.
+      *
+      * @code
+      * MicroBitMessageBus bus;
+      *
+      * // Creates and sends the MicroBitEvent using bus.
+	  * MicrobitEvent evt(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+      *
+      * // Creates the MicrobitEvent, but delays the sending of that event.
+      * MicrobitEvent evt1(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, CREATE_ONLY);
+      *
+      * bus.send(evt1);
+      *
+      * // This has the same effect!
+      * evt1.fire()
+      * @endcode
+	  */
+	virtual int send(MicroBitEvent evt);
+
+	/**
+      * Internal function, used to deliver the given event to all relevant recipients.
+      * Normally, this is called once an event has been removed from the event queue.
+	  *
+	  * @param evt The event to send.
+      *
+      * @param urgent The type of listeners to process (optional). If set to true, only listeners defined as urgent and non-blocking will be processed
+      *               otherwise, all other (standard) listeners will be processed. Defaults to false.
+      *
+      * @return 1 if all matching listeners were processed, 0 if further processing is required.
+      *
+      * @note It is recommended that all external code uses the send() function instead of this function,
+      *       or the constructors provided by MicrobitEvent.
+      */
+	int process(MicroBitEvent &evt, bool urgent = false);
+
+    /**
+      * Returns the microBitListener with the given position in our list.
+      *
+      * @param n The position in the list to return.
+      *
+      * @return the MicroBitListener at postion n in the list, or NULL if the position is invalid.
+      */
+    virtual MicroBitListener *elementAt(int n);
+
+    /**
+      * Destructor for MicroBitMessageBus, where we deregister this instance from the array of fiber components.
+      */
+    ~MicroBitMessageBus();
+
+    /**
+      * Add the given MicroBitListener to the list of event handlers, unconditionally.
+      *
+      * @param listener The MicroBitListener to add.
+      *
+      * @return MICROBIT_OK if the listener is valid, MICROBIT_INVALID_PARAMETER otherwise.
+      */
+    virtual int add(MicroBitListener *newListener);
+
+    /**
+      * Remove the given MicroBitListener from the list of event handlers.
+      *
+      * @param listener The MicroBitListener to remove.
+      *
+      * @return MICROBIT_OK if the listener is valid, MICROBIT_INVALID_PARAMETER otherwise.
+      */
+    virtual int remove(MicroBitListener *newListener);
+
+	private:
+
+    MicroBitListener            *listeners;		    // Chain of active listeners.
+    MicroBitEventQueueItem      *evt_queue_head;    // Head of queued events to be processed.
+    MicroBitEventQueueItem      *evt_queue_tail;    // Tail of queued events to be processed.
+    uint16_t                    nonce_val;          // The last nonce issued.
+    uint16_t                    queueLength;        // The number of events currently waiting to be processed.
+
+    /**
+      * Cleanup any MicroBitListeners marked for deletion from the list.
+      *
+      * @return The number of listeners removed from the list.
+      */
+    int deleteMarkedListeners();
+
+    /**
+      * Queue the given event for processing at a later time.
+      * Add the given event at the tail of our queue.
+      *
+      * @param The event to queue.
+      */
+    void queueEvent(MicroBitEvent &evt);
+
+    /**
+      * Extract the next event from the front of the event queue (if present).
+      *
+      * @return a pointer to the MicroBitEventQueueItem that is at the head of the list.
+      */
+    MicroBitEventQueueItem* dequeueEvent();
+
+    /**
+      * Periodic callback from MicroBit.
+      *
+      * Process at least one event from the event queue, if it is not empty.
+      * We then continue processing events until something appears on the runqueue.
+      */
+    virtual void idleTick();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitMultiButton.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,176 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_MULTI_BUTTON_H
+#define MICROBIT_MULTI_BUTTON_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitButton.h"
+#include "EventModel.h"
+
+#define MICROBIT_MULTI_BUTTON_STATE_1               0x01
+#define MICROBIT_MULTI_BUTTON_STATE_2               0x02
+#define MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1      0x04
+#define MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2      0x08
+#define MICROBIT_MULTI_BUTTON_SUPRESSED_1           0X10
+#define MICROBIT_MULTI_BUTTON_SUPRESSED_2           0x20
+#define MICROBIT_MULTI_BUTTON_ATTACHED              0x40
+
+/**
+  * Class definition for MicroBitMultiButton.
+  *
+  * Represents a virtual button, capable of reacting to simultaneous presses of two
+  * other buttons.
+  */
+class MicroBitMultiButton : public MicroBitComponent
+{
+    uint16_t    button1;        // ID of the first button we're monitoring
+    uint16_t    button2;        // ID of the second button we're monitoring
+    MicroBitButtonEventConfiguration eventConfiguration;    // Do we want to generate high level event (clicks), or defer this to another service.
+
+    /**
+      * Retrieves the button id for the alternate button id given.
+      *
+      * @param b the id of the button whose state we would like to retrieve.
+      *
+      * @return the other sub button id.
+      */
+    uint16_t    otherSubButton(uint16_t b);
+
+    /**
+      * Determines if the given button id is marked as pressed.
+      *
+      * @param button the id of the button whose state we would like to retrieve.
+      *
+      * @return 1 if pressed, 0 if not.
+      */
+    int         isSubButtonPressed(uint16_t button);
+
+    /**
+      * Determines if the given button id is marked as held.
+      *
+      * @param button the id of the button whose state we would like to retrieve.
+      *
+      * @return 1 if held, 0 if not.
+      */
+    int         isSubButtonHeld(uint16_t button);
+
+    /**
+      * Determines if the given button id is marked as supressed.
+      *
+      * @param button the id of the button whose state we would like to retrieve.
+      *
+      * @return 1 if supressed, 0 if not.
+      */
+    int         isSubButtonSupressed(uint16_t button);
+
+    /**
+      * Configures the button pressed state for the given button id.
+      *
+      * @param button the id of the button whose state requires updating.
+      *
+      * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+      */
+    void        setButtonState(uint16_t button, int value);
+
+    /**
+      * Configures the button held state for the given button id.
+      *
+      * @param button the id of the button whose state requires updating.
+      *
+      * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+      */
+    void        setHoldState(uint16_t button, int value);
+
+    /**
+      * Configures the button suppressed state for the given button id.
+      *
+      * @param button the id of the button whose state requires updating.
+      *
+      * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+      */
+    void        setSupressedState(uint16_t button, int value);
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create a representation of a virtual button, that generates events based upon the combination
+      * of two given buttons.
+      *
+      * @param button1 the unique ID of the first button to watch.
+      *
+      * @param button2 the unique ID of the second button to watch.
+      *
+      * @param id the unique EventModel id of this MicroBitMultiButton instance.
+      *
+      * @code
+      * multiButton(MICROBIT_ID_BUTTON_A, MICROBIT_ID_BUTTON_B, MICROBIT_ID_BUTTON_AB);
+      * @endcode
+      */
+    MicroBitMultiButton(uint16_t button1, uint16_t button2, uint16_t id);
+
+    /**
+      * Tests if this MicroBitMultiButton instance is virtually pressed.
+      *
+      * @return 1 if both physical buttons are pressed simultaneously.
+      *
+      * @code
+      * if(buttonAB.isPressed())
+      *     display.scroll("Pressed!");
+      * @endcode
+      */
+    int isPressed();
+
+    /**
+      * Changes the event configuration of this button to the given MicroBitButtonEventConfiguration.
+      * All subsequent events generated by this button will then be informed by this configuration.
+      *
+      * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
+      *
+      * @code
+      * // Configure a button to generate all possible events.
+      * buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
+      *
+      * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
+      * buttonAB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+      * @endcode
+      */
+    void setEventConfiguration(MicroBitButtonEventConfiguration config);
+
+    private:
+
+    /**
+      * A member function that is invoked when any event is detected from the two
+      * button IDs this MicrobitMultiButton instance was constructed with.
+      *
+      * @param evt the event received from the default EventModel.
+      */
+    void onButtonEvent(MicroBitEvent evt);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitPin.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,399 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_PIN_H
+#define MICROBIT_PIN_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+                                                        // Status Field flags...
+#define IO_STATUS_DIGITAL_IN                0x01        // Pin is configured as a digital input, with no pull up.
+#define IO_STATUS_DIGITAL_OUT               0x02        // Pin is configured as a digital output
+#define IO_STATUS_ANALOG_IN                 0x04        // Pin is Analog in
+#define IO_STATUS_ANALOG_OUT                0x08        // Pin is Analog out
+#define IO_STATUS_TOUCH_IN                  0x10        // Pin is a makey-makey style touch sensor
+#define IO_STATUS_EVENT_ON_EDGE             0x20        // Pin will generate events on pin change
+#define IO_STATUS_EVENT_PULSE_ON_EDGE       0x40        // Pin will generate events on pin change
+
+//#defines for each edge connector pin
+#define MICROBIT_PIN_P0                     P0_3        //P0 is the left most pad (ANALOG/DIGITAL) used to be P0_3 on green board
+#define MICROBIT_PIN_P1                     P0_2        //P1 is the middle pad (ANALOG/DIGITAL)
+#define MICROBIT_PIN_P2                     P0_1        //P2 is the right most pad (ANALOG/DIGITAL) used to be P0_1 on green board
+#define MICROBIT_PIN_P3                     P0_4        //COL1 (ANALOG/DIGITAL)
+#define MICROBIT_PIN_P4                     P0_5        //COL2 (ANALOG/DIGITAL)
+#define MICROBIT_PIN_P5                     P0_17       //BTN_A
+#define MICROBIT_PIN_P6                     P0_12       //COL9
+#define MICROBIT_PIN_P7                     P0_11       //COL8
+#define MICROBIT_PIN_P8                     P0_18       //PIN 18
+#define MICROBIT_PIN_P9                     P0_10       //COL7
+#define MICROBIT_PIN_P10                    P0_6        //COL3 (ANALOG/DIGITAL)
+#define MICROBIT_PIN_P11                    P0_26       //BTN_B
+#define MICROBIT_PIN_P12                    P0_20       //PIN 20
+#define MICROBIT_PIN_P13                    P0_23       //SCK
+#define MICROBIT_PIN_P14                    P0_22       //MISO
+#define MICROBIT_PIN_P15                    P0_21       //MOSI
+#define MICROBIT_PIN_P16                    P0_16       //PIN 16
+#define MICROBIT_PIN_P19                    P0_0        //SCL
+#define MICROBIT_PIN_P20                    P0_30       //SDA
+
+#define MICROBIT_PIN_MAX_OUTPUT             1023
+
+#define MICROBIT_PIN_MAX_SERVO_RANGE        180
+#define MICROBIT_PIN_DEFAULT_SERVO_RANGE    2000
+#define MICROBIT_PIN_DEFAULT_SERVO_CENTER   1500
+
+#define MICROBIT_PIN_EVENT_NONE             0
+#define MICROBIT_PIN_EVENT_ON_EDGE          1
+#define MICROBIT_PIN_EVENT_ON_PULSE         2
+#define MICROBIT_PIN_EVENT_ON_TOUCH         3
+
+#define MICROBIT_PIN_EVT_RISE               2
+#define MICROBIT_PIN_EVT_FALL               3
+#define MICROBIT_PIN_EVT_PULSE_HI           4
+#define MICROBIT_PIN_EVT_PULSE_LO           5
+
+/**
+  * Pin capabilities enum.
+  * Used to determine the capabilities of each Pin as some can only be digital, or can be both digital and analogue.
+  */
+enum PinCapability{
+    PIN_CAPABILITY_DIGITAL = 0x01,
+    PIN_CAPABILITY_ANALOG = 0x02,
+    PIN_CAPABILITY_AD = PIN_CAPABILITY_DIGITAL | PIN_CAPABILITY_ANALOG,
+    PIN_CAPABILITY_ALL = PIN_CAPABILITY_DIGITAL | PIN_CAPABILITY_ANALOG
+};
+
+/**
+  * Class definition for MicroBitPin.
+  *
+  * Commonly represents an I/O pin on the edge connector.
+  */
+class MicroBitPin : public MicroBitComponent
+{
+    // The mbed object looking after this pin at any point in time (untyped due to dynamic behaviour).
+    void *pin;
+    PinCapability capability;
+    uint8_t pullMode;
+
+    /**
+      * Disconnect any attached mBed IO from this pin.
+      *
+      * Used only when pin changes mode (i.e. Input/Output/Analog/Digital)
+      */
+    void disconnect();
+
+    /**
+      * Performs a check to ensure that the current Pin is in control of a
+      * DynamicPwm instance, and if it's not, allocates a new DynamicPwm instance.
+      */
+    int obtainAnalogChannel();
+
+    /**
+      * Interrupt handler for when an rise interrupt is triggered.
+      */
+    void onRise();
+
+    /**
+      * Interrupt handler for when an fall interrupt is triggered.
+      */
+    void onFall();
+
+    /**
+      * This member function manages the calculation of the timestamp of a pulse detected
+      * on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes.
+      *
+      * @param eventValue the event value to distribute onto the message bus.
+      */
+    void pulseWidthEvent(int eventValue);
+
+    /**
+      * This member function will construct an TimedInterruptIn instance, and configure
+      * interrupts for rise and fall.
+      *
+      * @param eventType the specific mode used in interrupt context to determine how an
+      *                  edge/rise is processed.
+      *
+      * @return MICROBIT_OK on success
+      */
+    int enableRiseFallEvents(int eventType);
+
+    /**
+      * If this pin is in a mode where the pin is generating events, it will destruct
+      * the current instance attached to this MicroBitPin instance.
+      *
+      * @return MICROBIT_OK on success.
+      */
+    int disableEvents();
+
+    public:
+
+    // mbed PinName of this pin.
+    PinName name;
+
+    /**
+      * Constructor.
+      * Create a MicroBitPin instance, generally used to represent a pin on the edge connector.
+      *
+      * @param id the unique EventModel id of this component.
+      *
+      * @param name the mbed PinName for this MicroBitPin instance.
+      *
+      * @param capability the capabilities this MicroBitPin instance should have.
+      *                   (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
+      * @endcode
+      */
+    MicroBitPin(int id, PinName name, PinCapability capability);
+
+    /**
+      * Configures this IO pin as a digital output (if necessary) and sets the pin to 'value'.
+      *
+      * @param value 0 (LO) or 1 (HI)
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have digital capability.
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.setDigitalValue(1); // P0 is now HI
+      * @endcode
+      */
+    int setDigitalValue(int value);
+
+    /**
+      * Configures this IO pin as a digital input (if necessary) and tests its current value.
+      *
+      *
+      * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have digital capability.
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.getDigitalValue(); // P0 is either 0 or 1;
+      * @endcode
+      */
+    int getDigitalValue();
+
+    /**
+      * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value.
+      *
+      * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+      *
+      * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have digital capability.
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.getDigitalValue(PullUp); // P0 is either 0 or 1;
+      * @endcode
+      */
+    int getDigitalValue(PinMode pull);
+
+    /**
+      * Configures this IO pin as an analog/pwm output, and change the output value to the given level.
+      *
+      * @param value the level to set on the output pin, in the range 0 - 1024
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have analog capability.
+      */
+    int setAnalogValue(int value);
+
+    /**
+      * Configures this IO pin as an analog/pwm output (if necessary) and configures the period to be 20ms,
+      * with a duty cycle between 500 us and 2500 us.
+      *
+      * A value of 180 sets the duty cycle to be 2500us, and a value of 0 sets the duty cycle to be 500us by default.
+      *
+      * This range can be modified to fine tune, and also tolerate different servos.
+      *
+      * @param value the level to set on the output pin, in the range 0 - 180.
+      *
+      * @param range which gives the span of possible values the i.e. the lower and upper bounds (center +/- range/2). Defaults to MICROBIT_PIN_DEFAULT_SERVO_RANGE.
+      *
+      * @param center the center point from which to calculate the lower and upper bounds. Defaults to MICROBIT_PIN_DEFAULT_SERVO_CENTER
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have analog capability.
+      */
+    int setServoValue(int value, int range = MICROBIT_PIN_DEFAULT_SERVO_RANGE, int center = MICROBIT_PIN_DEFAULT_SERVO_CENTER);
+
+    /**
+      * Configures this IO pin as an analogue input (if necessary), and samples the Pin for its analog value.
+      *
+      * @return the current analogue level on the pin, in the range 0 - 1024, or
+      *         MICROBIT_NOT_SUPPORTED if the given pin does not have analog capability.
+      *
+      * @code
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.getAnalogValue(); // P0 is a value in the range of 0 - 1024
+      * @endcode
+      */
+    int getAnalogValue();
+
+    /**
+      * Determines if this IO pin is currently configured as an input.
+      *
+      * @return 1 if pin is an analog or digital input, 0 otherwise.
+      */
+    int isInput();
+
+    /**
+      * Determines if this IO pin is currently configured as an output.
+      *
+      * @return 1 if pin is an analog or digital output, 0 otherwise.
+      */
+    int isOutput();
+
+    /**
+      * Determines if this IO pin is currently configured for digital use.
+      *
+      * @return 1 if pin is digital, 0 otherwise.
+      */
+    int isDigital();
+
+    /**
+      * Determines if this IO pin is currently configured for analog use.
+      *
+      * @return 1 if pin is analog, 0 otherwise.
+      */
+    int isAnalog();
+
+    /**
+      * Configures this IO pin as a "makey makey" style touch sensor (if necessary)
+      * and tests its current debounced state.
+      *
+      * Users can also subscribe to MicroBitButton events generated from this pin.
+      *
+      * @return 1 if pin is touched, 0 if not, or MICROBIT_NOT_SUPPORTED if this pin does not support touch capability.
+      *
+      * @code
+      * MicroBitMessageBus bus;
+      *
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
+      * if(P0.isTouched())
+      * {
+      *     //do something!
+      * }
+      *
+      * // subscribe to events generated by this pin!
+      * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_BUTTON_EVT_CLICK, someFunction);
+      * @endcode
+      */
+    int isTouched();
+
+    /**
+      * Configures this IO pin as an analog/pwm output if it isn't already, configures the period to be 20ms,
+      * and sets the pulse width, based on the value it is given.
+      *
+      * @param pulseWidth the desired pulse width in microseconds.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+      *         if the given pin does not have analog capability.
+      */
+    int setServoPulseUs(int pulseWidth);
+
+    /**
+      * Configures the PWM period of the analog output to the given value.
+      *
+      * @param period The new period for the analog output in milliseconds.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
+      *         given pin is not configured as an analog output.
+      */
+    int setAnalogPeriod(int period);
+
+    /**
+      * Configures the PWM period of the analog output to the given value.
+      *
+      * @param period The new period for the analog output in microseconds.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
+      *         given pin is not configured as an analog output.
+      */
+    int setAnalogPeriodUs(int period);
+
+    /**
+      * Obtains the PWM period of the analog output in microseconds.
+      *
+      * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
+      *         given pin is not configured as an analog output.
+      */
+    int getAnalogPeriodUs();
+
+    /**
+      * Obtains the PWM period of the analog output in milliseconds.
+      *
+      * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
+      *         given pin is not configured as an analog output.
+      */
+    int getAnalogPeriod();
+
+    /**
+      * Configures the pull of this pin.
+      *
+      * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+      *
+      * @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other
+      *         than a digital input, otherwise MICROBIT_OK.
+      */
+    int setPull(PinMode pull);
+
+    /**
+      * Configures the events generated by this MicroBitPin instance.
+      *
+      * MICROBIT_PIN_EVENT_ON_EDGE - Configures this pin to a digital input, and generates events whenever a rise/fall is detected on this pin. (MICROBIT_PIN_EVT_RISE, MICROBIT_PIN_EVT_FALL)
+      * MICROBIT_PIN_EVENT_ON_PULSE - Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either HI or LO. (MICROBIT_PIN_EVT_PULSE_HI, MICROBIT_PIN_EVT_PULSE_LO)
+      * MICROBIT_PIN_EVENT_ON_TOUCH - Configures this pin as a makey makey style touch sensor, in the form of a MicroBitButton. Normal button events will be generated using the ID of this pin.
+      * MICROBIT_PIN_EVENT_NONE - Disables events for this pin.
+      *
+      * @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE
+      *
+      * @code
+      * MicroBitMessageBus bus;
+      *
+      * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+      * P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE);
+      *
+      * void onPulse(MicroBitEvent evt)
+      * {
+      *     int duration = evt.timestamp;
+      * }
+      *
+      * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE)
+      * @endcode
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match
+      *
+      * @note In the MICROBIT_PIN_EVENT_ON_PULSE mode, the smallest pulse that was reliably detected was 85us, around 5khz. If more precision is required,
+      *       please use the InterruptIn class supplied by ARM mbed.
+      */
+    int eventOn(int eventType);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitRadio.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,227 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_RADIO_H
+#define MICROBIT_RADIO_H
+
+class MicroBitRadio;
+struct FrameBuffer;
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "PacketBuffer.h"
+#include "MicroBitRadioDatagram.h"
+#include "MicroBitRadioEvent.h"
+
+/**
+ * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+ *
+ * The nrf51822 RADIO module supports a number of proprietary modes of operation in addition to the typical BLE usage.
+ * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits.
+ *
+ * TODO: The protocols implemented here do not currently perform any significant form of energy management,
+ * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol
+ * should look to address this through energy efficient broadcast techniques / sleep scheduling. In particular, the GLOSSY
+ * approach to efficienct rebroadcast and network synchronisation would likely provide an effective future step.
+ *
+ * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to
+ * the master/slave arachitecture of BLE.
+ *
+ * TODO: This implementation only operates whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow
+ * BLE to cohabit with other protocols. Future work to allow this colocation would be benefical, and would also allow for the
+ * creation of wireless BLE bridges.
+ *
+ * NOTE: This API does not contain any form of encryption, authentication or authorization. It's purpose is solely for use as a
+ * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+ * For serious applications, BLE should be considered a substantially more secure alternative.
+ */
+
+// Status Flags
+#define MICROBIT_RADIO_STATUS_INITIALISED       0x0001
+
+// Default configuration values
+#define MICROBIT_RADIO_BASE_ADDRESS             0x75626974
+#define MICROBIT_RADIO_DEFAULT_GROUP            0
+#define MICROBIT_RADIO_DEFAULT_TX_POWER         6
+#define MICROBIT_RADIO_DEFAULT_FREQUENCY        7
+#define MICROBIT_RADIO_MAX_PACKET_SIZE          32
+#define MICROBIT_RADIO_HEADER_SIZE              4
+#define MICROBIT_RADIO_MAXIMUM_RX_BUFFERS       4
+
+// Known Protocol Numbers
+#define MICROBIT_RADIO_PROTOCOL_DATAGRAM        1       // A simple, single frame datagram. a little like UDP but with smaller packets. :-)
+#define MICROBIT_RADIO_PROTOCOL_EVENTBUS        2       // Transparent propogation of events from one micro:bit to another.
+
+// Events
+#define MICROBIT_RADIO_EVT_DATAGRAM             1       // Event to signal that a new datagram has been received.
+
+
+struct FrameBuffer
+{
+    uint8_t         length;                             // The length of the remaining bytes in the packet. includes protocol/version/group fields, excluding the length field itself.
+    uint8_t         version;                            // Protocol version code.
+    uint8_t         group;                              // ID of the group to which this packet belongs.
+    uint8_t         protocol;                           // Inner protocol number c.f. those issued by IANA for IP protocols
+
+    uint8_t         payload[MICROBIT_RADIO_MAX_PACKET_SIZE];    // User / higher layer protocol data
+    FrameBuffer     *next;                              // Linkage, to allow this and other protocols to queue packets pending processing.
+    uint8_t         rssi;                               // Received signal strength of this frame.
+};
+
+
+class MicroBitRadio : MicroBitComponent
+{
+    uint8_t                 group;      // The radio group to which this micro:bit belongs.
+    uint8_t                 queueDepth; // The number of packets in the receiver queue.
+    uint8_t                 rssi;
+    FrameBuffer             *rxQueue;   // A linear list of incoming packets, queued awaiting processing.
+    FrameBuffer             *rxBuf;     // A pointer to the buffer being actively used by the RADIO hardware.
+
+    public:
+    MicroBitRadioDatagram   datagram;   // A simple datagram service.
+    MicroBitRadioEvent      event;      // A simple event handling service.
+    static MicroBitRadio    *instance;  // A singleton reference, used purely by the interrupt service routine.
+
+    /**
+      * Constructor.
+      *
+      * Initialise the MicroBitRadio.
+      *
+      * @note This class is demand activated, as a result most resources are only
+      *       committed if send/recv or event registrations calls are made.
+      */
+    MicroBitRadio(uint16_t id = MICROBIT_ID_RADIO);
+
+    /**
+      * Change the output power level of the transmitter to the given value.
+      *
+      * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
+      */
+    int setTransmitPower(int power);
+
+    /**
+      * Change the transmission and reception band of the radio to the given channel
+      *
+      * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range,
+      *         or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int setFrequencyBand(int band);
+
+    /**
+      * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory
+      * actively being used by the radio hardware to store incoming data.
+      *
+      * @return a pointer to the current receive buffer.
+      */
+    FrameBuffer * getRxBuf();
+
+    /**
+      * Attempt to queue a buffer received by the radio hardware, if sufficient space is available.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer
+      *         could not be allocated (either by policy or memory exhaustion).
+      */
+    int queueRxBuf();
+
+    /**
+      * Sets the RSSI for the most recent packet.
+      *
+      * @param rssi the new rssi value.
+      *
+      * @note should only be called from RADIO_IRQHandler...
+      */
+    int setRSSI(uint8_t rssi);
+
+    /**
+      * Retrieves the current RSSI for the most recent packet.
+      *
+      * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int getRSSI();
+
+    /**
+      * Initialises the radio for use as a multipoint sender/receiver
+      *
+      * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int enable();
+
+    /**
+      * Disables the radio for use as a multipoint sender/receiver.
+      *
+      * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int disable();
+
+    /**
+      * Sets the radio to listen to packets sent with the given group id.
+      *
+      * @param group The group to join. A micro:bit can only listen to one group ID at any time.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int setGroup(uint8_t group);
+
+    /**
+      * A background, low priority callback that is triggered whenever the processor is idle.
+      * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers.
+      */
+    virtual void idleTick();
+
+    /**
+      * Determines the number of packets ready to be processed.
+      *
+      * @return The number of packets in the receive buffer.
+      */
+    int dataReady();
+
+    /**
+      * Retrieves the next packet from the receive buffer.
+      * If a data packet is available, then it will be returned immediately to
+      * the caller. This call will also dequeue the buffer.
+      *
+      * @return The buffer containing the the packet. If no data is available, NULL is returned.
+      *
+      * @note Once recv() has been called, it is the callers responsibility to
+      *       delete the buffer when appropriate.
+      */
+    FrameBuffer* recv();
+
+    /**
+      * Transmits the given buffer onto the broadcast radio.
+      * The call will wait until the transmission of the packet has completed before returning.
+      *
+      * @param data The packet contents to transmit.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+      */
+    int send(FrameBuffer *buffer);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitRadioDatagram.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,135 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_RADIO_DATAGRAM_H
+#define MICROBIT_RADIO_DATAGRAM_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitRadio.h"
+#include "ManagedString.h"
+
+/**
+  * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+  *
+  * This class provides the ability to broadcast simple text or binary messages to other micro:bits in the vicinity
+  * It is envisaged that this would provide the basis for children to experiment with building their own, simple,
+  * custom protocols.
+  *
+  * @note This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
+  * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+  * For serious applications, BLE should be considered a substantially more secure alternative.
+  */
+class MicroBitRadioDatagram
+{
+    MicroBitRadio   &radio;     // The underlying radio module used to send and receive data.
+    FrameBuffer     *rxQueue;   // A linear list of incoming packets, queued awaiting processing.
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Creates an instance of a MicroBitRadioDatagram which offers the ability
+      * to broadcast simple text or binary messages to other micro:bits in the vicinity
+      *
+      * @param r The underlying radio module used to send and receive data.
+      */
+    MicroBitRadioDatagram(MicroBitRadio &r);
+
+    /**
+      * Retrieves packet payload data into the given buffer.
+      *
+      * If a data packet is already available, then it will be returned immediately to the caller.
+      * If no data is available then MICROBIT_INVALID_PARAMETER is returned.
+      *
+      * @param buf A pointer to a valid memory location where the received data is to be stored
+      *
+      * @param len The maximum amount of data that can safely be stored in 'buf'
+      *
+      * @return The length of the data stored, or MICROBIT_INVALID_PARAMETER if no data is available, or the memory regions provided are invalid.
+      */
+    int recv(uint8_t *buf, int len);
+
+    /**
+      * Retreives packet payload data into the given buffer.
+      *
+      * If a data packet is already available, then it will be returned immediately to the caller
+      * in the form of a PacketBuffer.
+      *
+      * @return the data received, or an empty PacketBuffer if no data is available.
+      */
+    PacketBuffer recv();
+
+    /**
+      * Transmits the given buffer onto the broadcast radio.
+      *
+      * This is a synchronous call that will wait until the transmission of the packet
+      * has completed before returning.
+      *
+      * @param buffer The packet contents to transmit.
+      *
+      * @param len The number of bytes to transmit.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+      *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+      */
+    int send(uint8_t *buffer, int len);
+
+    /**
+      * Transmits the given string onto the broadcast radio.
+      *
+      * This is a synchronous call that will wait until the transmission of the packet
+      * has completed before returning.
+      *
+      * @param data The packet contents to transmit.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+      *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+      */
+    int send(PacketBuffer data);
+
+    /**
+      * Transmits the given string onto the broadcast radio.
+      *
+      * This is a synchronous call that will wait until the transmission of the packet
+      * has completed before returning.
+      *
+      * @param data The packet contents to transmit.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+      *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+      */
+    int send(ManagedString data);
+
+    /**
+      * Protocol handler callback. This is called when the radio receives a packet marked as a datagram.
+      *
+      * This function process this packet, and queues it for user reception.
+      */
+    void packetReceived();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitRadioEvent.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,143 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_RADIO_EVENT_H
+#define MICROBIT_RADIO_EVENT_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitRadio.h"
+#include "EventModel.h"
+
+/**
+ * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+ *
+ * This class provides the ability to extend the micro:bit's default EventModel to other micro:bits in the vicinity,
+ * in a very similar way to the MicroBitEventService for BLE interfaces.
+ *
+ * It is envisaged that this would provide the basis for children to experiment with building their own, simple,
+ * custom asynchronous events and actions.
+ *
+ * @note This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
+ * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+ * For serious applications, BLE should be considered a substantially more secure alternative.
+ */
+class MicroBitRadioEvent
+{
+    bool            suppressForwarding;     // A private flag used to prevent event forwarding loops.
+    MicroBitRadio   &radio;                 // A reference to the underlying radio module to use.
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Creates an instance of MicroBitRadioEvent which offers the ability to extend
+      * the micro:bit's default EventModel to other micro:bits in the vicinity.
+      *
+      * @param r The underlying radio module used to send and receive data.
+      */
+    MicroBitRadioEvent(MicroBitRadio &r);
+
+    /**
+      * Associates the given event with the radio channel.
+      *
+      * Once registered, all events matching the given registration sent to this micro:bit's
+      * default EventModel will be automatically retransmitted on the radio.
+      *
+      * @param id The id of the event to register.
+      *
+      * @param value the value of the event to register.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if no default EventModel is available.
+      *
+      * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
+      *       id and value fields.
+      */
+    int listen(uint16_t id, uint16_t value);
+
+    /**
+      * Associates the given event with the radio channel.
+      *
+      * Once registered, all events matching the given registration sent to the given
+      * EventModel will be automatically retransmitted on the radio.
+      *
+      * @param id The id of the events to register.
+      *
+      * @param value the value of the event to register.
+      *
+      * @param eventBus The EventModel to listen for events on.
+      *
+      * @return MICROBIT_OK on success.
+      *
+      * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
+      *       id and value fields.
+      */
+    int listen(uint16_t id, uint16_t value, EventModel &eventBus);
+
+    /**
+      * Disassociates the given event with the radio channel.
+      *
+      * @param id The id of the events to deregister.
+      *
+      * @param value The value of the event to deregister.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the default message bus does not exist.
+      *
+      * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id.
+      */
+    int ignore(uint16_t id, uint16_t value);
+
+    /**
+      * Disassociates the given events with the radio channel.
+      *
+      * @param id The id of the events to deregister.
+      *
+      * @param value The value of the event to deregister.
+      *
+      * @param eventBus The EventModel to deregister on.
+      *
+      * @return MICROBIT_OK on success.
+      *
+      * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id.
+      */
+    int ignore(uint16_t id, uint16_t value, EventModel &eventBus);
+
+    /**
+      * Protocol handler callback. This is called when the radio receives a packet marked as using the event protocol.
+      *
+      * This function process this packet, and fires the event contained inside onto the default EventModel.
+      */
+    void packetReceived();
+
+    /**
+      * Event handler callback. This is called whenever an event is received matching one of those registered through
+      * the registerEvent() method described above. Upon receiving such an event, it is wrapped into
+      * a radio packet and transmitted to any other micro:bits in the same group.
+      */
+    void eventReceived(MicroBitEvent e);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitSerial.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,597 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_SERIAL_H
+#define MICROBIT_SERIAL_H
+
+#include "mbed.h"
+#include "ManagedString.h"
+
+#define MICROBIT_SERIAL_DEFAULT_BAUD_RATE   115200
+#define MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE 20
+
+#define MICROBIT_SERIAL_EVT_DELIM_MATCH     1
+#define MICROBIT_SERIAL_EVT_HEAD_MATCH      2
+#define MICROBIT_SERIAL_EVT_RX_FULL         3
+
+#define MICROBIT_SERIAL_RX_IN_USE           1
+#define MICROBIT_SERIAL_TX_IN_USE           2
+#define MICROBIT_SERIAL_RX_BUFF_INIT        4
+#define MICROBIT_SERIAL_TX_BUFF_INIT        8
+
+
+enum MicroBitSerialMode
+{
+    ASYNC,
+	SYNC_SPINWAIT,
+	SYNC_SLEEP
+};
+
+/**
+  * Class definition for MicroBitSerial.
+  *
+  * Represents an instance of RawSerial which accepts micro:bit specific data types.
+  */
+class MicroBitSerial : public RawSerial
+{
+
+    //holds that state of the mutex locks for all MicroBitSerial instances.
+    static uint8_t status;
+
+    //holds the state of the baudrate for all MicroBitSerial instances.
+    static int baudrate;
+
+    //delimeters used for matching on receive.
+    ManagedString delimeters;
+
+    //a variable used when a user calls the eventAfter() method.
+    int rxBuffHeadMatch;
+
+    uint8_t *rxBuff;
+    uint8_t rxBuffSize;
+    volatile uint16_t rxBuffHead;
+    uint16_t rxBuffTail;
+
+
+    uint8_t *txBuff;
+    uint8_t txBuffSize;
+    uint16_t txBuffHead;
+    volatile uint16_t txBuffTail;
+
+    /**
+      * An internal interrupt callback for MicroBitSerial configured for when a
+      * character is received.
+      *
+      * Each time a character is received fill our circular buffer!
+      */
+    void dataReceived();
+
+    /**
+      * An internal interrupt callback for MicroBitSerial.
+      *
+      * Each time the Serial module's buffer is empty, write a character if we have
+      * characters to write.
+      */
+    void dataWritten();
+
+    /**
+      * An internal method to configure an interrupt on tx buffer and also
+      * a best effort copy operation to move bytes from a user buffer to our txBuff
+      *
+      * @param string a pointer to the first character of the users' buffer.
+      *
+      * @param len the length of the string, and ultimately the maximum number of bytes
+      *        that will be copied dependent on the state of txBuff
+      *
+      * @param mode determines whether to configure the current fiber context or not. If
+      *             The mode is SYNC_SPINWAIT, the context will not be configured, otherwise
+      *             no context will be configured.
+      *
+      * @return the number of bytes copied into the buffer.
+      */
+    int setTxInterrupt(uint8_t *string, int len, MicroBitSerialMode mode);
+
+    /**
+      * Locks the mutex so that others can't use this serial instance for reception
+      */
+    void lockRx();
+
+    /**
+      * Locks the mutex so that others can't use this serial instance for transmission
+      */
+    void lockTx();
+
+    /**
+      * Unlocks the mutex so that others can use this serial instance for reception
+      */
+    void unlockRx();
+
+    /**
+      * Unlocks the mutex so that others can use this serial instance for transmission
+      */
+    void unlockTx();
+
+    /**
+      * We do not want to always have our buffers initialised, especially if users to not
+      * use them. We only bring them up on demand.
+      */
+    int initialiseRx();
+
+    /**
+      * We do not want to always have our buffers initialised, especially if users to not
+      * use them. We only bring them up on demand.
+      */
+    int initialiseTx();
+
+    /**
+      * An internal method that either spin waits if mode is set to SYNC_SPINWAIT
+      * or puts the fiber to sleep if the mode is set to SYNC_SLEEP
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP
+      */
+    void send(MicroBitSerialMode mode);
+
+    /**
+      * Reads a single character from the rxBuff
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - A character is read from the rxBuff if available, if there
+      *                    are no characters to be read, a value of zero is returned immediately.
+      *
+      *            SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
+      *                            are no characters to be read, this method will spin
+      *                            (lock up the processor) until a character is available.
+      *
+      *            SYNC_SLEEP - A character is read from the rxBuff if available, if there
+      *                         are no characters to be read, the calling fiber sleeps
+      *                         until there is a character available.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return a character from the circular buffer, or MICROBIT_NO_DATA is there
+      *         are no characters in the buffer.
+      */
+    int getChar(MicroBitSerialMode mode);
+
+    /**
+      * An internal method that copies values from a circular buffer to a linear buffer.
+      *
+      * @param circularBuff a pointer to the source circular buffer
+      *
+      * @param circularBuffSize the size of the circular buffer
+      *
+      * @param linearBuff a pointer to the destination linear buffer
+      *
+      * @param tailPosition the tail position in the circular buffer you want to copy from
+      *
+      * @param headPosition the head position in the circular buffer you want to copy to
+      *
+      * @note this method assumes that the linear buffer has the appropriate amount of
+      *       memory to contain the copy operation
+      */
+    void circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition);
+
+    public:
+
+    /**
+      * Constructor.
+      * Create an instance of MicroBitSerial
+      *
+      * @param tx the Pin to be used for transmission
+      *
+      * @param rx the Pin to be used for receiving data
+      *
+      * @param rxBufferSize the size of the buffer to be used for receiving bytes
+      *
+      * @param txBufferSize the size of the buffer to be used for transmitting bytes
+      *
+      * @code
+      * MicroBitSerial serial(USBTX, USBRX);
+      * @endcode
+      * @note the default baud rate is 115200. More API details can be found:
+      *       -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/SerialBase.h
+      *       -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/RawSerial.h
+      *
+      *       Buffers aren't allocated until the first send or receive respectively.
+      */
+    MicroBitSerial(PinName tx, PinName rx, uint8_t rxBufferSize = MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE, uint8_t txBufferSize = MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE);
+
+    /**
+      * Sends a single character over the serial line.
+      *
+      * @param c the character to send
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - the character is copied into the txBuff and returns immediately.
+      *
+      *            SYNC_SPINWAIT - the character is copied into the txBuff and this method
+      *                            will spin (lock up the processor) until the character has
+      *                            been sent.
+      *
+      *            SYNC_SLEEP - the character is copied into the txBuff and the fiber sleeps
+      *                         until the character has been sent. This allows other fibers
+      *                         to continue execution.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber
+      *         is using the serial instance for transmission.
+      */
+    int sendChar(char c, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Sends a ManagedString over the serial line.
+      *
+      * @param s the string to send
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - bytes are copied into the txBuff and returns immediately.
+      *
+      *            SYNC_SPINWAIT - bytes are copied into the txBuff and this method
+      *                            will spin (lock up the processor) until all bytes
+      *                            have been sent.
+      *
+      *            SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
+      *                         until all bytes have been sent. This allows other fibers
+      *                         to continue execution.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
+      *         is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
+      *         if buffer is invalid, or the given bufferLen is <= 0.
+      */
+    int send(ManagedString s, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Sends a buffer of known length over the serial line.
+      *
+      * @param buffer a pointer to the first character of the buffer
+      *
+      * @param len the number of bytes that are safely available to read.
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - bytes are copied into the txBuff and returns immediately.
+      *
+      *            SYNC_SPINWAIT - bytes are copied into the txBuff and this method
+      *                            will spin (lock up the processor) until all bytes
+      *                            have been sent.
+      *
+      *            SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
+      *                         until all bytes have been sent. This allows other fibers
+      *                         to continue execution.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
+      *         is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
+      *         if buffer is invalid, or the given bufferLen is <= 0.
+      */
+    int send(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Reads a single character from the rxBuff
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - A character is read from the rxBuff if available, if there
+      *                    are no characters to be read, a value of MICROBIT_NO_DATA is returned immediately.
+      *
+      *            SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
+      *                            are no characters to be read, this method will spin
+      *                            (lock up the processor) until a character is available.
+      *
+      *            SYNC_SLEEP - A character is read from the rxBuff if available, if there
+      *                         are no characters to be read, the calling fiber sleeps
+      *                         until there is a character available.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return a character, MICROBIT_SERIAL_IN_USE if another fiber is using the serial instance for reception,
+      *         MICROBIT_NO_RESOURCES if buffer allocation did not complete successfully, or MICROBIT_NO_DATA if
+      *         the rx buffer is empty and the mode given is ASYNC.
+      */
+    int read(MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Reads multiple characters from the rxBuff and returns them as a ManagedString
+      *
+      * @param size the number of characters to read.
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - If the desired number of characters are available, this will return
+      *                    a ManagedString with the expected size. Otherwise, it will read however
+      *                    many characters there are available.
+      *
+      *            SYNC_SPINWAIT - If the desired number of characters are available, this will return
+      *                            a ManagedString with the expected size. Otherwise, this method will spin
+      *                            (lock up the processor) until the desired number of characters have been read.
+      *
+      *            SYNC_SLEEP - If the desired number of characters are available, this will return
+      *                         a ManagedString with the expected size. Otherwise, the calling fiber sleeps
+      *                         until the desired number of characters have been read.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return A ManagedString, or an empty ManagedString if an error was encountered during the read.
+      */
+    ManagedString read(int size, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Reads multiple characters from the rxBuff and fills a user buffer.
+      *
+      * @param buffer a pointer to a user allocated buffer.
+      *
+      * @param bufferLen the amount of data that can be safely stored
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - If the desired number of characters are available, this will fill
+      *                    the given buffer. Otherwise, it will fill the buffer with however
+      *                    many characters there are available.
+      *
+      *            SYNC_SPINWAIT - If the desired number of characters are available, this will fill
+      *                            the given buffer. Otherwise, this method will spin (lock up the processor)
+      *                            and fill the buffer until the desired number of characters have been read.
+      *
+      *            SYNC_SLEEP - If the desired number of characters are available, this will fill
+      *                         the given buffer. Otherwise, the calling fiber sleeps
+      *                         until the desired number of characters have been read.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return the number of characters read, or MICROBIT_SERIAL_IN_USE if another fiber
+      *         is using the instance for receiving.
+      */
+    int read(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * Reads until one of the delimeters matches a character in the rxBuff
+      *
+      * @param delimeters a ManagedString containing a sequence of delimeter characters e.g. ManagedString("\r\n")
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - If one of the delimeters matches a character already in the rxBuff
+      *                    this method will return a ManagedString up to the delimeter.
+      *                    Otherwise, it will return an Empty ManagedString.
+      *
+      *            SYNC_SPINWAIT - If one of the delimeters matches a character already in the rxBuff
+      *                            this method will return a ManagedString up to the delimeter.
+      *                            Otherwise, this method will spin (lock up the processor) until a
+      *                            received character matches one of the delimeters.
+      *
+      *            SYNC_SLEEP - If one of the delimeters matches a character already in the rxBuff
+      *                         this method will return a ManagedString up to the delimeter.
+      *                         Otherwise, the calling fiber sleeps until a character matching one
+      *                         of the delimeters is seen.
+      *
+      *         Defaults to SYNC_SLEEP.
+      *
+      * @return A ManagedString containing the characters up to a delimeter, or an Empty ManagedString,
+      *         if another fiber is currently using this instance for reception.
+      *
+      * @note delimeters are matched on a per byte basis.
+      */
+    ManagedString readUntil(ManagedString delimeters, MicroBitSerialMode mode = MICROBIT_DEFAULT_SERIAL_MODE);
+
+    /**
+      * A wrapper around the inherited method "baud" so we can trap the baud rate
+      * as it changes and restore it if redirect() is called.
+      *
+      * @param baudrate the new baudrate. See:
+      *         - https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c
+      *        for permitted baud rates.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if baud rate is less than 0, otherwise MICROBIT_OK.
+      *
+      * @note the underlying implementation chooses the first allowable rate at or above that requested.
+      */
+    void baud(int baudrate);
+
+    /**
+      * A way of dynamically configuring the serial instance to use pins other than USBTX and USBRX.
+      *
+      * @param tx the new transmission pin.
+      *
+      * @param rx the new reception pin.
+      *
+      * @return MICROBIT_SERIAL_IN_USE if another fiber is currently transmitting or receiving, otherwise MICROBIT_OK.
+      */
+    int redirect(PinName tx, PinName rx);
+
+    /**
+      * Configures an event to be fired after "len" characters.
+      *
+      * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_HEAD_MATCH.
+      *
+      * @param len the number of characters to wait before triggering the event.
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will configure the event and return immediately.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+      *                         event is received.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+      */
+    int eventAfter(int len, MicroBitSerialMode mode = ASYNC);
+
+    /**
+      * Configures an event to be fired on a match with one of the delimeters.
+      *
+      * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_DELIM_MATCH.
+      *
+      * @param delimeters the characters to match received characters against e.g. ManagedString("\n")
+      *
+      * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+      *        gives a different behaviour:
+      *
+      *            ASYNC - Will configure the event and return immediately.
+      *
+      *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+      *
+      *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+      *                         event is received.
+      *
+      * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+      *
+      * @note delimeters are matched on a per byte basis.
+      */
+    int eventOn(ManagedString delimeters, MicroBitSerialMode mode = ASYNC);
+
+    /**
+      * Determines whether there is any data waiting in our Rx buffer.
+      *
+      * @return 1 if we have space, 0 if we do not.
+      *
+      * @note We do not wrap the super's readable() method as we don't want to
+      *       interfere with communities that use manual calls to serial.readable().
+      */
+    int isReadable();
+
+    /**
+      * Determines if we have space in our txBuff.
+      *
+      * @return 1 if we have space, 0 if we do not.
+      *
+      * @note We do not wrap the super's writeable() method as we don't want to
+      *       interfere with communities that use manual calls to serial.writeable().
+      */
+    int isWriteable();
+
+    /**
+      * Reconfigures the size of our rxBuff
+      *
+      * @param size the new size for our rxBuff
+      *
+      * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+      *         for reception, otherwise MICROBIT_OK.
+      */
+    int setRxBufferSize(uint8_t size);
+
+    /**
+      * Reconfigures the size of our txBuff
+      *
+      * @param size the new size for our txBuff
+      *
+      * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+      *         for transmission, otherwise MICROBIT_OK.
+      */
+    int setTxBufferSize(uint8_t size);
+
+    /**
+      * The size of our rx buffer in bytes.
+      *
+      * @return the current size of rxBuff in bytes
+      */
+    int getRxBufferSize();
+
+    /**
+      * The size of our tx buffer in bytes.
+      *
+      * @return the current size of txBuff in bytes
+      */
+    int getTxBufferSize();
+
+    /**
+      * Sets the tail to match the head of our circular buffer for reception,
+      * effectively clearing the reception buffer.
+      *
+      * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+      *         for reception, otherwise MICROBIT_OK.
+      */
+    int clearRxBuffer();
+
+    /**
+      * Sets the tail to match the head of our circular buffer for transmission,
+      * effectively clearing the transmission buffer.
+      *
+      * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+      *         for transmission, otherwise MICROBIT_OK.
+      */
+    int clearTxBuffer();
+
+    /**
+      * The number of bytes currently stored in our rx buffer waiting to be digested,
+      * by the user.
+      *
+      * @return The currently buffered number of bytes in our rxBuff.
+      */
+    int rxBufferedSize();
+
+    /**
+      * The number of bytes currently stored in our tx buffer waiting to be transmitted
+      * by the hardware.
+      *
+      * @return The currently buffered number of bytes in our txBuff.
+      */
+    int txBufferedSize();
+
+    /**
+      * Determines if the serial bus is currently in use by another fiber for reception.
+      *
+      * @return The state of our mutex lock for reception.
+      *
+      * @note Only one fiber can call read at a time
+      */
+    int rxInUse();
+
+    /**
+      * Determines if the serial bus is currently in use by another fiber for transmission.
+      *
+      * @return The state of our mutex lock for transmition.
+      *
+      * @note Only one fiber can call send at a time
+      */
+    int txInUse();
+
+    /**
+      * Detaches a previously configured interrupt
+      *
+      * @param interruptType one of Serial::RxIrq or Serial::TxIrq
+      */
+    void detach(Serial::IrqType interuptType);
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitStorage.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,240 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_STORAGE_H
+#define MICROBIT_STORAGE_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "ManagedString.h"
+#include "ErrorNo.h"
+
+#define MICROBIT_STORAGE_MAGIC       0xCAFE
+
+#define MICROBIT_STORAGE_BLOCK_SIZE             48
+#define MICROBIT_STORAGE_KEY_SIZE               16
+#define MICROBIT_STORAGE_VALUE_SIZE             MICROBIT_STORAGE_BLOCK_SIZE - MICROBIT_STORAGE_KEY_SIZE
+
+#define MICROBIT_STORAGE_STORE_PAGE_OFFSET      17      //Use the page just above the BLE Bond Data.
+#define MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET    19      //Use the page just below the BLE Bond Data.
+
+struct KeyValuePair
+{
+    uint8_t key[MICROBIT_STORAGE_KEY_SIZE];
+    uint8_t value[MICROBIT_STORAGE_VALUE_SIZE];
+};
+
+struct KeyValueStore
+{
+    uint32_t magic;
+    uint32_t size;
+
+    KeyValueStore(uint32_t magic, uint32_t size)
+    {
+        this->magic = magic;
+        this->size = size;
+    }
+
+    KeyValueStore()
+    {
+        this->magic = 0;
+        this->size = 0;
+    }
+};
+
+
+/**
+  * Class definition for the MicroBitStorage class.
+  * This allows reading and writing of small blocks of data to FLASH memory.
+  *
+  * This class operates as a key value store, it allows the retrieval, addition
+  * and deletion of KeyValuePairs.
+  *
+  * The first 8 bytes are reserved for the KeyValueStore struct which gives core
+  * information such as the number of KeyValuePairs in the store, and whether the
+  * store has been initialised.
+  *
+  * After the KeyValueStore struct, KeyValuePairs are arranged contiguously until
+  * the end of the block used as persistent storage.
+  *
+  * |-------8-------|--------48-------|-----|---------48--------|
+  * | KeyValueStore | KeyValuePair[0] | ... | KeyValuePair[N-1] |
+  * |---------------|-----------------|-----|-------------------|
+  */
+class MicroBitStorage
+{
+    /**
+      * Function for copying words from one location to another.
+      *
+      * @param from the address to copy data from.
+      *
+      * @param to the address to copy the data to.
+      *
+      * @param sizeInWords the number of words to copy
+      */
+    void flashCopy(uint32_t* from, uint32_t* to, int sizeInWords);
+
+    /**
+      * Function for populating the scratch page with a KeyValueStore.
+      *
+      * @param store the KeyValueStore struct to write to the scratch page.
+      */
+    void scratchKeyValueStore(KeyValueStore store);
+
+    /**
+      * Function for populating the scratch page with a KeyValuePair.
+      *
+      * @param pair the KeyValuePair struct to write to the scratch page.
+      *
+      * @param flashPointer the pointer in flash where this KeyValuePair resides. This pointer
+      * is used to determine the offset into the scratch page, where the KeyValuePair should
+      * be written.
+      */
+    void scratchKeyValuePair(KeyValuePair pair, uint32_t* flashPointer);
+
+    public:
+
+    /**
+      * Default constructor.
+      *
+      * Creates an instance of MicroBitStorage which acts like a KeyValueStore
+      * that allows the retrieval, addition and deletion of KeyValuePairs.
+      */
+    MicroBitStorage();
+
+    /**
+      * Writes the given number of bytes to the address specified.
+      *
+      * @param buffer the data to write.
+      *
+      * @param address the location in memory to write to.
+      *
+      * @param length the number of bytes to write.
+      *
+      * @note currently not implemented.
+      */
+    int writeBytes(uint8_t *buffer, uint32_t address, int length);
+
+    /**
+      * Method for erasing a page in flash.
+      *
+      * @param page_address Address of the first word in the page to be erased.
+      */
+    void flashPageErase(uint32_t * page_address);
+
+    /**
+      * Method for writing a word of data in flash with a value.
+      *
+      * @param address Address of the word to change.
+      *
+      * @param value Value to be written to flash.
+      */
+    void flashWordWrite(uint32_t * address, uint32_t value);
+
+    /**
+      * Places a given key, and it's corresponding value into flash at the earliest
+      * available point.
+      *
+      * @param key the unique name that should be used as an identifier for the given data.
+      *            The key is presumed to be null terminated.
+      *
+      * @param data a pointer to the beginning of the data to be persisted.
+      *
+      * @param dataSize the size of the data to be persisted
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
+      *         MICROBIT_NO_RESOURCES if the storage page is full
+      */
+    int put(const char* key, uint8_t* data, int dataSize);
+
+
+    /**
+      * Places a given key, and it's corresponding value into flash at the earliest
+      * available point.
+      *
+      * @param key the unique name that should be used as an identifier for the given data.
+      *
+      * @param data a pointer to the beginning of the data to be persisted.
+      *
+      * @param dataSize the size of the data to be persisted
+      *
+      * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
+      *         MICROBIT_NO_RESOURCES if the storage page is full
+      */
+    int put(ManagedString key, uint8_t* data, int dataSize);
+
+    /**
+      * Retreives a KeyValuePair identified by a given key.
+      *
+      * @param key the unique name used to identify a KeyValuePair in flash.
+      *
+      * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
+      *         NULL if the key was not found in storage.
+      *
+      * @note it is up to the user to free memory after use.
+      */
+    KeyValuePair* get(const char* key);
+
+    /**
+      * Retreives a KeyValuePair identified by a given key.
+      *
+      * @param key the unique name used to identify a KeyValuePair in flash.
+      *
+      * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
+      *         NULL if the key was not found in storage.
+      *
+      * @note it is up to the user to free memory after use.
+      */
+    KeyValuePair* get(ManagedString key);
+
+    /**
+      * Removes a KeyValuePair identified by a given key.
+      *
+      * @param key the unique name used to identify a KeyValuePair in flash.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
+      *         was not found in flash.
+      */
+    int remove(const char* key);
+
+    /**
+      * Removes a KeyValuePair identified by a given key.
+      *
+      * @param key the unique name used to identify a KeyValuePair in flash.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
+      *         was not found in flash.
+      */
+    int remove(ManagedString key);
+
+    /**
+      * The size of the flash based KeyValueStore.
+      *
+      * @return the number of entries in the key value store
+      */
+    int size();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/MicroBitThermometer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,173 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_THERMOMETER_H
+#define MICROBIT_THERMOMETER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitComponent.h"
+#include "MicroBitStorage.h"
+
+#define MICROBIT_THERMOMETER_PERIOD             1000
+
+
+#define MAG3110_SAMPLE_RATES                    11
+
+/*
+ * Temperature events
+ */
+#define MICROBIT_THERMOMETER_EVT_UPDATE         1
+
+#define MICROBIT_THERMOMETER_ADDED_TO_IDLE      2
+
+/**
+  * Class definition for MicroBit Thermometer.
+  *
+  * Infers and stores the ambient temoperature based on the surface temperature
+  * of the various chips on the micro:bit.
+  *
+  */
+class MicroBitThermometer : public MicroBitComponent
+{
+    unsigned long           sampleTime;
+    uint32_t                samplePeriod;
+    int16_t                 temperature;
+    int16_t                 offset;
+    MicroBitStorage*        storage;
+
+    public:
+
+    /**
+      * Constructor.
+      * Create new MicroBitThermometer that gives an indication of the current temperature.
+      *
+      * @param _storage an instance of MicroBitStorage used to persist temperature offset data
+      *
+      * @param id the unique EventModel id of this component. Defaults to MICROBIT_ID_THERMOMETER.
+      *
+      * @code
+      * MicroBitStorage storage;
+      * MicroBitThermometer thermometer(storage);
+      * @endcode
+      */
+    MicroBitThermometer(MicroBitStorage& _storage, uint16_t id = MICROBIT_ID_THERMOMETER);
+
+    /**
+      * Constructor.
+      * Create new MicroBitThermometer that gives an indication of the current temperature.
+      *
+      * @param id the unique EventModel id of this component. Defaults to MICROBIT_ID_THERMOMETER.
+      *
+      * @code
+      * MicroBitThermometer thermometer;
+      * @endcode
+      */
+    MicroBitThermometer(uint16_t id = MICROBIT_ID_THERMOMETER);
+
+    /**
+      * Set the sample rate at which the temperatureis read (in ms).
+      *
+      * The default sample period is 1 second.
+      *
+      * @param period the requested time between samples, in milliseconds.
+      *
+      * @note the temperature is always read in the background, and is only updated
+      * when the processor is idle, or when the temperature is explicitly read.
+      */
+    void setPeriod(int period);
+
+    /**
+      * Reads the currently configured sample rate of the thermometer.
+      *
+      * @return The time between samples, in milliseconds.
+      */
+    int getPeriod();
+
+    /**
+      * Set the value that is used to offset the raw silicon temperature.
+      *
+      * @param offset the offset for the silicon temperature
+      *
+      * @return MICROBIT_OK on success
+      */
+    int setOffset(int offset);
+
+    /**
+      * Retreive the value that is used to offset the raw silicon temperature.
+      *
+      * @return the current offset.
+      */
+    int getOffset();
+
+    /**
+      * This member function fetches the raw silicon temperature, and calculates
+      * the value used to offset the raw silicon temperature based on a given temperature.
+      *
+      * @param calibrationTemp the temperature used to calculate the raw silicon temperature
+      * offset.
+      *
+      * @return MICROBIT_OK on success
+      */
+    int setCalibration(int calibrationTemp);
+
+    /**
+      * Gets the current temperature of the microbit.
+      *
+      * @return the current temperature, in degrees celsius.
+      *
+      * @code
+      * thermometer.getTemperature();
+      * @endcode
+      */
+    int getTemperature();
+
+    /**
+      * Updates the temperature sample of this instance of MicroBitThermometer
+      * only if isSampleNeeded() indicates that an update is required.
+      *
+      * This call also will add the thermometer to fiber components to receive
+      * periodic callbacks.
+      *
+      * @return MICROBIT_OK on success.
+      */
+    int updateSample();
+
+    /**
+      * Periodic callback from MicroBit idle thread.
+      */
+    virtual void idleTick();
+
+    private:
+
+    /**
+      * Determines if we're due to take another temperature reading
+      *
+      * @return 1 if we're due to take a temperature reading, 0 otherwise.
+      */
+    int isSampleNeeded();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/drivers/TimedInterruptIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,59 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 Lancaster University, UK.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef TIMED_INTERRUPT_H
+#define TIMED_INTERRUPT_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+class TimedInterruptIn : public InterruptIn
+{
+    uint64_t timestamp;
+
+    public:
+
+    /**
+      * Constructor.
+      *
+      * Create an instance of TimedInterruptIn that has an additional timestamp field.
+      */
+    TimedInterruptIn(PinName name);
+
+    /**
+      * Stores the given timestamp for this instance of TimedInterruptIn.
+      *
+      * @param timestamp the timestamp to retain.
+      */
+    void setTimestamp(uint64_t timestamp);
+
+    /**
+      * Retrieves the retained timestamp for this instance of TimedInterruptIn.
+      *
+      * @return the timestamp held by this instance.
+      */
+    uint64_t getTimestamp();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/platform/yotta_cfg_mappings.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,147 @@
+#ifndef YOTTA_CFG_MAPPINGS_H
+#define YOTTA_CFG_MAPPINGS_H
+
+/**
+  * This header file contains mappings from a yotta config.json file for the DAL,
+  * to DAL specific #defines used in the DAL.
+  */
+
+//DAL mappings
+#ifdef YOTTA_CFG_MICROBIT_DAL_HEAP_ALLOCATOR
+    #define MICROBIT_HEAP_ALLOCATOR YOTTA_CFG_MICROBIT_DAL_HEAP_ALLOCATOR
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_NESTED_HEAP_PROPORTION
+    #define MICROBIT_NESTED_HEAP_SIZE YOTTA_CFG_MICROBIT_DAL_NESTED_HEAP_PROPORTION
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_REUSE_SD
+    #define MICROBIT_HEAP_REUSE_SD YOTTA_CFG_MICROBIT_DAL_REUSE_SD
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_GATT_TABLE_SIZE
+    #define MICROBIT_SD_GATT_TABLE_SIZE YOTTA_CFG_MICROBIT_DAL_GATT_TABLE_SIZE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_SYSTEM_TICK_PERIOD
+    #define SYSTEM_TICK_PERIOD_MS YOTTA_CFG_MICROBIT_DAL_SYSTEM_TICK_PERIOD
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_SYSTEM_COMPONENTS
+    #define MICROBIT_SYSTEM_COMPONENTS YOTTA_CFG_MICROBIT_DAL_SYSTEM_COMPONENTS
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_IDLE_COMPONENTS
+    #define MICROBIT_IDLE_COMPONENTS YOTTA_CFG_MICROBIT_DAL_IDLE_COMPONENTS
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_ENABLED
+    #define MICROBIT_BLE_ENABLED YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_ENABLED
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_USE_ACCEL_LSB
+    #define USE_ACCEL_LSB YOTTA_CFG_MICROBIT_DAL_USE_ACCEL_LSB
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_MIN_DISPLAY_BRIGHTNESS
+    #define MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS YOTTA_CFG_MICROBIT_DAL_MIN_DISPLAY_BRIGHTNESS
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_MAX_DISPLAY_BRIGHTNESS
+    #define MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS YOTTA_CFG_MICROBIT_DAL_MAX_DISPLAY_BRIGHTNESS
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_DISPLAY_SCROLL_SPEED
+    #define MICROBIT_DEFAULT_SCROLL_SPEED YOTTA_CFG_MICROBIT_DAL_DISPLAY_SCROLL_SPEED
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_DISPLAY_SCROLL_STRIDE
+    #define MICROBIT_DEFAULT_SCROLL_STRIDE YOTTA_CFG_MICROBIT_DAL_DISPLAY_SCROLL_STRIDE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_DISPLAY_PRINT_SPEED
+    #define MICROBIT_DEFAULT_PRINT_SPEED YOTTA_CFG_MICROBIT_DAL_DISPLAY_PRINT_SPEED
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_DEFAULT_PULLMODE
+    #define MICROBIT_DEFAULT_PULLMODE YOTTA_CFG_MICROBIT_DAL_DEFAULT_PULLMODE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_PANIC_ON_HEAP_FULL
+    #define MICROBIT_PANIC_HEAP_FULL YOTTA_CFG_MICROBIT_DAL_PANIC_ON_HEAP_FULL
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_DEBUG
+    #define MICROBIT_DBG YOTTA_CFG_MICROBIT_DAL_DEBUG
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_HEAP_DEBUG
+    #define MICROBIT_HEAP_DBG YOTTA_CFG_MICROBIT_DAL_HEAP_DEBUG
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_STACK_SIZE
+    #define MICROBIT_STACK_SIZE YOTTA_CFG_MICROBIT_DAL_STACK_SIZE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_SRAM_BASE
+    #define MICROBIT_SRAM_BASE YOTTA_CFG_MICROBIT_DAL_SRAM_BASE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_SRAM_END
+    #define MICROBIT_SRAM_END YOTTA_CFG_MICROBIT_DAL_SRAM_END
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_SD_LIMIT
+    #define MICROBIT_SD_LIMIT YOTTA_CFG_MICROBIT_DAL_SD_LIMIT
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_GATT_TABLE_START
+    #define MICROBIT_SD_GATT_TABLE_START YOTTA_CFG_MICROBIT_DAL_GATT_TABLE_START
+#endif
+
+
+//Bluetooth mappings
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_PAIRING_MODE
+    #define MICROBIT_BLE_PAIRING_MODE YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_PAIRING_MODE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_PRIVATE_ADDRESSING
+    #define MICROBIT_BLE_PRIVATE_ADDRESSES YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_PRIVATE_ADDRESSING
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_OPEN
+    #define MICROBIT_BLE_OPEN YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_OPEN
+#endif
+
+
+//we check if the user has requested open mode, otherwise we will double def!
+#if (YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_OPEN == 0)
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_WHITELIST
+    #define MICROBIT_BLE_WHITELIST YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_WHITELIST
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_ADVERTISING_TIMEOUT
+    #define MICROBIT_BLE_ADVERTISING_TIMEOUT YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_ADVERTISING_TIMEOUT
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_TX_POWER
+    #define MICROBIT_BLE_DEFAULT_TX_POWER YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_TX_POWER
+#endif
+
+#endif
+
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_DFU_SERVICE
+    #define MICROBIT_BLE_DFU_SERVICE YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_DFU_SERVICE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_EVENT_SERVICE
+    #define MICROBIT_BLE_EVENT_SERVICE YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_EVENT_SERVICE
+#endif
+
+#ifdef YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_DEVICE_INFO_SERVICE
+    #define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE YOTTA_CFG_MICROBIT_DAL_BLUETOOTH_DEVICE_INFO_SERVICE
+#endif
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/ManagedString.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,400 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MANAGED_STRING_H
+#define MANAGED_STRING_H
+
+#include "MicroBitConfig.h"
+#include "RefCounted.h"
+#include "PacketBuffer.h"
+
+struct StringData : RefCounted
+{
+    uint16_t len;
+    char data[0];
+};
+
+
+/**
+  * Class definition for a ManagedString.
+  *
+  * Uses basic reference counting to implement a copy-assignable, immutable string.
+  *
+  * This maps closely to the constructs found in many high level application languages,
+  * such as Touch Develop.
+  *
+  * Written from first principles here, for several reasons:
+  * 1) std::shared_ptr is not yet availiable on the ARMCC compiler
+  *
+  * 2) to reduce memory footprint - we don't need many of the other features in the std library
+  *
+  * 3) it makes an interesting case study for anyone interested in seeing how it works!
+  *
+  * 4) we need explicit reference counting to inter-op with low-level application langauge runtimes.
+  *
+  * 5) the reference counting needs to also work for read-only, flash-resident strings
+  */
+class ManagedString
+{
+    // StringData contains the reference count, the length, follwed by char[] data, all in one block.
+    // When referece count is 0xffff, then it's read only and should not be counted.
+    // Otherwise the block was malloc()ed.
+    // We control access to this to proide immutability and reference counting.
+    StringData *ptr;
+
+    public:
+
+    /**
+      * Constructor.
+      * Create a managed string from a specially prepared string literal.
+      *
+      * @param ptr The literal - first two bytes should be 0xff, then the length in little endian, then the literal. The literal has to be 4-byte aligned.
+      *
+      * @code
+      * static const char hello[] __attribute__ ((aligned (4))) = "\xff\xff\x05\x00" "Hello";
+      * ManagedString s((StringData*)(void*)hello);
+      * @endcode
+      */
+    ManagedString(StringData *ptr);
+
+    /**
+      * Get current ptr, do not decr() it, and set the current instance to empty string.
+      *
+      * This is to be used by specialized runtimes which pass StringData around.
+      */
+    StringData *leakData();
+
+    /**
+      * Constructor.
+      *
+      * Create a managed string from a pointer to an 8-bit character buffer.
+      *
+      * The buffer is copied to ensure safe memory management (the supplied
+      * character buffer may be declared on the stack for instance).
+      *
+      * @param str The character array on which to base the new ManagedString.
+      *
+      * @code
+      * ManagedString s("abcdefg");
+      * @endcode
+      */
+    ManagedString(const char *str);
+
+    /**
+      * Constructor.
+      *
+      * Create a managed string from a given integer.
+      *
+      * @param value The integer from which to create the ManagedString.
+      *
+      * @code
+      * ManagedString s(20);
+      * @endcode
+      */
+    ManagedString(const int value);
+
+
+    /**
+      * Constructor.
+      * Create a managed string from a given char.
+      *
+      * @param value The character from which to create the ManagedString.
+      *
+      * @code
+      * ManagedString s('a');
+      * @endcode
+      */
+    ManagedString(const char value);
+
+    /**
+      * Constructor.
+      * Create a ManagedString from a PacketBuffer. All bytes in the
+      * PacketBuffer are added to the ManagedString.
+      *
+      * @param buffer The PacktBuffer from which to create the ManagedString.
+      *
+      * @code
+      * ManagedString s = radio.datagram.recv();
+      * @endcode
+      */
+    ManagedString(PacketBuffer buffer);
+
+    /**
+      * Constructor.
+      * Create a ManagedString from a pointer to an 8-bit character buffer of a given length.
+      *
+      * The buffer is copied to ensure sane memory management (the supplied
+      * character buffer may be declared on the stack for instance).
+      *
+      * @param str The character array on which to base the new ManagedString.
+      *
+      * @param length The length of the character array
+      *
+      * @code
+      * ManagedString s("abcdefg",7);
+      * @endcode
+      */
+    ManagedString(const char *str, const int16_t length);
+
+    /**
+      * Copy constructor.
+      * Makes a new ManagedString identical to the one supplied.
+      *
+      * Shares the character buffer and reference count with the supplied ManagedString.
+      *
+      * @param s The ManagedString to copy.
+      *
+      * @code
+      * ManagedString s("abcdefg");
+      * ManagedString p(s);
+      * @endcode
+      */
+    ManagedString(const ManagedString &s);
+
+    /**
+      * Default constructor.
+      *
+      * Create an empty ManagedString.
+      *
+      * @code
+      * ManagedString s();
+      * @endcode
+      */
+    ManagedString();
+
+    /**
+      * Destructor.
+      *
+      * Free this ManagedString, and decrement the reference count to the
+      * internal character buffer.
+      *
+      * If we're holding the last reference, also free the character buffer.
+      */
+    ~ManagedString();
+
+    /**
+      * Copy assign operation.
+      *
+      * Called when one ManagedString is assigned the value of another.
+      *
+      * If the ManagedString being assigned is already referring to a character buffer,
+      * decrement the reference count and free up the buffer as necessary.
+      *
+      * Then, update our character buffer to refer to that of the supplied ManagedString,
+      * and increase its reference count.
+      *
+      * @param s The ManagedString to copy.
+      *
+      * @code
+      * ManagedString s("abcd");
+      * ManagedString p("efgh");
+      * p = s   // p now points to s, s' ref is incremented
+      * @endcode
+      */
+    ManagedString& operator = (const ManagedString& s);
+
+    /**
+      * Equality operation.
+      *
+      * Called when one ManagedString is tested to be equal to another using the '==' operator.
+      *
+      * @param s The ManagedString to test ourselves against.
+      *
+      * @return true if this ManagedString is identical to the one supplied, false otherwise.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("abcd");
+      * ManagedString p("efgh");
+      *
+      * if(p == s)
+      *     display.scroll("We are the same!");
+      * else
+      *     display.scroll("We are different!"); //p is not equal to s - this will be called
+      * @endcode
+      */
+    bool operator== (const ManagedString& s);
+
+    /**
+      * Inequality operation.
+      *
+      * Called when one ManagedString is tested to be less than another using the '<' operator.
+      *
+      * @param s The ManagedString to test ourselves against.
+      *
+      * @return true if this ManagedString is alphabetically less than to the one supplied, false otherwise.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("a");
+      * ManagedString p("b");
+      *
+      * if(s < p)
+      *     display.scroll("a is before b!"); //a is before b
+      * else
+      *     display.scroll("b is before a!");
+      * @endcode
+      */
+    bool operator< (const ManagedString& s);
+
+    /**
+      * Inequality operation.
+      *
+      * Called when one ManagedString is tested to be greater than another using the '>' operator.
+      *
+      * @param s The ManagedString to test ourselves against.
+      *
+      * @return true if this ManagedString is alphabetically greater than to the one supplied, false otherwise.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("a");
+      * ManagedString p("b");
+      *
+      * if(p>a)
+      *     display.scroll("b is after a!"); //b is after a
+      * else
+      *     display.scroll("a is after b!");
+      * @endcode
+      */
+    bool operator> (const ManagedString& s);
+
+    /**
+      * Extracts a ManagedString from this string, at the position provided.
+      *
+      * @param start The index of the first character to extract, indexed from zero.
+      *
+      * @param length The number of characters to extract from the start position
+      *
+      * @return a ManagedString representing the requested substring.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("abcdefg");
+      *
+      * display.scroll(s.substring(0,2)) // displays "ab"
+      * @endcode
+      */
+    ManagedString substring(int16_t start, int16_t length);
+
+    /**
+      * Concatenates two strings.
+      *
+      * @param lhs The first ManagedString to concatenate.
+      * @param rhs The second ManagedString to concatenate.
+      *
+      * @return a new ManagedString representing the joined strings.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("abcd");
+      * ManagedString p("efgh")
+      *
+      * display.scroll(s + p) // scrolls "abcdefgh"
+      * @endcode
+      */
+    friend ManagedString operator+ (const ManagedString& lhs, const ManagedString& rhs);
+
+    /**
+      * Provides a character value at a given position in the string, indexed from zero.
+      *
+      * @param index The position of the character to return.
+      *
+      * @return the character at posisiton index, zero if index is invalid.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("abcd");
+      *
+      * display.scroll(s.charAt(1)) // scrolls "b"
+      * @endcode
+      */
+    char charAt(int16_t index);
+
+
+    /**
+      * Provides an immutable 8 bit wide character buffer representing this string.
+      *
+      * @return a pointer to the character buffer.
+      */
+    const char *toCharArray() const
+    {
+        return ptr->data;
+    }
+
+    /**
+      * Determines the length of this ManagedString in characters.
+      *
+      * @return the length of the string in characters.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * ManagedString s("abcd");
+      *
+      * display.scroll(s.length()) // scrolls "4"
+      * @endcode
+      */
+    int16_t length() const
+    {
+        return ptr->len;
+    }
+
+    /**
+      * Empty String constant
+      */
+    static ManagedString EmptyString;
+
+    private:
+
+    /**
+      * Internal constructor helper.
+      *
+      * Configures this ManagedString to refer to the static EmptyString
+      */
+    void initEmpty();
+
+    /**
+      * Internal constructor helper.
+      *
+      * Creates this ManagedString based on a given null terminated char array.
+      */
+    void initString(const char *str);
+
+    /**
+      * Private Constructor.
+      *
+      * Create a managed string based on a concat of two strings.
+      * The buffer is copied to ensure sane memory management (the supplied
+      * character buffer may be declared on the stack for instance).
+      *
+      * @param str1 The first string on which to base the new ManagedString.
+      *
+      * @param str2 The second string on which to base the new ManagedString.
+      */
+    ManagedString(const ManagedString &s1, const ManagedString &s2);
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/ManagedType.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,279 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_MANAGED_TYPE_H
+#define MICROBIT_MANAGED_TYPE_H
+
+#include "MicroBitConfig.h"
+
+/**
+  * Class definition for a Generic Managed Type.
+  *
+  * Represents a reference counted object.
+  *
+  * @note When the destructor is called, delete is called on the object - implicitly calling the given objects destructor.
+  */
+template <class T>
+class ManagedType
+{
+protected:
+
+    int *ref;
+
+public:
+
+    T *object;
+
+    /**
+      * Constructor for the managed type, given a class space T.
+      *
+      * @param object the object that you would like to be ref counted - of class T
+      *
+      * @code
+      * T object = new T();
+      * ManagedType<T> mt(t);
+      * @endcode
+      */
+    ManagedType(T* object);
+
+    /**
+      * Default constructor for the managed type, given a class space T.
+      */
+    ManagedType();
+
+    /**
+      * Copy constructor for the managed type, given a class space T.
+      *
+      * @param t another managed type instance of class type T.
+      *
+      * @code
+      * T* object = new T();
+      * ManagedType<T> mt(t);
+      * ManagedType<T> mt1(mt);
+      * @endcode
+      */
+    ManagedType(const ManagedType<T> &t);
+
+    /**
+      * Destructor for the managed type, given a class space T.
+      */
+    ~ManagedType();
+
+    /**
+      * Copy-assign member function for the managed type, given a class space.
+      *
+      * @code
+      * T* object = new T();
+      * ManagedType<T> mt(t);
+      * ManagedType<T> mt1 = mt;
+      * @endcode
+      */
+    ManagedType<T>& operator = (const ManagedType<T>&i);
+
+    /**
+      * Returns the references to this ManagedType.
+      *
+      * @code
+      * T* object = new T();
+      * ManagedType<T> mt(t);
+      * ManagedType<T> mt1(mt);
+      *
+      * mt.getReferences // this will be 2!
+      * @endcode
+      */
+    int getReferences();
+
+    /**
+      * De-reference operator overload. This makes modifying ref-counted POD
+      * easier.
+      *
+      * @code
+      * ManagedType<int> x = 0;
+      * *x = 1; // mutates the ref-counted integer
+      * @endcode
+      */
+    T& operator*() {
+        return *object;
+    }
+
+    /**
+      * Method call operator overload. This forwards the call to the underlying
+      * object.
+      *
+      * @code
+      * ManagedType<T> x = new T();
+      * x->m(); // resolves to T::m
+      */
+    T* operator->() {
+        if (object == NULL)
+            microbit_panic(MICROBIT_NULL_DEREFERENCE);
+        return object;
+    }
+
+    /**
+      * Shorthand for `x.operator->()`
+      */
+    T* get() {
+        return object;
+    }
+
+    /**
+      * A simple inequality overload to compare two ManagedType instances.
+      */
+    bool operator!=(const ManagedType<T>& x) {
+        return !(this == x);
+    }
+
+    /**
+      * A simple equality overload to compare two ManagedType instances.
+      */
+    bool operator==(const ManagedType<T>& x) {
+        return this->object == x.object;
+    }
+};
+
+/**
+  * Constructor for the managed type, given a class space T.
+  *
+  * @param object the object that you would like to be ref counted - of class T
+  *
+  * @code
+  * T object = new T();
+  * ManagedType<T> mt(t);
+  * @endcode
+  */
+template<typename T>
+ManagedType<T>::ManagedType(T* object)
+{
+    this->object = object;
+    ref = (int *)malloc(sizeof(int));
+    *ref = 1;
+}
+
+/**
+  * Default constructor for the managed type, given a class space T.
+  */
+template<typename T>
+ManagedType<T>::ManagedType()
+{
+    this->object = NULL;
+    ref = (int *)malloc(sizeof(int));
+    *ref = 0;
+}
+
+/**
+  * Copy constructor for the managed type, given a class space T.
+  *
+  * @param t another managed type instance of class type T.
+  *
+  * @code
+  * T* object = new T();
+  * ManagedType<T> mt(t);
+  * ManagedType<T> mt1(mt);
+  * @endcode
+  */
+template<typename T>
+ManagedType<T>::ManagedType(const ManagedType<T> &t)
+{
+    this->object = t.object;
+    this->ref = t.ref;
+    (*ref)++;
+}
+
+/**
+  * Destructor for the managed type, given a class space T.
+  */
+template<typename T>
+ManagedType<T>::~ManagedType()
+{
+    // Special case - we were created using a default constructor, and never assigned a value.
+    if (*ref == 0)
+    {
+        // Simply destroy our reference counter and we're done.
+        free(ref);
+    }
+
+    // Normal case - we have a valid piece of data.
+    // Decrement our reference counter and free all allocated memory if we're deleting the last reference.
+    else if (--(*ref) == 0)
+    {
+        delete object;
+        free(ref);
+    }
+}
+
+/**
+  * Copy-assign member function for the managed type, given a class space.
+  *
+  * @code
+  * T* object = new T();
+  * ManagedType<T> mt(t);
+  * ManagedType<T> mt1 = mt;
+  * @endcode
+  */
+template<typename T>
+ManagedType<T>& ManagedType<T>::operator = (const ManagedType<T>&t)
+{
+    if (this == &t)
+        return *this;
+
+    // Special case - we were created using a default constructor, and never assigned a value.
+    if (*ref == 0)
+    {
+        // Simply destroy our reference counter, as we're about to adopt another.
+        free(ref);
+    }
+
+    else if (--(*ref) == 0)
+    {
+        delete object;
+        free(ref);
+    }
+
+    object = t.object;
+    ref = t.ref;
+
+    (*ref)++;
+
+    return *this;
+}
+
+/**
+  * Returns the references to this ManagedType.
+  *
+  * @code
+  * T* object = new T();
+  * ManagedType<T> mt(t);
+  * ManagedType<T> mt1(mt);
+  *
+  * mt.getReferences // this will be 2!
+  * @endcode
+  */
+template<typename T>
+int ManagedType<T>::getReferences()
+{
+    return (*ref);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/Matrix4.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,202 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_MATRIX4_H
+#define MICROBIT_MATRIX4_H
+
+#include "MicroBitConfig.h"
+
+/**
+* Class definition for a simple matrix, that is optimised for nx4 or 4xn matrices.
+*
+* This class is heavily optimised for these commonly used matrices as used in 3D geometry.
+* Whilst this class does support basic operations on matrices of any dimension, it is not intended as a
+* general purpose matrix class as inversion operations are only provided for 4x4 matrices.
+* For programmers needing more flexible Matrix support, the Matrix and MatrixMath classes from
+* Ernsesto Palacios provide a good basis:
+*
+* https://developer.mbed.org/cookbook/MatrixClass
+* https://developer.mbed.org/users/Yo_Robot/code/MatrixMath/
+*/
+class Matrix4
+{
+	float   *data;         // Linear buffer representing the matrix.
+	int     rows;           // The number of rows in the matrix.
+	int     cols;           // The number of columns in the matrix.
+
+public:
+
+	/**
+	  * Constructor.
+	  * Create a matrix of the given size.
+	  *
+	  * @param rows the number of rows in the matrix to be created.
+	  *
+	  * @param cols the number of columns in the matrix to be created.
+	  *
+	  * @code
+	  * Matrix4(10, 4);        // Creates a Matrix with 10 rows and 4 columns.
+	  * @endcode
+	  */
+	Matrix4(int rows, int cols);
+
+	/**
+	  * Constructor.
+	  * Create a matrix that is an identical copy of the given matrix.
+	  *
+	  * @param matrix The matrix to copy.
+	  *
+	  * @code
+	  * Matrix newMatrix(matrix);        .
+	  * @endcode
+	  */
+	Matrix4(const Matrix4 &matrix);
+
+	/**
+	  * Determines the number of columns in this matrix.
+	  *
+	  * @return The number of columns in the matrix.
+	  *
+	  * @code
+	  * int c = matrix.width();
+	  * @endcode
+	  */
+	int width();
+
+	/**
+	  * Determines the number of rows in this matrix.
+	  *
+	  * @return The number of rows in the matrix.
+	  *
+	  * @code
+	  * int r = matrix.height();
+	  * @endcode
+	  */
+	int height();
+
+	/**
+	  * Reads the matrix element at the given position.
+	  *
+	  * @param row The row of the element to read.
+	  *
+	  * @param col The column of the element to read.
+	  *
+	  * @return The value of the matrix element at the given position. 0 is returned if the given index is out of range.
+	  *
+	  * @code
+	  * float v = matrix.get(1,2);
+	  * @endcode
+	  */
+	float get(int row, int col);
+
+	/**
+	  * Writes the matrix element at the given position.
+	  *
+	  * @param row The row of the element to write.
+	  *
+	  * @param col The column of the element to write.
+	  *
+	  * @param v The new value of the element.
+	  *
+	  * @code
+	  * matrix.set(1,2,42.0);
+	  * @endcode
+	  */
+	void set(int row, int col, float v);
+
+	/**
+	  * Transposes this matrix.
+	  *
+	  * @return the resultant matrix.
+	  *
+	  * @code
+	  * matrix.transpose();
+	  * @endcode
+	  */
+	Matrix4 transpose();
+
+	/**
+	  * Multiplies this matrix with the given matrix (if possible).
+	  *
+	  * @param matrix the matrix to multiply this matrix's values against.
+	  *
+	  * @param transpose Transpose the matrices before multiplication. Defaults to false.
+	  *
+	  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+	  *
+	  * @code
+	  * Matrix result = matrixA.multiply(matrixB);
+	  * @endcode
+	  */
+	Matrix4 multiply(Matrix4 &matrix, bool transpose = false);
+
+	/**
+	  * Multiplies the transpose of this matrix with the given matrix (if possible).
+      *
+	  * @param matrix the matrix to multiply this matrix's values against.
+	  *
+	  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+	  *
+	  * @code
+	  * Matrix result = matrixA.multiplyT(matrixB);
+	  * @endcode
+	  */
+	Matrix4 multiplyT(Matrix4 &matrix);
+
+	/**
+	  * Performs an optimised inversion of a 4x4 matrix.
+	  * Only 4x4 matrices are supported by this operation.
+	  *
+	  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+	  *
+	  * @code
+	  * Matrix result = matrixA.invert();
+	  * @endcode
+	  */
+	Matrix4 invert();
+
+	/**
+	  * Destructor.
+	  *
+	  * Frees any memory consumed by this Matrix4 instance.
+	  */
+	~Matrix4();
+};
+
+/**
+  * Multiplies the transpose of this matrix with the given matrix (if possible).
+  *
+  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+  *
+  * @code
+  * Matrix result = matrixA.multiplyT(matrixB);
+  * @endcode
+  */
+inline Matrix4 Matrix4::multiplyT(Matrix4 &matrix)
+{
+    return multiply(matrix, true);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/MicroBitCoordinateSystem.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,67 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_COORDINATE_SYSTEM_H
+#define MICROBIT_COORDINATE_SYSTEM_H
+#include "MicroBitConfig.h"
+
+/**
+  * Co-ordinate systems that can be used.
+  * RAW: Unaltered data. Data will be returned directly from the accelerometer.
+  *
+  * SIMPLE_CARTESIAN: Data will be returned based on an easy to understand alignment, consistent with the cartesian system taught in schools.
+  * When held upright, facing the user:
+  *
+  *                            /
+  *    +--------------------+ z
+  *    |                    |
+  *    |       .....        |
+  *    | *     .....      * |
+  * ^  |       .....        |
+  * |  |                    |
+  * y  +--------------------+  x-->
+  *
+  *
+  * NORTH_EAST_DOWN: Data will be returned based on the industry convention of the North East Down (NED) system.
+  * When held upright, facing the user:
+  *
+  *                            z
+  *    +--------------------+ /
+  *    |                    |
+  *    |       .....        |
+  *    | *     .....      * |
+  * ^  |       .....        |
+  * |  |                    |
+  * x  +--------------------+  y-->
+  *
+  */
+enum MicroBitCoordinateSystem
+{
+    RAW,
+    SIMPLE_CARTESIAN,
+    NORTH_EAST_DOWN
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/MicroBitEvent.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,106 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_EVENT_H
+#define MICROBIT_EVENT_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+
+// Wildcard event codes
+#define MICROBIT_ID_ANY         0
+#define MICROBIT_EVT_ANY        0
+
+enum MicroBitEventLaunchMode
+{
+    CREATE_ONLY,
+    CREATE_AND_FIRE
+};
+
+#define MICROBIT_EVENT_DEFAULT_LAUNCH_MODE     CREATE_AND_FIRE
+
+/**
+  * Class definition for a MicroBitEvent
+  *
+  * It represents a common event that is generated by the various components on the micro:bit.
+  */
+class MicroBitEvent
+{
+    public:
+
+    uint16_t source;         // ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
+    uint16_t value;          // Component specific code indicating the cause of the event.
+    uint64_t timestamp;      // Time at which the event was generated. us since power on.
+
+    /**
+      * Constructor.
+      *
+      * @param src The id of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
+      *
+      * @param value A component specific code indicating the cause of the event.
+      *
+      * @param mode Optional definition of how the event should be processed after construction (if at all):
+      *                 CREATE_ONLY: MicroBitEvent is initialised, and no further processing takes place.
+      *                 CREATE_AND_FIRE: MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).
+      *
+      * @code
+      * // Create and launch an event using the default configuration
+      * MicrobitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK);
+      *
+      * // Create an event only, do not fire onto an EventModel.
+      * MicrobitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK,CREATE_AND_FIRE);
+      * @endcode
+      */
+    MicroBitEvent(uint16_t source, uint16_t value, MicroBitEventLaunchMode mode = MICROBIT_EVENT_DEFAULT_LAUNCH_MODE);
+
+    /**
+      * Default constructor - initialises all values, and sets timestamp to the current time.
+      */
+    MicroBitEvent();
+
+    /**
+      * Fires this MicroBitEvent onto the Default EventModel, or a custom one!
+      */
+    void fire();
+};
+
+/**
+  * Enclosing class to hold a chain of events.
+  */
+struct MicroBitEventQueueItem
+{
+    MicroBitEvent evt;
+    MicroBitEventQueueItem *next;
+
+    /**
+      * Constructor.
+      * Create a new MicroBitEventQueueItem.
+      *
+      * @param evt The event to be queued.
+      */
+    MicroBitEventQueueItem(MicroBitEvent evt);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/MicroBitImage.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,480 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_IMAGE_H
+#define MICROBIT_IMAGE_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "ManagedString.h"
+#include "RefCounted.h"
+
+struct ImageData : RefCounted
+{
+    uint16_t width;     // Width in pixels
+    uint16_t height;    // Height in pixels
+    uint8_t data[0];    // 2D array representing the bitmap image
+};
+
+/**
+  * Class definition for a MicroBitImage.
+  *
+  * An MicroBitImage is a simple bitmap representation of an image.
+  * n.b. This is a mutable, managed type.
+  */
+class MicroBitImage
+{
+    ImageData *ptr;     // Pointer to payload data
+
+
+    /**
+      * Internal constructor which provides sanity checking and initialises class properties.
+      *
+      * @param x the width of the image
+      *
+      * @param y the height of the image
+      *
+      * @param bitmap an array of integers that make up an image.
+      */
+    void init(const int16_t x, const int16_t y, const uint8_t *bitmap);
+
+    /**
+      * Internal constructor which defaults to the Empty Image instance variable
+      */
+    void init_empty();
+
+    public:
+    static MicroBitImage EmptyImage;    // Shared representation of a null image.
+
+    /**
+      * Get current ptr, do not decr() it, and set the current instance to empty image.
+      *
+      * This is to be used by specialized runtimes which pass ImageData around.
+      */
+    ImageData *leakData();
+
+    /**
+      * Return a 2D array representing the bitmap image.
+      */
+    uint8_t *getBitmap()
+    {
+        return ptr->data;
+    }
+
+    /**
+      * Constructor.
+      * Create an image from a specially prepared constant array, with no copying. Will call ptr->incr().
+      *
+      * @param ptr The literal - first two bytes should be 0xff, then width, 0, height, 0, and the bitmap. Width and height are 16 bit. The literal has to be 4-byte aligned.
+      *
+      * @code
+      * static const uint8_t heart[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 10, 0, 5, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i((ImageData*)(void*)heart);
+      * @endcode
+      */
+    MicroBitImage(ImageData *ptr);
+
+    /**
+      * Default Constructor.
+      * Creates a new reference to the empty MicroBitImage bitmap
+      *
+      * @code
+      * MicroBitImage i(); //an empty image instance
+      * @endcode
+      */
+    MicroBitImage();
+
+
+    /**
+      * Copy Constructor.
+      * Add ourselves as a reference to an existing MicroBitImage.
+      *
+      * @param image The MicroBitImage to reference.
+      *
+      * @code
+      * MicroBitImage i("0,1,0,1,0\n");
+      * MicroBitImage i2(i); //points to i
+      * @endcode
+      */
+    MicroBitImage(const MicroBitImage &image);
+
+    /**
+      * Constructor.
+      * Create a blank bitmap representation of a given size.
+      *
+      * @param s A text based representation of the image given whitespace delimited numeric values.
+      *
+      * @code
+      * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+      * @endcode
+      */
+    explicit MicroBitImage(const char *s);
+
+    /**
+      * Constructor.
+      * Create a blank bitmap representation of a given size.
+      *
+      * @param x the width of the image.
+      *
+      * @param y the height of the image.
+      *
+      * Bitmap buffer is linear, with 8 bits per pixel, row by row,
+      * top to bottom with no word alignment. Stride is therefore the image width in pixels.
+      * in where w and h are width and height respectively, the layout is therefore:
+      *
+      * |[0,0]...[w,o][1,0]...[w,1]  ...  [[w,h]
+      *
+      * A copy of the image is made in RAM, as images are mutable.
+      */
+    MicroBitImage(const int16_t x, const int16_t y);
+
+    /**
+      * Constructor.
+      * Create a bitmap representation of a given size, based on a given buffer.
+      *
+      * @param x the width of the image.
+      *
+      * @param y the height of the image.
+      *
+      * @param bitmap a 2D array representing the image.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * @endcode
+      */
+    MicroBitImage(const int16_t x, const int16_t y, const uint8_t *bitmap);
+
+    /**
+      * Destructor.
+      *
+      * Removes buffer resources held by the instance.
+      */
+    ~MicroBitImage();
+
+    /**
+      * Copy assign operation.
+      *
+      * Called when one MicroBitImage is assigned the value of another using the '=' operator.
+      *
+      * Decrement our reference count and free up the buffer as necessary.
+      *
+      * Then, update our buffer to refer to that of the supplied MicroBitImage,
+      * and increase its reference count.
+      *
+      * @param s The MicroBitImage to reference.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * MicroBitImage i1();
+      * i1 = i; // i1 now references i
+      * @endcode
+      */
+    MicroBitImage& operator = (const MicroBitImage& i);
+
+
+    /**
+      * Equality operation.
+      *
+      * Called when one MicroBitImage is tested to be equal to another using the '==' operator.
+      *
+      * @param i The MicroBitImage to test ourselves against.
+      *
+      * @return true if this MicroBitImage is identical to the one supplied, false otherwise.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * MicroBitImage i();
+      * MicroBitImage i1();
+      *
+      * if(i == i1) //will be true
+      *     display.scroll("true");
+      * @endcode
+      */
+    bool operator== (const MicroBitImage& i);
+
+    /**
+      * Resets all pixels in this image to 0.
+      *
+      * @code
+      * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+      * i.clear();
+      * @endcode
+      */
+    void clear();
+
+    /**
+      * Sets the pixel at the given co-ordinates to a given value.
+      *
+      * @param x The co-ordinate of the pixel to change.
+      *
+      * @param y The co-ordinate of the pixel to change.
+      *
+      * @param value The new value of the pixel (the brightness level 0-255)
+      *
+      * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+      * i.setPixelValue(0,0,255);
+      * @endcode
+      *
+      * @note all coordinates originate from the top left of an image.
+      */
+    int setPixelValue(int16_t x , int16_t y, uint8_t value);
+
+    /**
+      * Retrieves the value of a given pixel.
+      *
+      * @param x The x co-ordinate of the pixel to read. Must be within the dimensions of the image.
+      *
+      * @param y The y co-ordinate of the pixel to read. Must be within the dimensions of the image.
+      *
+      * @return The value assigned to the given pixel location (the brightness level 0-255), or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+      * i.getPixelValue(0,0); //should be 0;
+      * @endcode
+      */
+    int getPixelValue(int16_t x , int16_t y);
+
+    /**
+      * Replaces the content of this image with that of a given 2D array representing
+      * the image.
+      *
+      * @param x the width of the image. Must be within the dimensions of the image.
+      *
+      * @param y the width of the image. Must be within the dimensions of the image.
+      *
+      * @param bitmap a 2D array representing the image.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i();
+      * i.printImage(0,0,heart);
+      * @endcode
+      *
+      * @note all coordinates originate from the top left of an image.
+      */
+    int printImage(int16_t x, int16_t y, const uint8_t *bitmap);
+
+    /**
+      * Pastes a given bitmap at the given co-ordinates.
+      *
+      * Any pixels in the relevant area of this image are replaced.
+      *
+      * @param image The MicroBitImage to paste.
+      *
+      * @param x The leftmost X co-ordinate in this image where the given image should be pasted. Defaults to 0.
+      *
+      * @param y The uppermost Y co-ordinate in this image where the given image should be pasted. Defaults to 0.
+      *
+      * @param alpha set to 1 if transparency clear pixels in given image should be treated as transparent. Set to 0 otherwise.  Defaults to 0.
+      *
+      * @return The number of pixels written.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart); // a big heart
+      * i.paste(i, -5, 0); // a small heart
+      * @endcode
+      */
+    int paste(const MicroBitImage &image, int16_t x = 0, int16_t y = 0, uint8_t alpha = 0);
+
+     /**
+       * Prints a character to the display at the given location
+       *
+       * @param c The character to display.
+       *
+       * @param x The x co-ordinate of on the image to place the top left of the character. Defaults to 0.
+       *
+       * @param y The y co-ordinate of on the image to place the top left of the character. Defaults to 0.
+       *
+       * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+       *
+       * @code
+       * MicroBitImage i(5,5);
+       * i.print('a');
+       * @endcode
+       */
+    int print(char c, int16_t x = 0, int16_t y = 0);
+
+    /**
+      * Shifts the pixels in this Image a given number of pixels to the left.
+      *
+      * @param n The number of pixels to shift.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart); // a big heart
+      * i.shiftLeft(5); // a small heart
+      * @endcode
+      */
+    int shiftLeft(int16_t n);
+
+    /**
+      * Shifts the pixels in this Image a given number of pixels to the right.
+      *
+      * @param n The number of pixels to shift.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart); // a big heart
+      * i.shiftLeft(5); // a small heart
+      * i.shiftRight(5); // a big heart
+      * @endcode
+      */
+    int shiftRight(int16_t n);
+
+    /**
+      * Shifts the pixels in this Image a given number of pixels to upward.
+      *
+      * @param n The number of pixels to shift.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.shiftUp(1);
+      * @endcode
+      */
+    int shiftUp(int16_t n);
+
+    /**
+      * Shifts the pixels in this Image a given number of pixels to downward.
+      *
+      * @param n The number of pixels to shift.
+      *
+      * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.shiftDown(1);
+      * @endcode
+      */
+    int shiftDown(int16_t n);
+
+    /**
+      * Gets the width of this image.
+      *
+      * @return The width of this image.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.getWidth(); // equals 10...
+      * @endcode
+      */
+    int getWidth() const
+    {
+        return ptr->width;
+    }
+
+    /**
+      * Gets the height of this image.
+      *
+      * @return The height of this image.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.getHeight(); // equals 5...
+      * @endcode
+      */
+    int getHeight() const
+    {
+        return ptr->height;
+    }
+
+    /**
+      * Gets number of bytes in the bitmap, ie., width * height.
+      *
+      * @return The size of the bitmap.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.getSize(); // equals 50...
+      * @endcode
+      */
+    int getSize() const
+    {
+        return ptr->width * ptr->height;
+    }
+
+    /**
+      * Converts the bitmap to a csv ManagedString.
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * uBit.serial.printString(i.toString()); // "0,1,0,1,0,0,0,0,0,0\n..."
+      * @endcode
+      */
+    ManagedString toString();
+
+    /**
+      * Crops the image to the given dimensions.
+      *
+      * @param startx the location to start the crop in the x-axis
+      *
+      * @param starty the location to start the crop in the y-axis
+      *
+      * @param width the width of the desired cropped region
+      *
+      * @param height the height of the desired cropped region
+      *
+      * @code
+      * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+      * MicroBitImage i(10,5,heart);
+      * i.crop(0,0,2,2).toString() // "0,1\n1,1\n"
+      * @endcode
+      */
+    MicroBitImage crop(int startx, int starty, int finx, int finy);
+
+    /**
+      * Check if image is read-only (i.e., residing in flash).
+      */
+    bool isReadOnly();
+
+    /**
+      * Create a copy of the image bitmap. Used particularly, when isReadOnly() is true.
+      *
+      * @return an instance of MicroBitImage which can be modified independently of the current instance
+      */
+    MicroBitImage clone();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/PacketBuffer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,269 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MICROBIT_PACKET_BUFFER_H
+#define MICROBIT_PACKET_BUFFER_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "RefCounted.h"
+
+struct PacketData : RefCounted
+{
+    uint16_t        rssi;               // The radio signal strength this packet was received.
+    uint8_t         length;             // The length of the payload in bytes
+    uint8_t         payload[0];         // User / higher layer protocol data
+};
+
+/**
+  * Class definition for a PacketBuffer.
+  * A PacketBuffer holds a series of bytes that can be sent or received from the MicroBitRadio channel.
+  *
+  * @note This is a mutable, managed type.
+  */
+class PacketBuffer
+{
+    PacketData      *ptr;     // Pointer to payload data
+
+    public:
+
+    /**
+      * Provide a pointer to a memory location containing the packet data.
+      *
+      * @return The contents of this packet, as an array of bytes.
+      */
+    uint8_t *getBytes();
+
+    /**
+      * Default Constructor.
+      * Creates an empty Packet Buffer.
+      *
+      * @code
+      * PacketBuffer p();
+      * @endcode
+      */
+    PacketBuffer();
+
+    /**
+      * Constructor.
+      * Creates a new PacketBuffer of the given size.
+      *
+      * @param length The length of the buffer to create.
+      *
+      * @code
+      * PacketBuffer p(16);         // Creates a PacketBuffer 16 bytes long.
+      * @endcode
+      */
+    PacketBuffer(int length);
+
+    /**
+      * Constructor.
+      * Creates an empty Packet Buffer of the given size,
+      * and fills it with the data provided.
+      *
+      * @param data The data with which to fill the buffer.
+      *
+      * @param length The length of the buffer to create.
+      *
+      * @param rssi The radio signal strength at the time this packet was recieved. Defaults to 0.
+      *
+      * @code
+      * uint8_t buf = {13,5,2};
+      * PacketBuffer p(buf, 3);         // Creates a PacketBuffer 3 bytes long.
+      * @endcode
+      */
+    PacketBuffer(uint8_t *data, int length, int rssi = 0);
+
+    /**
+      * Copy Constructor.
+      * Add ourselves as a reference to an existing PacketBuffer.
+      *
+      * @param buffer The PacketBuffer to reference.
+      *
+      * @code
+      * PacketBuffer p();
+      * PacketBuffer p2(p); // Refers to the same packet as p.
+      * @endcode
+      */
+    PacketBuffer(const PacketBuffer &buffer);
+
+    /**
+      * Internal constructor-initialiser.
+      *
+      * @param data The data with which to fill the buffer.
+      *
+      * @param length The length of the buffer to create.
+      *
+      * @param rssi The radio signal strength at the time this packet was recieved.
+      */
+    void init(uint8_t *data, int length, int rssi);
+
+    /**
+      * Destructor.
+      *
+      * Removes buffer resources held by the instance.
+      */
+    ~PacketBuffer();
+
+    /**
+      * Copy assign operation.
+      *
+      * Called when one PacketBuffer is assigned the value of another using the '=' operator.
+      *
+      * Decrements our reference count and free up the buffer as necessary.
+      *
+      * Then, update our buffer to refer to that of the supplied PacketBuffer,
+      * and increase its reference count.
+      *
+      * @param p The PacketBuffer to reference.
+      *
+      * @code
+      * uint8_t buf = {13,5,2};
+      * PacketBuffer p1(16);
+      * PacketBuffer p2(buf, 3);
+      *
+      * p1 = p2;
+      * @endcode
+      */
+    PacketBuffer& operator = (const PacketBuffer& p);
+
+    /**
+      * Array access operation (read).
+      *
+      * Called when a PacketBuffer is dereferenced with a [] operation.
+      *
+      * Transparently map this through to the underlying payload for elegance of programming.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * uint8_t data = p1[0];
+      * @endcode
+      */
+    uint8_t operator [] (int i) const;
+
+    /**
+      * Array access operation (modify).
+      *
+      * Called when a PacketBuffer is dereferenced with a [] operation.
+      *
+      * Transparently map this through to the underlying payload for elegance of programming.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1[0] = 42;
+      * @endcode
+      */
+    uint8_t& operator [] (int i);
+
+    /**
+      * Equality operation.
+      *
+      * Called when one PacketBuffer is tested to be equal to another using the '==' operator.
+      *
+      * @param p The PacketBuffer to test ourselves against.
+      *
+      * @return true if this PacketBuffer is identical to the one supplied, false otherwise.
+      *
+      * @code
+      * MicroBitDisplay display;
+      * uint8_t buf = {13,5,2};
+      * PacketBuffer p1();
+      * PacketBuffer p2();
+      *
+      * if(p1 == p2)                    // will be true
+      *     display.scroll("same!");
+      * @endcode
+      */
+    bool operator== (const PacketBuffer& p);
+
+    /**
+      * Sets the byte at the given index to value provided.
+      *
+      * @param position The index of the byte to change.
+      *
+      * @param value The new value of the byte (0-255).
+      *
+      * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1.setByte(0,255);              // Sets the first byte in the buffer to the value 255.
+      * @endcode
+      */
+    int setByte(int position, uint8_t value);
+
+    /**
+      * Determines the value of the given byte in the packet.
+      *
+      * @param position The index of the byte to read.
+      *
+      * @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1.setByte(0,255);              // Sets the first byte in the buffer to the value 255.
+      * p1.getByte(0);                  // Returns 255.
+      * @endcode
+      */
+    int getByte(int position);
+
+    /**
+      * Gets number of bytes in this buffer
+      *
+      * @return The size of the buffer in bytes.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1.length(); // Returns 16.
+      * @endcode
+      */
+    int length();
+
+    /**
+      * Retrieves the received signal strength of this packet.
+      *
+      * @return The signal strength of the radio when this packet was received, in -dbM.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1.getRSSI();                 // Returns the received signal strength.
+      * @endcode
+      */
+    int getRSSI();
+
+    /**
+      * Sets the received signal strength of this packet.
+      *
+      * @code
+      * PacketBuffer p1(16);
+      * p1.setRSSI(37);
+      * @endcode
+      */
+    void setRSSI(uint8_t rssi);
+
+    static PacketBuffer EmptyPacket;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/inc/types/RefCounted.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,72 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef REF_COUNTED_H
+#define REF_COUNTED_H
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "MicroBitDevice.h"
+
+/**
+  * Base class for payload for ref-counted objects. Used by ManagedString and MicroBitImage.
+  * There is no constructor, as this struct is typically malloc()ed.
+  */
+struct RefCounted
+{
+public:
+
+    /**
+      * The high 15 bits hold the number of outstanding references. The lowest bit is always 1
+      * to make sure it doesn't look like vtable.
+      * Should never be even or one (object should be deleted then).
+      * When it's set to 0xffff, it means the object sits in flash and should not be counted.
+      */
+    uint16_t refCount;
+
+    /**
+      * Increment reference count.
+      */
+    void incr();
+
+    /**
+      * Decrement reference count.
+      */
+    void decr();
+
+    /**
+      * Initializes for one outstanding reference.
+      */
+    void init();
+
+    /**
+      * Checks if the object resides in flash memory.
+      *
+      * @return true if the object resides in flash memory, false otherwise.
+      */
+    bool isReadOnly();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/AnalogIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,103 @@
+/* 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_ANALOGIN_H
+#define MBED_ANALOGIN_H
+
+#include "platform.h"
+
+#if DEVICE_ANALOGIN
+
+#include "analogin_api.h"
+
+namespace mbed {
+
+/** An analog input, used for reading the voltage on a pin
+ *
+ * Example:
+ * @code
+ * // Print messages when the AnalogIn is greater than 50%
+ *
+ * #include "mbed.h"
+ *
+ * AnalogIn temperature(p20);
+ *
+ * int main() {
+ *     while(1) {
+ *         if(temperature > 0.5) {
+ *             printf("Too hot! (%f)", temperature.read());
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class AnalogIn {
+
+public:
+
+    /** Create an AnalogIn, connected to the specified pin
+     *
+     * @param pin AnalogIn pin to connect to
+     * @param name (optional) A string to identify the object
+     */
+    AnalogIn(PinName pin) {
+        analogin_init(&_adc, pin);
+    }
+
+    /** Read the input voltage, represented as a float in the range [0.0, 1.0]
+     *
+     * @returns A floating-point value representing the current input voltage, measured as a percentage
+     */
+    float read() {
+        return analogin_read(&_adc);
+    }
+
+    /** Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
+     *
+     * @returns
+     *   16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
+     */
+    unsigned short read_u16() {
+        return analogin_read_u16(&_adc);
+    }
+
+#ifdef MBED_OPERATORS
+    /** An operator shorthand for read()
+     *
+     * The float() operator can be used as a shorthand for read() to simplify common code sequences
+     *
+     * Example:
+     * @code
+     * float x = volume.read();
+     * float x = volume;
+     *
+     * if(volume.read() > 0.25) { ... }
+     * if(volume > 0.25) { ... }
+     * @endcode
+     */
+    operator float() {
+        return read();
+    }
+#endif
+
+protected:
+    analogin_t _adc;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/AnalogOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,121 @@
+/* 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_ANALOGOUT_H
+#define MBED_ANALOGOUT_H
+
+#include "platform.h"
+
+#if DEVICE_ANALOGOUT
+
+#include "analogout_api.h"
+
+namespace mbed {
+
+/** An analog output, used for setting the voltage on a pin
+ *
+ * Example:
+ * @code
+ * // Make a sawtooth output
+ *
+ * #include "mbed.h"
+ *
+ * AnalogOut tri(p18);
+ * int main() {
+ *     while(1) {
+ *         tri = tri + 0.01;
+ *         wait_us(1);
+ *         if(tri == 1) {
+ *             tri = 0;
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class AnalogOut {
+
+public:
+
+    /** Create an AnalogOut connected to the specified pin
+     *
+     *  @param AnalogOut pin to connect to (18)
+     */
+    AnalogOut(PinName pin) {
+        analogout_init(&_dac, pin);
+    }
+
+    /** Set the output voltage, specified as a percentage (float)
+     *
+     *  @param value A floating-point value representing the output voltage,
+     *    specified as a percentage. The value should lie between
+     *    0.0f (representing 0v / 0%) and 1.0f (representing 3.3v / 100%).
+     *    Values outside this range will be saturated to 0.0f or 1.0f.
+     */
+    void write(float value) {
+        analogout_write(&_dac, value);
+    }
+
+    /** Set the output voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
+     *
+     *  @param value 16-bit unsigned short representing the output voltage,
+     *            normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v)
+     */
+    void write_u16(unsigned short value) {
+        analogout_write_u16(&_dac, value);
+    }
+
+    /** Return the current output voltage setting, measured as a percentage (float)
+     *
+     *  @returns
+     *    A floating-point value representing the current voltage being output on the pin,
+     *    measured as a percentage. The returned value will lie between
+     *    0.0f (representing 0v / 0%) and 1.0f (representing 3.3v / 100%).
+     *
+     *  @note
+     *    This value may not match exactly the value set by a previous write().
+     */
+    float read() {
+        return analogout_read(&_dac);
+    }
+
+#ifdef MBED_OPERATORS
+    /** An operator shorthand for write()
+     */
+    AnalogOut& operator= (float percent) {
+        write(percent);
+        return *this;
+    }
+
+    AnalogOut& operator= (AnalogOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** An operator shorthand for read()
+     */
+    operator float() {
+        return read();
+    }
+#endif
+
+protected:
+    dac_t _dac;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/BusIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,98 @@
+/* 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_BUSIN_H
+#define MBED_BUSIN_H
+
+#include "platform.h"
+#include "DigitalIn.h"
+
+namespace mbed {
+
+/** A digital input bus, used for reading the state of a collection of pins
+ */
+class BusIn {
+
+public:
+    /* Group: Configuration Methods */
+
+    /** Create an BusIn, connected to the specified pins
+     *
+     * @param <n> DigitalIn pin to connect to bus bit <n> (p5-p30, NC)
+     *
+     * @note
+     *  It is only required to specify as many pin variables as is required
+     *  for the bus; the rest will default to NC (not connected)
+     */
+    BusIn(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
+          PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
+          PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
+          PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
+
+    BusIn(PinName pins[16]);
+
+    virtual ~BusIn();
+
+    /** Read the value of the input bus
+     *
+     *  @returns
+     *   An integer with each bit corresponding to the value read from the associated DigitalIn pin
+     */
+    int read();
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone
+     */
+    void mode(PinMode pull);
+
+    /** Binary mask of bus pins connected to actual pins (not NC pins)
+     *  If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
+     *
+     *  @returns
+     *    Binary mask of connected pins
+     */
+    int mask() {
+        return _nc_mask;
+    }
+
+#ifdef MBED_OPERATORS
+    /** A shorthand for read()
+     */
+    operator int();
+
+    /** Access to particular bit in random-iterator fashion
+     */
+    DigitalIn & operator[] (int index);
+#endif
+
+protected:
+    DigitalIn* _pin[16];
+
+    /** Mask of bus's NC pins
+     * If bit[n] is set to 1 - pin is connected
+     * if bit[n] is cleared - pin is not connected (NC)
+     */
+    int _nc_mask;
+
+    /* disallow copy constructor and assignment operators */
+private:
+    BusIn(const BusIn&);
+    BusIn & operator = (const BusIn&);
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/BusInOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,117 @@
+/* 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_BUSINOUT_H
+#define MBED_BUSINOUT_H
+
+#include "DigitalInOut.h"
+
+namespace mbed {
+
+/** A digital input output bus, used for setting the state of a collection of pins
+ */
+class BusInOut {
+
+public:
+
+    /** Create an BusInOut, connected to the specified pins
+     *
+     *  @param p<n> DigitalInOut pin to connect to bus bit p<n> (p5-p30, NC)
+     *
+     *  @note
+     *  It is only required to specify as many pin variables as is required
+     *  for the bus; the rest will default to NC (not connected)
+     */
+    BusInOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
+             PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
+             PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
+             PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
+
+    BusInOut(PinName pins[16]);
+
+    virtual ~BusInOut();
+
+    /* Group: Access Methods */
+
+    /** Write the value to the output bus
+     *
+     *  @param value An integer specifying a bit to write for every corresponding DigitalInOut pin
+     */
+    void write(int value);
+
+    /** Read the value currently output on the bus
+     *
+     *  @returns
+     *    An integer with each bit corresponding to associated DigitalInOut pin setting
+     */
+    int read();
+
+    /** Set as an output
+     */
+    void output();
+
+    /** Set as an input
+     */
+    void input();
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone
+     */
+    void mode(PinMode pull);
+
+    /** Binary mask of bus pins connected to actual pins (not NC pins)
+     *  If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
+     *
+     *  @returns
+     *    Binary mask of connected pins
+     */
+    int mask() {
+        return _nc_mask;
+    }
+
+#ifdef MBED_OPERATORS
+     /** A shorthand for write()
+     */
+    BusInOut& operator= (int v);
+    BusInOut& operator= (BusInOut& rhs);
+
+    /** Access to particular bit in random-iterator fashion
+    */
+    DigitalInOut& operator[] (int index);
+
+    /** A shorthand for read()
+     */
+    operator int();
+#endif
+
+protected:
+    DigitalInOut* _pin[16];
+
+    /** Mask of bus's NC pins
+     * If bit[n] is set to 1 - pin is connected
+     * if bit[n] is cleared - pin is not connected (NC)
+     */
+    int _nc_mask;
+
+    /* disallow copy constructor and assignment operators */
+private:
+    BusInOut(const BusInOut&);
+    BusInOut & operator = (const BusInOut&);
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/BusOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,101 @@
+/* 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_BUSOUT_H
+#define MBED_BUSOUT_H
+
+#include "DigitalOut.h"
+
+namespace mbed {
+
+/** A digital output bus, used for setting the state of a collection of pins
+ */
+class BusOut {
+
+public:
+
+    /** Create an BusOut, connected to the specified pins
+     *
+     *  @param p<n> DigitalOut pin to connect to bus bit <n> (p5-p30, NC)
+     *
+     *  @note
+     *  It is only required to specify as many pin variables as is required
+     *  for the bus; the rest will default to NC (not connected)
+     */
+    BusOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
+           PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
+           PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
+           PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
+
+    BusOut(PinName pins[16]);
+
+    virtual ~BusOut();
+
+    /** Write the value to the output bus
+     *
+     *  @param value An integer specifying a bit to write for every corresponding DigitalOut pin
+     */
+    void write(int value);
+
+    /** Read the value currently output on the bus
+     *
+     *  @returns
+     *    An integer with each bit corresponding to associated DigitalOut pin setting
+     */
+    int read();
+
+    /** Binary mask of bus pins connected to actual pins (not NC pins)
+     *  If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
+     *
+     *  @returns
+     *    Binary mask of connected pins
+     */
+    int mask() {
+        return _nc_mask;
+    }
+
+#ifdef MBED_OPERATORS
+    /** A shorthand for write()
+     */
+    BusOut& operator= (int v);
+    BusOut& operator= (BusOut& rhs);
+
+    /** Access to particular bit in random-iterator fashion
+     */
+    DigitalOut& operator[] (int index);
+
+    /** A shorthand for read()
+     */
+    operator int();
+#endif
+
+protected:
+    DigitalOut* _pin[16];
+
+    /** Mask of bus's NC pins
+     * If bit[n] is set to 1 - pin is connected
+     * if bit[n] is cleared - pin is not connected (NC)
+     */
+    int _nc_mask;
+
+   /* disallow copy constructor and assignment operators */
+private:
+    BusOut(const BusOut&);
+    BusOut & operator = (const BusOut&);
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/CAN.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,243 @@
+/* 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_CAN_H
+#define MBED_CAN_H
+
+#include "platform.h"
+
+#if DEVICE_CAN
+
+#include "can_api.h"
+#include "can_helper.h"
+#include "FunctionPointer.h"
+
+namespace mbed {
+
+/** CANMessage class
+ */
+class CANMessage : public CAN_Message {
+
+public:
+    /** Creates empty CAN message.
+     */
+    CANMessage() : CAN_Message() {
+        len    = 8;
+        type   = CANData;
+        format = CANStandard;
+        id     = 0;
+        memset(data, 0, 8);
+    }
+
+    /** Creates CAN message with specific content.
+     */
+    CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
+      len    = _len & 0xF;
+      type   = _type;
+      format = _format;
+      id     = _id;
+      memcpy(data, _data, _len);
+    }
+
+    /** Creates CAN remote message.
+     */
+    CANMessage(int _id, CANFormat _format = CANStandard) {
+      len    = 0;
+      type   = CANRemote;
+      format = _format;
+      id     = _id;
+      memset(data, 0, 8);
+    }
+};
+
+/** A can bus client, used for communicating with can devices
+ */
+class CAN {
+
+public:
+    /** Creates an CAN interface connected to specific pins.
+     *
+     *  @param rd read from transmitter
+     *  @param td transmit to transmitter
+     *
+     * Example:
+     * @code
+     * #include "mbed.h"
+     *
+     * Ticker ticker;
+     * DigitalOut led1(LED1);
+     * DigitalOut led2(LED2);
+     * CAN can1(p9, p10);
+     * CAN can2(p30, p29);
+     *
+     * char counter = 0;
+     *
+     * void send() {
+     *     if(can1.write(CANMessage(1337, &counter, 1))) {
+     *         printf("Message sent: %d\n", counter);
+     *         counter++;
+     *     }
+     *     led1 = !led1;
+     * }
+     *
+     * int main() {
+     *     ticker.attach(&send, 1);
+     *    CANMessage msg;
+     *     while(1) {
+     *         if(can2.read(msg)) {
+     *             printf("Message received: %d\n\n", msg.data[0]);
+     *             led2 = !led2;
+     *         }
+     *         wait(0.2);
+     *     }
+     * }
+     * @endcode
+     */
+    CAN(PinName rd, PinName td);
+    virtual ~CAN();
+
+    /** Set the frequency of the CAN interface
+     *
+     *  @param hz The bus frequency in hertz
+     *
+     *  @returns
+     *    1 if successful,
+     *    0 otherwise
+     */
+    int frequency(int hz);
+
+    /** Write a CANMessage to the bus.
+     *
+     *  @param msg The CANMessage to write.
+     *
+     *  @returns
+     *    0 if write failed,
+     *    1 if write was successful
+     */
+    int write(CANMessage msg);
+
+    /** Read a CANMessage from the bus.
+     *
+     *  @param msg A CANMessage to read to.
+     *  @param handle message filter handle (0 for any message)
+     *
+     *  @returns
+     *    0 if no message arrived,
+     *    1 if message arrived
+     */
+    int read(CANMessage &msg, int handle = 0);
+
+    /** Reset CAN interface.
+     *
+     * To use after error overflow.
+     */
+    void reset();
+
+    /** Puts or removes the CAN interface into silent monitoring mode
+     *
+     *  @param silent boolean indicating whether to go into silent mode or not
+     */
+    void monitor(bool silent);
+
+    enum Mode {
+        Reset = 0,
+        Normal,
+        Silent,
+        LocalTest,
+        GlobalTest,
+        SilentTest
+    };
+
+    /** Change CAN operation to the specified mode
+     *
+     *  @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
+     *
+     *  @returns
+     *    0 if mode change failed or unsupported,
+     *    1 if mode change was successful
+     */
+    int mode(Mode mode);
+
+    /** Filter out incomming messages
+     *
+     *  @param id the id to filter on
+     *  @param mask the mask applied to the id
+     *  @param format format to filter on (Default CANAny)
+     *  @param handle message filter handle (Optional)
+     *
+     *  @returns
+     *    0 if filter change failed or unsupported,
+     *    new filter handle if successful
+     */
+    int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
+
+    /** Returns number of read errors to detect read overflow errors.
+     */
+    unsigned char rderror();
+
+    /** Returns number of write errors to detect write overflow errors.
+     */
+    unsigned char tderror();
+
+    enum IrqType {
+        RxIrq = 0,
+        TxIrq,
+        EwIrq,
+        DoIrq,
+        WuIrq,
+        EpIrq,
+        AlIrq,
+        BeIrq,
+        IdIrq
+    };
+
+    /** Attach a function to call whenever a CAN frame received interrupt is
+     *  generated.
+     *
+     *  @param fptr A pointer to a void function, or 0 to set as none
+     *  @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
+     */
+    void attach(void (*fptr)(void), IrqType type=RxIrq);
+
+   /** Attach a member function to call whenever a CAN frame received interrupt
+    *  is generated.
+    *
+    *  @param tptr pointer to the object to call the member function on
+    *  @param mptr pointer to the member function to be called
+    *  @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
+    */
+   template<typename T>
+   void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
+        if((mptr != NULL) && (tptr != NULL)) {
+            _irq[type].attach(tptr, mptr);
+            can_irq_set(&_can, (CanIrqType)type, 1);
+        }
+        else {
+            can_irq_set(&_can, (CanIrqType)type, 0);
+        }
+    }
+
+    static void _irq_handler(uint32_t id, CanIrqType type);
+
+protected:
+    can_t           _can;
+    FunctionPointer _irq[9];
+};
+
+} // namespace mbed
+
+#endif
+
+#endif    // MBED_CAN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/CThunk.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,202 @@
+/* General C++ Object Thunking class
+ *
+ * - allows direct callbacks to non-static C++ class functions
+ * - keeps track for the corresponding class instance
+ * - supports an optional context parameter for the called function
+ * - ideally suited for class object receiving interrupts (NVIC_SetVector)
+ *
+ * Copyright (c) 2014-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __CTHUNK_H__
+#define __CTHUNK_H__
+
+#define CTHUNK_ADDRESS 1
+
+#if defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__thumb2__)
+#define CTHUNK_VARIABLES volatile uint32_t code[1]
+/**
+* CTHUNK disassembly for Cortex-M3/M4 (thumb2):
+* * ldm.w pc,{r0,r1,r2,pc}
+*
+* This instruction loads the arguments for the static thunking function to r0-r2, and
+* branches to that function by loading its address into PC.
+*
+* This is safe for both regular calling and interrupt calling, since it only touches scratch registers
+* which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
+*/
+#define CTHUNK_ASSIGMENT m_thunk.code[0] = 0x8007E89F
+
+#elif defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0)
+/*
+* CTHUNK disassembly for Cortex M0 (thumb):
+* * push {r0,r1,r2,r3,r4,lr} save touched registers and return address
+* * movs r4,#4 set up address to load arguments from (immediately following this code block) (1)
+* * add r4,pc set up address to load arguments from (immediately following this code block) (2)
+* * ldm r4!,{r0,r1,r2,r3} load arguments for static thunk function
+* * blx r3 call static thunk function
+* * pop {r0,r1,r2,r3,r4,pc} restore scratch registers and return from function
+*/
+#define CTHUNK_VARIABLES volatile uint32_t code[3]
+#define CTHUNK_ASSIGMENT do {                              \
+                             m_thunk.code[0] = 0x2404B51F; \
+                             m_thunk.code[1] = 0xCC0F447C; \
+                             m_thunk.code[2] = 0xBD1F4798; \
+                         } while (0)
+
+#else
+#error "Target is not currently suported."
+#endif
+
+/* IRQ/Exception compatible thunk entry function */
+typedef void (*CThunkEntry)(void);
+
+template<class T>
+class CThunk
+{
+    public:
+        typedef void (T::*CCallbackSimple)(void);
+        typedef void (T::*CCallback)(void* context);
+
+        inline CThunk(T *instance)
+        {
+            init(instance, NULL, NULL);
+        }
+
+        inline CThunk(T *instance, CCallback callback)
+        {
+            init(instance, callback, NULL);
+        }
+
+        ~CThunk() {
+
+        }
+
+        inline CThunk(T *instance, CCallbackSimple callback)
+        {
+            init(instance, (CCallback)callback, NULL);
+        }
+
+        inline CThunk(T &instance, CCallback callback)
+        {
+            init(instance, callback, NULL);
+        }
+
+        inline CThunk(T &instance, CCallbackSimple callback)
+        {
+            init(instance, (CCallback)callback, NULL);
+        }
+
+        inline CThunk(T &instance, CCallback callback, void* context)
+        {
+            init(instance, callback, context);
+        }
+
+        inline void callback(CCallback callback)
+        {
+            m_callback = callback;
+        }
+
+        inline void callback(CCallbackSimple callback)
+        {
+            m_callback = (CCallback)callback;
+        }
+
+        inline void context(void* context)
+        {
+            m_thunk.context = (uint32_t)context;
+        }
+
+        inline void context(uint32_t context)
+        {
+            m_thunk.context = context;
+        }
+        
+        inline uint32_t entry(void)
+        {
+            return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
+        }
+
+        /* get thunk entry point for connecting rhunk to an IRQ table */
+        inline operator CThunkEntry(void)
+        {
+            return (CThunkEntry)entry();
+        }
+
+        /* get thunk entry point for connecting rhunk to an IRQ table */
+        inline operator uint32_t(void)
+        {
+            return entry();
+        }
+
+        /* simple test function */
+        inline void call(void)
+        {
+            (((CThunkEntry)(entry()))());
+        }
+
+    private:
+        T* m_instance;
+        volatile CCallback m_callback;
+
+// TODO: this needs proper fix, to refactor toolchain header file and all its use
+// PACKED there is not defined properly for IAR
+#if defined (__ICCARM__)
+        typedef __packed struct
+        {
+            CTHUNK_VARIABLES;
+            volatile uint32_t instance;
+            volatile uint32_t context;
+            volatile uint32_t callback;
+            volatile uint32_t trampoline;
+        }  CThunkTrampoline;
+#else
+        typedef struct
+        {
+            CTHUNK_VARIABLES;
+            volatile uint32_t instance;
+            volatile uint32_t context;
+            volatile uint32_t callback;
+            volatile uint32_t trampoline;
+        } __attribute__((__packed__)) CThunkTrampoline;
+#endif
+
+        static void trampoline(T* instance, void* context, CCallback* callback)
+        {
+            if(instance && *callback) {
+                (static_cast<T*>(instance)->**callback)(context);
+            }
+        }
+
+        volatile CThunkTrampoline m_thunk;
+
+        inline void init(T *instance, CCallback callback, void* context)
+        {
+            /* remember callback - need to add this level of redirection
+               as pointer size for member functions differs between platforms */
+            m_callback = callback;
+
+            /* populate thunking trampoline */
+            CTHUNK_ASSIGMENT;
+            m_thunk.context = (uint32_t)context;
+            m_thunk.instance = (uint32_t)instance;
+            m_thunk.callback = (uint32_t)&m_callback;
+            m_thunk.trampoline = (uint32_t)&trampoline;
+
+            __ISB();
+            __DSB();
+        }
+};
+
+#endif/*__CTHUNK_H__*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/CallChain.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,181 @@
+/* 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_CALLCHAIN_H
+#define MBED_CALLCHAIN_H
+
+#include "FunctionPointer.h"
+#include <string.h>
+
+namespace mbed {
+
+/** Group one or more functions in an instance of a CallChain, then call them in
+ * sequence using CallChain::call(). Used mostly by the interrupt chaining code,
+ * but can be used for other purposes.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * CallChain chain;
+ *
+ * void first(void) {
+ *     printf("'first' function.\n");
+ * }
+ *
+ * void second(void) {
+ *     printf("'second' function.\n");
+ * }
+ *
+ * class Test {
+ * public:
+ *     void f(void) {
+ *         printf("A::f (class member).\n");
+ *     }
+ * };
+ *
+ * int main() {
+ *     Test test;
+ *
+ *     chain.add(second);
+ *     chain.add_front(first);
+ *     chain.add(&test, &Test::f);
+ *     chain.call();
+ * }
+ * @endcode
+ */
+
+typedef FunctionPointer* pFunctionPointer_t;
+
+class CallChain {
+public:
+    /** Create an empty chain
+     *
+     *  @param size (optional) Initial size of the chain
+     */
+    CallChain(int size = 4);
+    virtual ~CallChain();
+
+    /** Add a function at the end of the chain
+     *
+     *  @param function A pointer to a void function
+     *
+     *  @returns
+     *  The function object created for 'function'
+     */
+    pFunctionPointer_t add(void (*function)(void));
+
+    /** Add a function at the end of the chain
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *
+     *  @returns
+     *  The function object created for 'tptr' and 'mptr'
+     */
+    template<typename T>
+    pFunctionPointer_t add(T *tptr, void (T::*mptr)(void)) {
+        return common_add(new FunctionPointer(tptr, mptr));
+    }
+
+    /** Add a function at the beginning of the chain
+     *
+     *  @param function A pointer to a void function
+     *
+     *  @returns
+     *  The function object created for 'function'
+     */
+    pFunctionPointer_t add_front(void (*function)(void));
+
+    /** Add a function at the beginning of the chain
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *
+     *  @returns
+     *  The function object created for 'tptr' and 'mptr'
+     */
+    template<typename T>
+    pFunctionPointer_t add_front(T *tptr, void (T::*mptr)(void)) {
+        return common_add_front(new FunctionPointer(tptr, mptr));
+    }
+
+    /** Get the number of functions in the chain
+     */
+    int size() const;
+
+    /** Get a function object from the chain
+     *
+     *  @param i function object index
+     *
+     *  @returns
+     *  The function object at position 'i' in the chain
+     */
+    pFunctionPointer_t get(int i) const;
+
+    /** Look for a function object in the call chain
+     *
+     *  @param f the function object to search
+     *
+     *  @returns
+     *  The index of the function object if found, -1 otherwise.
+     */
+    int find(pFunctionPointer_t f) const;
+
+    /** Clear the call chain (remove all functions in the chain).
+     */
+    void clear();
+
+    /** Remove a function object from the chain
+     *
+     *  @arg f the function object to remove
+     *
+     *  @returns
+     *  true if the function object was found and removed, false otherwise.
+     */
+    bool remove(pFunctionPointer_t f);
+
+    /** Call all the functions in the chain in sequence
+     */
+    void call();
+
+#ifdef MBED_OPERATORS
+    void operator ()(void) {
+        call();
+    }
+    pFunctionPointer_t operator [](int i) const {
+        return get(i);
+    }
+#endif
+
+private:
+    void _check_size();
+    pFunctionPointer_t common_add(pFunctionPointer_t pf);
+    pFunctionPointer_t common_add_front(pFunctionPointer_t pf);
+
+    pFunctionPointer_t* _chain;
+    int _size;
+    int _elements;
+
+    /* disallow copy constructor and assignment operators */
+private:
+    CallChain(const CallChain&);
+    CallChain & operator = (const CallChain&);
+};
+
+} // namespace mbed
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/CircularBuffer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,98 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_CIRCULARBUFFER_H
+#define MBED_CIRCULARBUFFER_H
+
+namespace mbed {
+
+/** Templated Circular buffer class
+ */
+template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
+class CircularBuffer {
+public:
+    CircularBuffer() : _head(0), _tail(0), _full(false) {
+    }
+
+    ~CircularBuffer() {
+    }
+
+    /** Push the transaction to the buffer. This overwrites the buffer if it's
+     *  full
+     *
+     * @param data Data to be pushed to the buffer
+     */
+    void push(const T& data) {
+        if (full()) {
+            _tail++;
+            _tail %= BufferSize;
+        }
+        _pool[_head++] = data;
+        _head %= BufferSize;
+        if (_head == _tail) {
+            _full = true;
+        }
+    }
+
+    /** Pop the transaction from the buffer
+     *
+     * @param data Data to be pushed to the buffer
+     * @return True if the buffer is not empty and data contains a transaction, false otherwise
+     */
+    bool pop(T& data) {
+        if (!empty()) {
+            data = _pool[_tail++];
+            _tail %= BufferSize;
+            _full = false;
+            return true;
+        }
+        return false;
+    }
+
+    /** Check if the buffer is empty
+     *
+     * @return True if the buffer is empty, false if not
+     */
+    bool empty() {
+        return (_head == _tail) && !_full;
+    }
+
+    /** Check if the buffer is full
+     *
+     * @return True if the buffer is full, false if not
+     */
+    bool full() {
+        return _full;
+    }
+
+    /** Reset the buffer
+     *
+     */
+    void reset() {
+        _head = 0;
+        _tail = 0;
+        _full = false;
+    }
+
+private:
+    T _pool[BufferSize];
+    volatile CounterType _head;
+    volatile CounterType _tail;
+    volatile bool _full;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/DigitalIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,107 @@
+/* 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_DIGITALIN_H
+#define MBED_DIGITALIN_H
+
+#include "platform.h"
+
+#include "gpio_api.h"
+
+namespace mbed {
+
+/** A digital input, used for reading the state of a pin
+ *
+ * Example:
+ * @code
+ * // Flash an LED while a DigitalIn is true
+ *
+ * #include "mbed.h"
+ *
+ * DigitalIn enable(p5);
+ * DigitalOut led(LED1);
+ *
+ * int main() {
+ *     while(1) {
+ *         if(enable) {
+ *             led = !led;
+ *         }
+ *         wait(0.25);
+ *     }
+ * }
+ * @endcode
+ */
+class DigitalIn {
+
+public:
+    /** Create a DigitalIn connected to the specified pin
+     *
+     *  @param pin DigitalIn pin to connect to
+     */
+    DigitalIn(PinName pin) : gpio() {
+        gpio_init_in(&gpio, pin);
+    }
+
+    /** Create a DigitalIn connected to the specified pin
+     *
+     *  @param pin DigitalIn pin to connect to
+     *  @param mode the initial mode of the pin
+     */
+    DigitalIn(PinName pin, PinMode mode) : gpio() {
+        gpio_init_in_ex(&gpio, pin, mode);
+    }
+    /** Read the input, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    An integer representing the state of the input pin,
+     *    0 for logical 0, 1 for logical 1
+     */
+    int read() {
+        return gpio_read(&gpio);
+    }
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone, OpenDrain
+     */
+    void mode(PinMode pull) {
+        gpio_mode(&gpio, pull);
+    }
+
+    /** Return the output setting, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    Non zero value if pin is connected to uc GPIO
+     *    0 if gpio object was initialized with NC
+     */
+    int is_connected() {
+        return gpio_is_connected(&gpio);
+    }
+
+#ifdef MBED_OPERATORS
+    /** An operator shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+#endif
+
+protected:
+    gpio_t gpio;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/DigitalInOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,124 @@
+/* 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_DIGITALINOUT_H
+#define MBED_DIGITALINOUT_H
+
+#include "platform.h"
+
+#include "gpio_api.h"
+
+namespace mbed {
+
+/** A digital input/output, used for setting or reading a bi-directional pin
+ */
+class DigitalInOut {
+
+public:
+    /** Create a DigitalInOut connected to the specified pin
+     *
+     *  @param pin DigitalInOut pin to connect to
+     */
+    DigitalInOut(PinName pin) : gpio() {
+        gpio_init_in(&gpio, pin);
+    }
+
+    /** Create a DigitalInOut connected to the specified pin
+     *
+     *  @param pin DigitalInOut pin to connect to
+     *  @param direction the initial direction of the pin
+     *  @param mode the initial mode of the pin
+     *  @param value the initial value of the pin if is an output
+     */
+    DigitalInOut(PinName pin, PinDirection direction, PinMode mode, int value) : gpio() {
+        gpio_init_inout(&gpio, pin, direction, mode, value);
+    }
+
+    /** Set the output, specified as 0 or 1 (int)
+     *
+     *  @param value An integer specifying the pin output value,
+     *      0 for logical 0, 1 (or any other non-zero value) for logical 1
+     */
+    void write(int value) {
+        gpio_write(&gpio, value);
+    }
+
+    /** Return the output setting, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    an integer representing the output setting of the pin if it is an output,
+     *    or read the input if set as an input
+     */
+    int read() {
+        return gpio_read(&gpio);
+    }
+
+    /** Set as an output
+     */
+    void output() {
+        gpio_dir(&gpio, PIN_OUTPUT);
+    }
+
+    /** Set as an input
+     */
+    void input() {
+        gpio_dir(&gpio, PIN_INPUT);
+    }
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone, OpenDrain
+     */
+    void mode(PinMode pull) {
+        gpio_mode(&gpio, pull);
+    }
+
+    /** Return the output setting, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    Non zero value if pin is connected to uc GPIO
+     *    0 if gpio object was initialized with NC
+     */
+    int is_connected() {
+        return gpio_is_connected(&gpio);
+    }
+
+#ifdef MBED_OPERATORS
+    /** A shorthand for write()
+     */
+    DigitalInOut& operator= (int value) {
+        write(value);
+        return *this;
+    }
+
+    DigitalInOut& operator= (DigitalInOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** A shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+#endif
+
+protected:
+    gpio_t gpio;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/DigitalOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,116 @@
+/* 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_DIGITALOUT_H
+#define MBED_DIGITALOUT_H
+
+#include "platform.h"
+#include "gpio_api.h"
+
+namespace mbed {
+
+/** A digital output, used for setting the state of a pin
+ *
+ * Example:
+ * @code
+ * // Toggle a LED
+ * #include "mbed.h"
+ *
+ * DigitalOut led(LED1);
+ *
+ * int main() {
+ *     while(1) {
+ *         led = !led;
+ *         wait(0.2);
+ *     }
+ * }
+ * @endcode
+ */
+class DigitalOut {
+
+public:
+    /** Create a DigitalOut connected to the specified pin
+     *
+     *  @param pin DigitalOut pin to connect to
+     */
+    DigitalOut(PinName pin) : gpio() {
+        gpio_init_out(&gpio, pin);
+    }
+
+    /** Create a DigitalOut connected to the specified pin
+     *
+     *  @param pin DigitalOut pin to connect to
+     *  @param value the initial pin value
+     */
+    DigitalOut(PinName pin, int value) : gpio() {
+        gpio_init_out_ex(&gpio, pin, value);
+    }
+
+    /** Set the output, specified as 0 or 1 (int)
+     *
+     *  @param value An integer specifying the pin output value,
+     *      0 for logical 0, 1 (or any other non-zero value) for logical 1
+     */
+    void write(int value) {
+        gpio_write(&gpio, value);
+    }
+
+    /** Return the output setting, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    an integer representing the output setting of the pin,
+     *    0 for logical 0, 1 for logical 1
+     */
+    int read() {
+        return gpio_read(&gpio);
+    }
+
+    /** Return the output setting, represented as 0 or 1 (int)
+     *
+     *  @returns
+     *    Non zero value if pin is connected to uc GPIO
+     *    0 if gpio object was initialized with NC
+     */
+    int is_connected() {
+        return gpio_is_connected(&gpio);
+    }
+
+#ifdef MBED_OPERATORS
+    /** A shorthand for write()
+     */
+    DigitalOut& operator= (int value) {
+        write(value);
+        return *this;
+    }
+
+    DigitalOut& operator= (DigitalOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** A shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+#endif
+
+protected:
+    gpio_t gpio;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/DirHandle.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/* 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_DIRHANDLE_H
+#define MBED_DIRHANDLE_H
+
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+#   define NAME_MAX 255
+typedef int mode_t;
+
+#else
+#   include <sys/syslimits.h>
+#endif
+
+#include "FileHandle.h"
+
+struct dirent {
+    char d_name[NAME_MAX+1];
+};
+
+namespace mbed {
+
+/** Represents a directory stream. Objects of this type are returned
+ *  by a FileSystemLike's opendir method. Implementations must define
+ *  at least closedir, readdir and rewinddir.
+ *
+ *  If a FileSystemLike class defines the opendir method, then the
+ *  directories of an object of that type can be accessed by
+ *  DIR *d = opendir("/example/directory") (or opendir("/example")
+ *  to open the root of the filesystem), and then using readdir(d) etc.
+ *
+ *  The root directory is considered to contain all FileLike and
+ *  FileSystemLike objects, so the DIR* returned by opendir("/") will
+ *  reflect this.
+ */
+class DirHandle {
+
+public:
+    /** Closes the directory.
+     *
+     *  @returns
+     *    0 on success,
+     *   -1 on error.
+     */
+    virtual int closedir()=0;
+
+    /** Return the directory entry at the current position, and
+     *  advances the position to the next entry.
+     *
+     * @returns
+     *  A pointer to a dirent structure representing the
+     *  directory entry at the current position, or NULL on reaching
+     *  end of directory or error.
+     */
+    virtual struct dirent *readdir()=0;
+
+    /** Resets the position to the beginning of the directory.
+     */
+    virtual void rewinddir()=0;
+
+    /** Returns the current position of the DirHandle.
+     *
+     * @returns
+     *   the current position,
+     *  -1 on error.
+     */
+    virtual off_t telldir() { return -1; }
+
+    /** Sets the position of the DirHandle.
+     *
+     *  @param location The location to seek to. Must be a value returned by telldir.
+     */
+    virtual void seekdir(off_t location) { }
+
+    virtual ~DirHandle() {}
+};
+
+} // namespace mbed
+
+typedef mbed::DirHandle DIR;
+
+extern "C" {
+    DIR *opendir(const char*);
+    struct dirent *readdir(DIR *);
+    int closedir(DIR*);
+    void rewinddir(DIR*);
+    long telldir(DIR*);
+    void seekdir(DIR*, long);
+    int mkdir(const char *name, mode_t n);
+};
+
+#endif /* MBED_DIRHANDLE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Ethernet.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,170 @@
+/* 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_ETHERNET_H
+#define MBED_ETHERNET_H
+
+#include "platform.h"
+
+#if DEVICE_ETHERNET
+
+namespace mbed {
+
+/** An ethernet interface, to use with the ethernet pins.
+ *
+ * Example:
+ * @code
+ * // Read destination and source from every ethernet packet
+ *
+ * #include "mbed.h"
+ *
+ * Ethernet eth;
+ *
+ * int main() {
+ *     char buf[0x600];
+ *
+ *     while(1) {
+ *         int size = eth.receive();
+ *         if(size > 0) {
+ *             eth.read(buf, size);
+ *             printf("Destination:  %02X:%02X:%02X:%02X:%02X:%02X\n",
+ *                     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+ *             printf("Source: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ *                     buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
+ *         }
+ *
+ *         wait(1);
+ *     }
+ * }
+ * @endcode
+ */
+class Ethernet {
+
+public:
+
+    /** Initialise the ethernet interface.
+     */
+    Ethernet();
+
+    /** Powers the hardware down.
+     */
+    virtual ~Ethernet();
+
+    enum Mode {
+        AutoNegotiate,
+        HalfDuplex10,
+        FullDuplex10,
+        HalfDuplex100,
+        FullDuplex100
+    };
+
+    /** Writes into an outgoing ethernet packet.
+     *
+     *  It will append size bytes of data to the previously written bytes.
+     *
+     *  @param data An array to write.
+     *  @param size The size of data.
+     *
+     *  @returns
+     *   The number of written bytes.
+     */
+    int write(const char *data, int size);
+
+    /** Send an outgoing ethernet packet.
+     *
+     *  After filling in the data in an ethernet packet it must be send.
+     *  Send will provide a new packet to write to.
+     *
+     *  @returns
+     *    0 if the sending was failed,
+     *    or the size of the packet successfully sent.
+     */
+    int send();
+
+    /** Recevies an arrived ethernet packet.
+     *
+     *  Receiving an ethernet packet will drop the last received ethernet packet
+     *  and make a new ethernet packet ready to read.
+     *  If no ethernet packet is arrived it will return 0.
+     *
+     *  @returns
+     *    0 if no ethernet packet is arrived,
+     *    or the size of the arrived packet.
+     */
+    int receive();
+
+    /** Read from an recevied ethernet packet.
+     *
+     *  After receive returnd a number bigger than 0it is
+     *  possible to read bytes from this packet.
+     *  Read will write up to size bytes into data.
+     *
+     *  It is possible to use read multible times.
+     *  Each time read will start reading after the last read byte before.
+     *
+     *  @returns
+     *  The number of byte read.
+     */
+    int read(char *data, int size);
+
+    /** Gives the ethernet address of the mbed.
+     *
+     *  @param mac Must be a pointer to a 6 byte char array to copy the ethernet address in.
+     */
+    void address(char *mac);
+
+    /** Returns if an ethernet link is pressent or not. It takes a wile after Ethernet initializion to show up.
+     *
+     *  @returns
+     *   0 if no ethernet link is pressent,
+     *   1 if an ethernet link is pressent.
+     *
+     * Example:
+     * @code
+     * // Using the Ethernet link function
+     * #include "mbed.h"
+     *
+     * Ethernet eth;
+     *
+     * int main() {
+     *     wait(1); // Needed after startup.
+     *     if (eth.link()) {
+     *          printf("online\n");
+     *     } else {
+     *          printf("offline\n");
+     *     }
+     * }
+     * @endcode
+     */
+    int link();
+
+    /** Sets the speed and duplex parameters of an ethernet link
+     *
+     * - AutoNegotiate      Auto negotiate speed and duplex
+     * - HalfDuplex10       10 Mbit, half duplex
+     * - FullDuplex10       10 Mbit, full duplex
+     * - HalfDuplex100      100 Mbit, half duplex
+     * - FullDuplex100      100 Mbit, full duplex
+     *
+     *  @param mode the speed and duplex mode to set the link to:
+     */
+    void set_link(Mode mode);
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FileBase.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,80 @@
+/* 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_FILEBASE_H
+#define MBED_FILEBASE_H
+
+typedef int FILEHANDLE;
+
+#include <stdio.h>
+
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+#    define O_RDONLY 0
+#    define O_WRONLY 1
+#    define O_RDWR   2
+#    define O_CREAT  0x0200
+#    define O_TRUNC  0x0400
+#    define O_APPEND 0x0008
+
+#    define NAME_MAX 255
+
+typedef int mode_t;
+typedef int ssize_t;
+typedef long off_t;
+
+#else
+#    include <sys/fcntl.h>
+#    include <sys/types.h>
+#    include <sys/syslimits.h>
+#endif
+
+#include "platform.h"
+
+namespace mbed {
+
+typedef enum {
+    FilePathType,
+    FileSystemPathType
+} PathType;
+
+class FileBase {
+public:
+    FileBase(const char *name, PathType t);
+
+    virtual ~FileBase();
+
+    const char* getName(void);
+    PathType    getPathType(void);
+
+    static FileBase *lookup(const char *name, unsigned int len);
+
+    static FileBase *get(int n);
+
+protected:
+    static FileBase *_head;
+
+    FileBase   *_next;
+    const char *_name;
+    PathType    _path_type;
+
+    /* disallow copy constructor and assignment operators */
+private:
+    FileBase(const FileBase&);
+    FileBase & operator = (const FileBase&);
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FileHandle.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,119 @@
+/* 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_FILEHANDLE_H
+#define MBED_FILEHANDLE_H
+
+typedef int FILEHANDLE;
+
+#include <stdio.h>
+
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+typedef int ssize_t;
+typedef long off_t;
+
+#else
+#   include <sys/types.h>
+#endif
+
+namespace mbed {
+
+/** An OO equivalent of the internal FILEHANDLE variable
+ *  and associated _sys_* functions.
+ *
+ * FileHandle is an abstract class, needing at least sys_write and
+ *  sys_read to be implmented for a simple interactive device.
+ *
+ * No one ever directly tals to/instanciates a FileHandle - it gets
+ *  created by FileSystem, and wrapped up by stdio.
+ */
+class FileHandle {
+
+public:
+    /** Write the contents of a buffer to the file
+     *
+     *  @param buffer the buffer to write from
+     *  @param length the number of characters to write
+     *
+     *  @returns
+     *  The number of characters written (possibly 0) on success, -1 on error.
+     */
+    virtual ssize_t write(const void* buffer, size_t length) = 0;
+
+    /** Close the file
+     *
+     *  @returns
+     *  Zero on success, -1 on error.
+     */
+    virtual int close() = 0;
+
+    /** Function read
+     *  Reads the contents of the file into a buffer
+     *
+     *  @param buffer the buffer to read in to
+     *  @param length the number of characters to read
+     *
+     *  @returns
+     *  The number of characters read (zero at end of file) on success, -1 on error.
+     */
+    virtual ssize_t read(void* buffer, size_t length) = 0;
+
+    /** Check if the handle is for a interactive terminal device.
+     * If so, line buffered behaviour is used by default
+     *
+     *  @returns
+     *    1 if it is a terminal,
+     *    0 otherwise
+     */
+    virtual int isatty() = 0;
+
+    /** Move the file position to a given offset from a given location.
+     *
+     *  @param offset The offset from whence to move to
+     *  @param whence SEEK_SET for the start of the file, SEEK_CUR for the
+     *   current file position, or SEEK_END for the end of the file.
+     *
+     *  @returns
+     *    new file position on success,
+     *    -1 on failure or unsupported
+     */
+    virtual off_t lseek(off_t offset, int whence) = 0;
+
+    /** Flush any buffers associated with the FileHandle, ensuring it
+     *  is up to date on disk
+     *
+     *  @returns
+     *    0 on success or un-needed,
+     *   -1 on error
+     */
+    virtual int fsync() = 0;
+
+    virtual off_t flen() {
+        /* remember our current position */
+        off_t pos = lseek(0, SEEK_CUR);
+        if(pos == -1) return -1;
+        /* seek to the end to get the file length */
+        off_t res = lseek(0, SEEK_END);
+        /* return to our old position */
+        lseek(pos, SEEK_SET);
+        return res;
+    }
+
+    virtual ~FileHandle();
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FileLike.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,44 @@
+/* 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_FILELIKE_H
+#define MBED_FILELIKE_H
+
+#include "FileBase.h"
+#include "FileHandle.h"
+
+namespace mbed {
+
+/* Class FileLike
+ *  A file-like object is one that can be opened with fopen by
+ *  fopen("/name", mode). It is intersection of the classes Base and
+ *  FileHandle.
+ */
+class FileLike : public FileHandle, public FileBase {
+
+public:
+    /* Constructor FileLike
+     *
+     * Variables
+     *  name - The name to use to open the file.
+     */
+    FileLike(const char *name);
+
+    virtual ~FileLike();
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FilePath.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,46 @@
+/* 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_FILEPATH_H
+#define MBED_FILEPATH_H
+
+#include "platform.h"
+
+#include "FileSystemLike.h"
+#include "FileLike.h"
+
+namespace mbed {
+
+class FilePath {
+public:
+    FilePath(const char* file_path);
+
+    const char* fileName(void);
+
+    bool          isFileSystem(void);
+    FileSystemLike* fileSystem(void);
+
+    bool    isFile(void);
+    FileLike* file(void);
+    bool    exists(void);
+
+private:
+    const char* file_name;
+    FileBase* fb;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FileSystemLike.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/* 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_FILESYSTEMLIKE_H
+#define MBED_FILESYSTEMLIKE_H
+
+#include "platform.h"
+
+#include "FileBase.h"
+#include "FileHandle.h"
+#include "DirHandle.h"
+
+namespace mbed {
+
+/** A filesystem-like object is one that can be used to open files
+ *  though it by fopen("/name/filename", mode)
+ *
+ *  Implementations must define at least open (the default definitions
+ *  of the rest of the functions just return error values).
+ */
+class FileSystemLike : public FileBase {
+
+public:
+    /** FileSystemLike constructor
+     *
+     *  @param name The name to use for the filesystem.
+     */
+    FileSystemLike(const char *name);
+
+    virtual ~FileSystemLike();
+
+    static DirHandle *opendir();
+    friend class BaseDirHandle;
+
+    /** Opens a file from the filesystem
+     *
+     *  @param filename The name of the file to open.
+     *  @param flags One of O_RDONLY, O_WRONLY, or O_RDWR, OR'd with
+     *    zero or more of O_CREAT, O_TRUNC, or O_APPEND.
+     *
+     *  @returns
+     *    A pointer to a FileHandle object representing the
+     *   file on success, or NULL on failure.
+     */
+    virtual FileHandle *open(const char *filename, int flags) = 0;
+
+    /** Remove a file from the filesystem.
+     *
+     *  @param filename the name of the file to remove.
+     *  @param returns 0 on success, -1 on failure.
+     */
+    virtual int remove(const char *filename) { return -1; };
+
+    /** Rename a file in the filesystem.
+     *
+     *  @param oldname the name of the file to rename.
+     *  @param newname the name to rename it to.
+     *
+     *  @returns
+     *    0 on success,
+     *   -1 on failure.
+     */
+    virtual int rename(const char *oldname, const char *newname) { return -1; };
+
+    /** Opens a directory in the filesystem and returns a DirHandle
+     *   representing the directory stream.
+     *
+     *  @param name The name of the directory to open.
+     *
+     *  @returns
+     *    A DirHandle representing the directory stream, or
+     *   NULL on failure.
+     */
+    virtual DirHandle *opendir(const char *name) { return NULL; };
+
+    /** Creates a directory in the filesystem.
+     *
+     *  @param name The name of the directory to create.
+     *  @param mode The permissions to create the directory with.
+     *
+     *  @returns
+     *    0 on success,
+     *   -1 on failure.
+     */
+    virtual int mkdir(const char *name, mode_t mode) { return -1; }
+
+    // TODO other filesystem functions (mkdir, rm, rn, ls etc)
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/FunctionPointer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,202 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_FUNCTIONPOINTER_H
+#define MBED_FUNCTIONPOINTER_H
+
+#include <string.h>
+#include <stdint.h>
+
+namespace mbed {
+
+/* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
+
+/** A class for storing and calling a pointer to a static or member function
+ */
+template <typename R, typename A1>
+class FunctionPointerArg1{
+public:
+    /** Create a FunctionPointer, attaching a static function
+     *
+     *  @param function The static function to attach (default is none)
+     */
+    FunctionPointerArg1(R (*function)(A1) = 0) {
+        attach(function);
+    }
+
+    /** Create a FunctionPointer, attaching a member function
+     *
+     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
+     *  @param function The address of the member function to attach
+     */
+    template<typename T>
+    FunctionPointerArg1(T *object, R (T::*member)(A1)) {
+        attach(object, member);
+    }
+
+    /** Attach a static function
+     *
+     *  @param function The static function to attach (default is none)
+     */
+    void attach(R (*function)(A1)) {
+        _p.function = function;
+        _membercaller = 0;
+    }
+
+    /** Attach a member function
+     *
+     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
+     *  @param function The address of the member function to attach
+     */
+    template<typename T>
+    void attach(T *object, R (T::*member)(A1)) {
+        _p.object = static_cast<void*>(object);
+        *reinterpret_cast<R (T::**)(A1)>(_member) = member;
+        _membercaller = &FunctionPointerArg1::membercaller<T>;
+    }
+
+    /** Call the attached static or member function
+     */
+    R call(A1 a) {
+        if (_membercaller == 0 && _p.function) {
+           return _p.function(a);
+        } else if (_membercaller && _p.object) {
+           return _membercaller(_p.object, _member, a);
+        }
+        return (R)0;
+    }
+
+    /** Get registered static function
+     */
+    R(*get_function(A1))() {
+        return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function;
+    }
+
+#ifdef MBED_OPERATORS
+    R operator ()(A1 a) {
+        return call(a);
+    }
+    operator bool(void) const {
+        return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
+    }
+#endif
+private:
+    template<typename T>
+    static R membercaller(void *object, uintptr_t *member, A1 a) {
+        T* o = static_cast<T*>(object);
+        R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
+        return (o->**m)(a);
+    }
+
+    union {
+        R (*function)(A1); // static function pointer
+        void *object;      // object this pointer
+    } _p;
+    uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
+    R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
+};
+
+/** A class for storing and calling a pointer to a static or member function (R ()(void))
+ */
+template <typename R>
+class FunctionPointerArg1<R, void>{
+public:
+    /** Create a FunctionPointer, attaching a static function
+     *
+     *  @param function The static function to attach (default is none)
+     */
+    FunctionPointerArg1(R (*function)(void) = 0) {
+        attach(function);
+    }
+
+    /** Create a FunctionPointer, attaching a member function
+     *
+     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
+     *  @param function The address of the void member function to attach
+     */
+    template<typename T>
+    FunctionPointerArg1(T *object, R (T::*member)(void)) {
+        attach(object, member);
+    }
+
+    /** Attach a static function
+     *
+     *  @param function The void static function to attach (default is none)
+     */
+    void attach(R (*function)(void)) {
+        _p.function = function;
+        _membercaller = 0;
+    }
+
+    /** Attach a member function
+     *
+     *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
+     *  @param function The address of the void member function to attach
+     */
+    template<typename T>
+    void attach(T *object, R (T::*member)(void)) {
+        _p.object = static_cast<void*>(object);
+        *reinterpret_cast<R (T::**)(void)>(_member) = member;
+        _membercaller = &FunctionPointerArg1::membercaller<T>;
+    }
+
+    /** Call the attached static or member function
+     */
+    R call(){
+        if (_membercaller == 0 && _p.function) {
+            return _p.function();
+        } else if (_membercaller && _p.object) {
+            return _membercaller(_p.object, _member);
+        }
+        return (R)0;
+    }
+
+    /** Get registered static function
+     */
+    R(*get_function())() {
+        return _membercaller ? (R(*)())0 : (R(*)())_p.function;
+    }
+
+#ifdef MBED_OPERATORS
+    R operator ()(void) {
+        return call();
+    }
+    operator bool(void) const {
+        return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
+    }
+#endif
+
+private:
+    template<typename T>
+    static R membercaller(void *object, uintptr_t *member) {
+        T* o = static_cast<T*>(object);
+        R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
+        return (o->**m)();
+    }
+
+    union {
+        R (*function)(void); // static function pointer
+        void *object;        // object this pointer
+    } _p;
+    uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
+    R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
+};
+
+typedef FunctionPointerArg1<void, void> FunctionPointer;
+typedef FunctionPointerArg1<void, int> event_callback_t;
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/I2C.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,176 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_I2C_H
+#define MBED_I2C_H
+
+#include "platform.h"
+
+#if DEVICE_I2C
+
+#include "i2c_api.h"
+
+#if DEVICE_I2C_ASYNCH
+#include "CThunk.h"
+#include "dma_api.h"
+#include "FunctionPointer.h"
+#endif
+
+namespace mbed {
+
+/** An I2C Master, used for communicating with I2C slave devices
+ *
+ * Example:
+ * @code
+ * // Read from I2C slave at address 0x62
+ *
+ * #include "mbed.h"
+ *
+ * I2C i2c(p28, p27);
+ *
+ * int main() {
+ *     int address = 0x62;
+ *     char data[2];
+ *     i2c.read(address, data, 2);
+ * }
+ * @endcode
+ */
+class I2C {
+
+public:
+    enum RxStatus {
+        NoData,
+        MasterGeneralCall,
+        MasterWrite,
+        MasterRead
+    };
+
+    enum Acknowledge {
+        NoACK = 0,
+        ACK   = 1
+    };
+
+    /** Create an I2C Master interface, connected to the specified pins
+     *
+     *  @param sda I2C data line pin
+     *  @param scl I2C clock line pin
+     */
+    I2C(PinName sda, PinName scl);
+
+    /** Set the frequency of the I2C interface
+     *
+     *  @param hz The bus frequency in hertz
+     */
+    void frequency(int hz);
+
+    /** Read from an I2C slave
+     *
+     * Performs a complete read transaction. The bottom bit of
+     * the address is forced to 1 to indicate a read.
+     *
+     *  @param address 8-bit I2C slave address [ addr | 1 ]
+     *  @param data Pointer to the byte-array to read data in to
+     *  @param length Number of bytes to read
+     *  @param repeated Repeated start, true - don't send stop at end
+     *
+     *  @returns
+     *       0 on success (ack),
+     *   non-0 on failure (nack)
+     */
+    int read(int address, char *data, int length, bool repeated = false);
+
+    /** Read a single byte from the I2C bus
+     *
+     *  @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
+     *
+     *  @returns
+     *    the byte read
+     */
+    int read(int ack);
+
+    /** Write to an I2C slave
+     *
+     * Performs a complete write transaction. The bottom bit of
+     * the address is forced to 0 to indicate a write.
+     *
+     *  @param address 8-bit I2C slave address [ addr | 0 ]
+     *  @param data Pointer to the byte-array data to send
+     *  @param length Number of bytes to send
+     *  @param repeated Repeated start, true - do not send stop at end
+     *
+     *  @returns
+     *       0 on success (ack),
+     *   non-0 on failure (nack)
+     */
+    int write(int address, const char *data, int length, bool repeated = false);
+
+    /** Write single byte out on the I2C bus
+     *
+     *  @param data data to write out on bus
+     *
+     *  @returns
+     *    '1' if an ACK was received,
+     *    '0' otherwise
+     */
+    int write(int data);
+
+    /** Creates a start condition on the I2C bus
+     */
+
+    void start(void);
+
+    /** Creates a stop condition on the I2C bus
+     */
+    void stop(void);
+
+#if DEVICE_I2C_ASYNCH
+
+    /** Start non-blocking I2C transfer.
+     *
+     * @param address   8/10 bit I2c slave address
+     * @param tx_buffer The TX buffer with data to be transfered
+     * @param tx_length The length of TX buffer in bytes
+     * @param rx_buffer The RX buffer which is used for received data
+     * @param rx_length The length of RX buffer in bytes
+     * @param event     The logical OR of events to modify
+     * @param callback  The event callback function
+     * @param repeated Repeated start, true - do not send stop at end
+     * @return Zero if the transfer has started, or -1 if I2C peripheral is busy
+     */
+    int transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t& callback, int event = I2C_EVENT_TRANSFER_COMPLETE, bool repeated = false);
+
+    /** Abort the on-going I2C transfer
+     */
+    void abort_transfer();
+protected:
+    void irq_handler_asynch(void);
+    event_callback_t _callback;
+    CThunk<I2C> _irq;
+    DMAUsage _usage;
+#endif
+
+protected:
+    void aquire();
+
+    i2c_t _i2c;
+    static I2C  *_owner;
+    int         _hz;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/I2CSlave.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,154 @@
+/* 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_I2C_SLAVE_H
+#define MBED_I2C_SLAVE_H
+
+#include "platform.h"
+
+#if DEVICE_I2CSLAVE
+
+#include "i2c_api.h"
+
+namespace mbed {
+
+/** An I2C Slave, used for communicating with an I2C Master device
+ *
+ * Example:
+ * @code
+ * // Simple I2C responder
+ * #include <mbed.h>
+ *
+ * I2CSlave slave(p9, p10);
+ *
+ * int main() {
+ *     char buf[10];
+ *     char msg[] = "Slave!";
+ *
+ *     slave.address(0xA0);
+ *     while (1) {
+ *         int i = slave.receive();
+ *         switch (i) {
+ *             case I2CSlave::ReadAddressed:
+ *                 slave.write(msg, strlen(msg) + 1); // Includes null char
+ *                 break;
+ *             case I2CSlave::WriteGeneral:
+ *                 slave.read(buf, 10);
+ *                 printf("Read G: %s\n", buf);
+ *                 break;
+ *             case I2CSlave::WriteAddressed:
+ *                 slave.read(buf, 10);
+ *                 printf("Read A: %s\n", buf);
+ *                 break;
+ *         }
+ *         for(int i = 0; i < 10; i++) buf[i] = 0;    // Clear buffer
+ *     }
+ * }
+ * @endcode
+ */
+class I2CSlave {
+
+public:
+    enum RxStatus {
+        NoData         = 0,
+        ReadAddressed  = 1,
+        WriteGeneral   = 2,
+        WriteAddressed = 3
+    };
+
+    /** Create an I2C Slave interface, connected to the specified pins.
+     *
+     *  @param sda I2C data line pin
+     *  @param scl I2C clock line pin
+     */
+    I2CSlave(PinName sda, PinName scl);
+
+    /** Set the frequency of the I2C interface
+     *
+     *  @param hz The bus frequency in hertz
+     */
+    void frequency(int hz);
+
+    /** Checks to see if this I2C Slave has been addressed.
+     *
+     *  @returns
+     *  A status indicating if the device has been addressed, and how
+     *  - NoData            - the slave has not been addressed
+     *  - ReadAddressed     - the master has requested a read from this slave
+     *  - WriteAddressed    - the master is writing to this slave
+     *  - WriteGeneral      - the master is writing to all slave
+     */
+    int receive(void);
+
+    /** Read from an I2C master.
+     *
+     *  @param data pointer to the byte array to read data in to
+     *  @param length maximum number of bytes to read
+     *
+     *  @returns
+     *       0 on success,
+     *   non-0 otherwise
+     */
+    int read(char *data, int length);
+
+    /** Read a single byte from an I2C master.
+     *
+     *  @returns
+     *    the byte read
+     */
+    int read(void);
+
+    /** Write to an I2C master.
+     *
+     *  @param data pointer to the byte array to be transmitted
+     *  @param length the number of bytes to transmite
+     *
+     *  @returns
+     *       0 on success,
+     *   non-0 otherwise
+     */
+    int write(const char *data, int length);
+
+    /** Write a single byte to an I2C master.
+     *
+     *  @data the byte to write
+     *
+     *  @returns
+     *    '1' if an ACK was received,
+     *    '0' otherwise
+     */
+    int write(int data);
+
+    /** Sets the I2C slave address.
+     *
+     *  @param address The address to set for the slave (ignoring the least
+     *  signifcant bit). If set to 0, the slave will only respond to the
+     *  general call address.
+     */
+    void address(int address);
+
+    /** Reset the I2C slave back into the known ready receiving state.
+     */
+    void stop(void);
+
+protected:
+    i2c_t _i2c;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/InterruptIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,135 @@
+/* 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_INTERRUPTIN_H
+#define MBED_INTERRUPTIN_H
+
+#include "platform.h"
+
+#if DEVICE_INTERRUPTIN
+
+#include "gpio_api.h"
+#include "gpio_irq_api.h"
+#include "FunctionPointer.h"
+
+namespace mbed {
+
+/** A digital interrupt input, used to call a function on a rising or falling edge
+ *
+ * Example:
+ * @code
+ * // Flash an LED while waiting for events
+ *
+ * #include "mbed.h"
+ *
+ * InterruptIn event(p16);
+ * DigitalOut led(LED1);
+ *
+ * void trigger() {
+ *     printf("triggered!\n");
+ * }
+ *
+ * int main() {
+ *     event.rise(&trigger);
+ *     while(1) {
+ *         led = !led;
+ *         wait(0.25);
+ *     }
+ * }
+ * @endcode
+ */
+class InterruptIn {
+
+public:
+
+    /** Create an InterruptIn connected to the specified pin
+     *
+     *  @param pin InterruptIn pin to connect to
+     *  @param name (optional) A string to identify the object
+     */
+    InterruptIn(PinName pin);
+    virtual ~InterruptIn();
+
+     int read();
+#ifdef MBED_OPERATORS
+    operator int();
+
+#endif
+
+    /** Attach a function to call when a rising edge occurs on the input
+     *
+     *  @param fptr A pointer to a void function, or 0 to set as none
+     */
+    void rise(void (*fptr)(void));
+
+    /** Attach a member function to call when a rising edge occurs on the input
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     */
+    template<typename T>
+    void rise(T* tptr, void (T::*mptr)(void)) {
+        _rise.attach(tptr, mptr);
+        gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
+    }
+
+    /** Attach a function to call when a falling edge occurs on the input
+     *
+     *  @param fptr A pointer to a void function, or 0 to set as none
+     */
+    void fall(void (*fptr)(void));
+
+    /** Attach a member function to call when a falling edge occurs on the input
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     */
+    template<typename T>
+    void fall(T* tptr, void (T::*mptr)(void)) {
+        _fall.attach(tptr, mptr);
+        gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
+    }
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone
+     */
+    void mode(PinMode pull);
+
+    /** Enable IRQ. This method depends on hw implementation, might enable one
+     *  port interrupts. For further information, check gpio_irq_enable().
+     */
+    void enable_irq();
+
+    /** Disable IRQ. This method depends on hw implementation, might disable one
+     *  port interrupts. For further information, check gpio_irq_disable().
+     */
+    void disable_irq();
+
+    static void _irq_handler(uint32_t id, gpio_irq_event event);
+
+protected:
+    gpio_t gpio;
+    gpio_irq_t gpio_irq;
+
+    FunctionPointer _rise;
+    FunctionPointer _fall;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/InterruptManager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,143 @@
+#ifndef MBED_INTERRUPTMANAGER_H
+#define MBED_INTERRUPTMANAGER_H
+
+#include "cmsis.h"
+#include "CallChain.h"
+#include <string.h>
+
+namespace mbed {
+
+/** Use this singleton if you need to chain interrupt handlers.
+ *
+ * Example (for LPC1768):
+ * @code
+ * #include "InterruptManager.h"
+ * #include "mbed.h"
+ *
+ * Ticker flipper;
+ * DigitalOut led1(LED1);
+ * DigitalOut led2(LED2);
+ *
+ * void flip(void) {
+ *     led1 = !led1;
+ * }
+ *
+ * void handler(void) {
+ *     led2 = !led1;
+ * }
+ *
+ * int main() {
+ *     led1 = led2 = 0;
+ *     flipper.attach(&flip, 1.0);
+ *     InterruptManager::get()->add_handler(handler, TIMER3_IRQn);
+ * }
+ * @endcode
+ */
+class InterruptManager {
+public:
+    /** Return the only instance of this class
+     */
+    static InterruptManager* get();
+
+    /** Destroy the current instance of the interrupt manager
+     */
+    static void destroy();
+
+    /** Add a handler for an interrupt at the end of the handler list
+     *
+     *  @param function the handler to add
+     *  @param irq interrupt number
+     *
+     *  @returns
+     *  The function object created for 'function'
+     */
+    pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) {
+        return add_common(function, irq);
+    }
+
+    /** Add a handler for an interrupt at the beginning of the handler list
+     *
+     *  @param function the handler to add
+     *  @param irq interrupt number
+     *
+     *  @returns
+     *  The function object created for 'function'
+     */
+    pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) {
+        return add_common(function, irq, true);
+    }
+
+    /** Add a handler for an interrupt at the end of the handler list
+     *
+     *  @param tptr pointer to the object that has the handler function
+     *  @param mptr pointer to the actual handler function
+     *  @param irq interrupt number
+     *
+     *  @returns
+     *  The function object created for 'tptr' and 'mptr'
+     */
+    template<typename T>
+    pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
+        return add_common(tptr, mptr, irq);
+    }
+
+    /** Add a handler for an interrupt at the beginning of the handler list
+     *
+     *  @param tptr pointer to the object that has the handler function
+     *  @param mptr pointer to the actual handler function
+     *  @param irq interrupt number
+     *
+     *  @returns
+     *  The function object created for 'tptr' and 'mptr'
+     */
+    template<typename T>
+    pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
+        return add_common(tptr, mptr, irq, true);
+    }
+
+    /** Remove a handler from an interrupt
+     *
+     *  @param handler the function object for the handler to remove
+     *  @param irq the interrupt number
+     *
+     *  @returns
+     *  true if the handler was found and removed, false otherwise
+     */
+    bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
+
+private:
+    InterruptManager();
+    ~InterruptManager();
+
+    // We declare the copy contructor and the assignment operator, but we don't
+    // implement them. This way, if someone tries to copy/assign our instance,
+    // he will get an error at compile time.
+    InterruptManager(const InterruptManager&);
+    InterruptManager& operator =(const InterruptManager&);
+
+    template<typename T>
+    pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) {
+        int irq_pos = get_irq_index(irq);
+        bool change = must_replace_vector(irq);
+
+        pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr);
+        if (change)
+            NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
+        return pf;
+    }
+
+    pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false);
+    bool must_replace_vector(IRQn_Type irq);
+    int get_irq_index(IRQn_Type irq);
+    void irq_helper();
+    void add_helper(void (*function)(void), IRQn_Type irq, bool front=false);
+    static void static_irq_helper();
+
+    CallChain* _chains[NVIC_NUM_VECTORS];
+    static InterruptManager* _instance;
+};
+
+} // namespace mbed
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/LocalFileSystem.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,103 @@
+/* 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_LOCALFILESYSTEM_H
+#define MBED_LOCALFILESYSTEM_H
+
+#include "platform.h"
+
+#if DEVICE_LOCALFILESYSTEM
+
+#include "FileSystemLike.h"
+
+namespace mbed {
+
+FILEHANDLE local_file_open(const char* name, int flags);
+
+class LocalFileHandle : public FileHandle {
+
+public:
+    LocalFileHandle(FILEHANDLE fh);
+
+    virtual int close();
+
+    virtual ssize_t write(const void *buffer, size_t length);
+
+    virtual ssize_t read(void *buffer, size_t length);
+
+    virtual int isatty();
+
+    virtual off_t lseek(off_t position, int whence);
+
+    virtual int fsync();
+
+    virtual off_t flen();
+
+protected:
+    FILEHANDLE _fh;
+    int pos;
+};
+
+/** A filesystem for accessing the local mbed Microcontroller USB disk drive
+ *
+ *  This allows programs to read and write files on the same disk drive that is used to program the
+ *  mbed Microcontroller. Once created, the standard C file access functions are used to open,
+ *  read and write files.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * LocalFileSystem local("local");               // Create the local filesystem under the name "local"
+ *
+ * int main() {
+ *     FILE *fp = fopen("/local/out.txt", "w");  // Open "out.txt" on the local file system for writing
+ *     fprintf(fp, "Hello World!");
+ *     fclose(fp);
+ *     remove("/local/out.txt");                 // Removes the file "out.txt" from the local file system
+ *
+ *     DIR *d = opendir("/local");               // Opens the root directory of the local file system
+ *     struct dirent *p;
+ *     while((p = readdir(d)) != NULL) {         // Print the names of the files in the local file system
+ *       printf("%s\n", p->d_name);              // to stdout.
+ *     }
+ *     closedir(d);
+ * }
+ * @endcode
+ *
+ * @note
+ *  If the microcontroller program makes an access to the local drive, it will be marked as "removed"
+ *  on the Host computer. This means it is no longer accessible from the Host Computer.
+ *
+ *  The drive will only re-appear when the microcontroller program exists. Note that if the program does
+ *  not exit, you will need to hold down reset on the mbed Microcontroller to be able to see the drive again!
+ */
+class LocalFileSystem : public FileSystemLike {
+
+public:
+    LocalFileSystem(const char* n) : FileSystemLike(n) {
+
+    }
+
+    virtual FileHandle *open(const char* name, int flags);
+    virtual int remove(const char *filename);
+    virtual DirHandle *opendir(const char *name);
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/LowPowerTicker.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,44 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_LOWPOWERTICKER_H
+#define MBED_LOWPOWERTICKER_H
+
+#include "platform.h"
+#include "Ticker.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+#include "lp_ticker_api.h"
+
+namespace mbed {
+
+/** Low Power Ticker
+ */
+class LowPowerTicker : public Ticker {
+
+public:
+    LowPowerTicker() : Ticker(get_lp_ticker_data()) {
+    }
+
+    virtual ~LowPowerTicker() {
+    }
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/LowPowerTimeout.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_LOWPOWERTIMEOUT_H
+#define MBED_LOWPOWERTIMEOUT_H
+
+#include "platform.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+#include "lp_ticker_api.h"
+#include "LowPowerTicker.h"
+
+namespace mbed {
+
+/** Low Power Timout
+ */
+class LowPowerTimeout : public LowPowerTicker {
+
+private:
+    virtual void handler(void) {
+        _function.call();
+    }
+};
+
+}
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/LowPowerTimer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_LOWPOWERTIMER_H
+#define MBED_LOWPOWERTIMER_H
+
+#include "platform.h"
+#include "Timer.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+#include "lp_ticker_api.h"
+
+namespace mbed {
+
+/** Low power timer
+ */
+class LowPowerTimer : public Timer {
+
+public:
+    LowPowerTimer() : Timer(get_lp_ticker_data()) {
+    }
+
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/PortIn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,93 @@
+/* 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_PORTIN_H
+#define MBED_PORTIN_H
+
+#include "platform.h"
+
+#if DEVICE_PORTIN
+
+#include "port_api.h"
+
+namespace mbed {
+
+/** A multiple pin digital input
+ *
+ *  Example:
+ * @code
+ * // Switch on an LED if any of mbed pins 21-26 is high
+ *
+ * #include "mbed.h"
+ *
+ * PortIn     p(Port2, 0x0000003F);   // p21-p26
+ * DigitalOut ind(LED4);
+ *
+ * int main() {
+ *     while(1) {
+ *         int pins = p.read();
+ *         if(pins) {
+ *             ind = 1;
+ *         } else {
+ *             ind = 0;
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class PortIn {
+public:
+
+    /** Create an PortIn, connected to the specified port
+     *
+     *  @param port Port to connect to (Port0-Port5)
+     *  @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
+        */
+    PortIn(PortName port, int mask = 0xFFFFFFFF) {
+        port_init(&_port, port, mask, PIN_INPUT);
+    }
+
+    /** Read the value currently output on the port
+     *
+     *  @returns
+     *    An integer with each bit corresponding to associated port pin setting
+     */
+    int read() {
+        return port_read(&_port);
+    }
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone, OpenDrain
+     */
+    void mode(PinMode mode) {
+        port_mode(&_port, mode);
+    }
+
+    /** A shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+
+private:
+    port_t _port;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/PortInOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/* 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_PORTINOUT_H
+#define MBED_PORTINOUT_H
+
+#include "platform.h"
+
+#if DEVICE_PORTINOUT
+
+#include "port_api.h"
+
+namespace mbed {
+
+/** A multiple pin digital in/out used to set/read multiple bi-directional pins
+ */
+class PortInOut {
+public:
+
+    /** Create an PortInOut, connected to the specified port
+     *
+     *  @param port Port to connect to (Port0-Port5)
+     *  @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
+     */
+    PortInOut(PortName port, int mask = 0xFFFFFFFF) {
+        port_init(&_port, port, mask, PIN_INPUT);
+    }
+
+    /** Write the value to the output port
+     *
+     *  @param value An integer specifying a bit to write for every corresponding port pin
+     */
+    void write(int value) {
+        port_write(&_port, value);
+    }
+
+    /** Read the value currently output on the port
+     *
+     *  @returns
+     *    An integer with each bit corresponding to associated port pin setting
+     */
+    int read() {
+        return port_read(&_port);
+    }
+
+    /** Set as an output
+     */
+    void output() {
+        port_dir(&_port, PIN_OUTPUT);
+    }
+
+    /** Set as an input
+     */
+    void input() {
+        port_dir(&_port, PIN_INPUT);
+    }
+
+    /** Set the input pin mode
+     *
+     *  @param mode PullUp, PullDown, PullNone, OpenDrain
+     */
+    void mode(PinMode mode) {
+        port_mode(&_port, mode);
+    }
+
+    /** A shorthand for write()
+     */
+    PortInOut& operator= (int value) {
+        write(value);
+        return *this;
+    }
+
+    PortInOut& operator= (PortInOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** A shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+
+private:
+    port_t _port;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/PortOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/* 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_PORTOUT_H
+#define MBED_PORTOUT_H
+
+#include "platform.h"
+
+#if DEVICE_PORTOUT
+
+#include "port_api.h"
+
+namespace mbed {
+/** A multiple pin digital out
+ *
+ * Example:
+ * @code
+ * // Toggle all four LEDs
+ *
+ * #include "mbed.h"
+ *
+ * // LED1 = P1.18  LED2 = P1.20  LED3 = P1.21  LED4 = P1.23
+ * #define LED_MASK 0x00B40000
+ *
+ * PortOut ledport(Port1, LED_MASK);
+ *
+ * int main() {
+ *     while(1) {
+ *         ledport = LED_MASK;
+ *         wait(1);
+ *         ledport = 0;
+ *         wait(1);
+ *     }
+ * }
+ * @endcode
+ */
+class PortOut {
+public:
+
+    /** Create an PortOut, connected to the specified port
+     *
+     *  @param port Port to connect to (Port0-Port5)
+     *  @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
+     */
+    PortOut(PortName port, int mask = 0xFFFFFFFF) {
+        port_init(&_port, port, mask, PIN_OUTPUT);
+    }
+
+    /** Write the value to the output port
+     *
+     *  @param value An integer specifying a bit to write for every corresponding PortOut pin
+     */
+    void write(int value) {
+        port_write(&_port, value);
+    }
+
+    /** Read the value currently output on the port
+     *
+     *  @returns
+     *    An integer with each bit corresponding to associated PortOut pin setting
+     */
+    int read() {
+        return port_read(&_port);
+    }
+
+    /** A shorthand for write()
+     */
+    PortOut& operator= (int value) {
+        write(value);
+        return *this;
+    }
+
+    PortOut& operator= (PortOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** A shorthand for read()
+     */
+    operator int() {
+        return read();
+    }
+
+private:
+    port_t _port;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/PwmOut.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,158 @@
+/* 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_PWMOUT_H
+#define MBED_PWMOUT_H
+
+#include "platform.h"
+
+#if DEVICE_PWMOUT
+#include "pwmout_api.h"
+
+namespace mbed {
+
+/** A pulse-width modulation digital output
+ *
+ * Example
+ * @code
+ * // Fade a led on.
+ * #include "mbed.h"
+ *
+ * PwmOut led(LED1);
+ *
+ * int main() {
+ *     while(1) {
+ *         led = led + 0.01;
+ *         wait(0.2);
+ *         if(led == 1.0) {
+ *             led = 0;
+ *         }
+ *     }
+ * }
+ * @endcode
+ *
+ * @note
+ *  On the LPC1768 and LPC2368, the PWMs all share the same
+ *  period - if you change the period for one, you change it for all.
+ *  Although routines that change the period maintain the duty cycle
+ *  for its PWM, all other PWMs will require their duty cycle to be
+ *  refreshed.
+ */
+class PwmOut {
+
+public:
+
+    /** Create a PwmOut connected to the specified pin
+     *
+     *  @param pin PwmOut pin to connect to
+     */
+    PwmOut(PinName pin) {
+        pwmout_init(&_pwm, pin);
+    }
+
+    /** Set the ouput duty-cycle, specified as a percentage (float)
+     *
+     *  @param value A floating-point value representing the output duty-cycle,
+     *    specified as a percentage. The value should lie between
+     *    0.0f (representing on 0%) and 1.0f (representing on 100%).
+     *    Values outside this range will be saturated to 0.0f or 1.0f.
+     */
+    void write(float value) {
+        pwmout_write(&_pwm, value);
+    }
+
+    /** Return the current output duty-cycle setting, measured as a percentage (float)
+     *
+     *  @returns
+     *    A floating-point value representing the current duty-cycle being output on the pin,
+     *    measured as a percentage. The returned value will lie between
+     *    0.0f (representing on 0%) and 1.0f (representing on 100%).
+     *
+     *  @note
+     *  This value may not match exactly the value set by a previous <write>.
+     */
+    float read() {
+        return pwmout_read(&_pwm);
+    }
+
+    /** Set the PWM period, specified in seconds (float), keeping the duty cycle the same.
+     *
+     *  @note
+     *   The resolution is currently in microseconds; periods smaller than this
+     *   will be set to zero.
+     */
+    void period(float seconds) {
+        pwmout_period(&_pwm, seconds);
+    }
+
+    /** Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
+     */
+    void period_ms(int ms) {
+        pwmout_period_ms(&_pwm, ms);
+    }
+
+    /** Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
+     */
+    void period_us(int us) {
+        pwmout_period_us(&_pwm, us);
+    }
+
+    /** Set the PWM pulsewidth, specified in seconds (float), keeping the period the same.
+     */
+    void pulsewidth(float seconds) {
+        pwmout_pulsewidth(&_pwm, seconds);
+    }
+
+    /** Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
+     */
+    void pulsewidth_ms(int ms) {
+        pwmout_pulsewidth_ms(&_pwm, ms);
+    }
+
+    /** Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
+     */
+    void pulsewidth_us(int us) {
+        pwmout_pulsewidth_us(&_pwm, us);
+    }
+
+#ifdef MBED_OPERATORS
+    /** A operator shorthand for write()
+     */
+    PwmOut& operator= (float value) {
+        write(value);
+        return *this;
+    }
+
+    PwmOut& operator= (PwmOut& rhs) {
+        write(rhs.read());
+        return *this;
+    }
+
+    /** An operator shorthand for read()
+     */
+    operator float() {
+        return read();
+    }
+#endif
+
+protected:
+    pwmout_t _pwm;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/RawSerial.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,90 @@
+/* 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_RAW_SERIAL_H
+#define MBED_RAW_SERIAL_H
+
+#include "platform.h"
+
+#if DEVICE_SERIAL
+
+#include "SerialBase.h"
+#include "serial_api.h"
+
+namespace mbed {
+
+/** A serial port (UART) for communication with other serial devices
+ * This is a variation of the Serial class that doesn't use streams,
+ * thus making it safe to use in interrupt handlers with the RTOS.
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ * // Send a char to the PC
+ *
+ * #include "mbed.h"
+ *
+ * RawSerial pc(USBTX, USBRX);
+ *
+ * int main() {
+ *     pc.putc('A');
+ * }
+ * @endcode
+ */
+class RawSerial: public SerialBase {
+
+public:
+    /** Create a RawSerial port, connected to the specified transmit and receive pins
+     *
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *
+     *  @note
+     *    Either tx or rx may be specified as NC if unused
+     */
+    RawSerial(PinName tx, PinName rx);
+
+    /** Write a char to the serial port
+     *
+     * @param c The char to write
+     *
+     * @returns The written char or -1 if an error occured
+     */
+    int putc(int c);
+
+    /** Read a char from the serial port
+     *
+     * @returns The char read from the serial port
+     */
+    int getc();
+
+    /** Write a string to the serial port
+     *
+     * @param str The string to write
+     *
+     * @returns 0 if the write succeeds, EOF for error
+     */
+    int puts(const char *str);
+
+    int printf(const char *format, ...);
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/SPI.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,245 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_SPI_H
+#define MBED_SPI_H
+
+#include "platform.h"
+
+#if DEVICE_SPI
+
+#include "spi_api.h"
+
+#if DEVICE_SPI_ASYNCH
+#include "CThunk.h"
+#include "dma_api.h"
+#include "CircularBuffer.h"
+#include "FunctionPointer.h"
+#include "Transaction.h"
+#endif
+
+namespace mbed {
+
+/** A SPI Master, used for communicating with SPI slave devices
+ *
+ * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
+ *
+ * Most SPI devices will also require Chip Select and Reset signals. These
+ * can be controlled using <DigitalOut> pins
+ *
+ * Example:
+ * @code
+ * // Send a byte to a SPI slave, and record the response
+ *
+ * #include "mbed.h"
+ *
+ * // hardware ssel (where applicable)
+ * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
+ *
+ * // software ssel
+ * SPI device(p5, p6, p7); // mosi, miso, sclk
+ * DigitalOut cs(p8); // ssel
+ *
+ * int main() {
+ *     // hardware ssel (where applicable)
+ *     //int response = device.write(0xFF);
+ *
+ *     // software ssel
+ *     cs = 0;
+ *     int response = device.write(0xFF);
+ *     cs = 1;
+ * }
+ * @endcode
+ */
+class SPI {
+
+public:
+
+    /** Create a SPI master connected to the specified pins
+     *
+     *  mosi or miso can be specfied as NC if not used
+     *
+     *  @param mosi SPI Master Out, Slave In pin
+     *  @param miso SPI Master In, Slave Out pin
+     *  @param sclk SPI Clock pin
+     *  @param ssel SPI chip select pin
+     */
+    SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC);
+
+    /** Configure the data transmission format
+     *
+     *  @param bits Number of bits per SPI frame (4 - 16)
+     *  @param mode Clock polarity and phase mode (0 - 3)
+     *
+     * @code
+     * mode | POL PHA
+     * -----+--------
+     *   0  |  0   0
+     *   1  |  0   1
+     *   2  |  1   0
+     *   3  |  1   1
+     * @endcode
+     */
+    void format(int bits, int mode = 0);
+
+    /** Set the spi bus clock frequency
+     *
+     *  @param hz SCLK frequency in hz (default = 1MHz)
+     */
+    void frequency(int hz = 1000000);
+
+    /** Write to the SPI Slave and return the response
+     *
+     *  @param value Data to be sent to the SPI slave
+     *
+     *  @returns
+     *    Response from the SPI slave
+    */
+    virtual int write(int value);
+
+#if DEVICE_SPI_ASYNCH
+
+    /** Start non-blocking SPI transfer using 8bit buffers.
+     *
+     * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
+     *                  the default SPI value is sent
+     * @param tx_length The length of TX buffer in bytes
+     * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
+     *                  received data are ignored
+     * @param rx_length The length of RX buffer in bytes
+     * @param callback  The event callback function
+     * @param event     The logical OR of events to modify. Look at spi hal header file for SPI events.
+     * @return Zero if the transfer has started, or -1 if SPI peripheral is busy
+     */
+    template<typename Type>
+    int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t& callback, int event = SPI_EVENT_COMPLETE) {
+        if (spi_active(&_spi)) {
+            return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
+        }
+        start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
+        return 0;
+    }
+
+    /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any.
+     */
+    void abort_transfer();
+
+    /** Clear the transaction buffer
+     */
+    void clear_transfer_buffer();
+
+    /** Clear the transaction buffer and abort on-going transfer.
+     */
+    void abort_all_transfers();
+
+    /** Configure DMA usage suggestion for non-blocking transfers
+     *
+     *  @param usage The usage DMA hint for peripheral
+     *  @return Zero if the usage was set, -1 if a transaction is on-going
+    */
+    int set_dma_usage(DMAUsage usage);
+
+protected:
+    /** SPI IRQ handler
+     *
+    */
+    void irq_handler_asynch(void);
+
+    /** Common transfer method
+     *
+     * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
+     *                  the default SPI value is sent
+     * @param tx_length The length of TX buffer in bytes
+     * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
+     *                  received data are ignored
+     * @param rx_length The length of RX buffer in bytes
+     * @param bit_width The buffers element width
+     * @param callback  The event callback function
+     * @param event     The logical OR of events to modify
+     * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full
+    */
+    int transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
+
+    /**
+     *
+     * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
+     *                  the default SPI value is sent
+     * @param tx_length The length of TX buffer in bytes
+     * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
+     *                  received data are ignored
+     * @param rx_length The length of RX buffer in bytes
+     * @param bit_width The buffers element width
+     * @param callback  The event callback function
+     * @param event     The logical OR of events to modify
+     * @return Zero if a transfer was added to the queue, or -1 if the queue is full
+    */
+    int queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
+
+    /** Configures a callback, spi peripheral and initiate a new transfer
+     *
+     * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
+     *                  the default SPI value is sent
+     * @param tx_length The length of TX buffer in bytes
+     * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
+     *                  received data are ignored
+     * @param rx_length The length of RX buffer in bytes
+     * @param bit_width The buffers element width
+     * @param callback  The event callback function
+     * @param event     The logical OR of events to modify
+    */
+    void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
+
+#if TRANSACTION_QUEUE_SIZE_SPI
+
+    /** Start a new transaction
+     *
+     *  @param data Transaction data
+    */
+    void start_transaction(transaction_t *data);
+
+    /** Dequeue a transaction
+     *
+    */
+    void dequeue_transaction();
+    static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer;
+#endif
+
+#endif
+
+public:
+    virtual ~SPI() {
+    }
+
+protected:
+    spi_t _spi;
+
+#if DEVICE_SPI_ASYNCH
+    CThunk<SPI> _irq;
+    event_callback_t _callback;
+    DMAUsage _usage;
+#endif
+
+    void aquire(void);
+    static SPI *_owner;
+    int _bits;
+    int _mode;
+    int _hz;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/SPISlave.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,122 @@
+/* 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_SPISLAVE_H
+#define MBED_SPISLAVE_H
+
+#include "platform.h"
+
+#if DEVICE_SPISLAVE
+
+#include "spi_api.h"
+
+namespace mbed {
+
+/** A SPI slave, used for communicating with a SPI Master device
+ *
+ * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
+ *
+ * Example:
+ * @code
+ * // Reply to a SPI master as slave
+ *
+ * #include "mbed.h"
+ *
+ * SPISlave device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
+ *
+ * int main() {
+ *     device.reply(0x00);              // Prime SPI with first reply
+ *     while(1) {
+ *         if(device.receive()) {
+ *             int v = device.read();   // Read byte from master
+ *             v = (v + 1) % 0x100;     // Add one to it, modulo 256
+ *             device.reply(v);         // Make this the next reply
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class SPISlave {
+
+public:
+
+    /** Create a SPI slave connected to the specified pins
+     *
+     *  mosi or miso can be specfied as NC if not used
+     *
+     *  @param mosi SPI Master Out, Slave In pin
+     *  @param miso SPI Master In, Slave Out pin
+     *  @param sclk SPI Clock pin
+     *  @param ssel SPI chip select pin
+     */
+    SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel);
+
+    /** Configure the data transmission format
+     *
+     *  @param bits Number of bits per SPI frame (4 - 16)
+     *  @param mode Clock polarity and phase mode (0 - 3)
+     *
+     * @code
+     * mode | POL PHA
+     * -----+--------
+     *   0  |  0   0
+     *   1  |  0   1
+     *   2  |  1   0
+     *   3  |  1   1
+     * @endcode
+     */
+    void format(int bits, int mode = 0);
+
+    /** Set the spi bus clock frequency
+     *
+     *  @param hz SCLK frequency in hz (default = 1MHz)
+     */
+    void frequency(int hz = 1000000);
+
+    /** Polls the SPI to see if data has been received
+     *
+     *  @returns
+     *    0 if no data,
+     *    1 otherwise
+     */
+    int receive(void);
+
+    /** Retrieve  data from receive buffer as slave
+     *
+     *  @returns
+     *    the data in the receive buffer
+     */
+    int read(void);
+
+    /** Fill the transmission buffer with the value to be written out
+     *  as slave on the next received message from the master.
+     *
+     *  @param value the data to be transmitted next
+     */
+    void reply(int value);
+
+protected:
+    spi_t _spi;
+
+    int _bits;
+    int _mode;
+    int _hz;
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Serial.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,74 @@
+/* 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_SERIAL_H
+#define MBED_SERIAL_H
+
+#include "platform.h"
+
+#if DEVICE_SERIAL
+
+#include "Stream.h"
+#include "SerialBase.h"
+#include "serial_api.h"
+
+namespace mbed {
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ * // Print "Hello World" to the PC
+ *
+ * #include "mbed.h"
+ *
+ * Serial pc(USBTX, USBRX);
+ *
+ * int main() {
+ *     pc.printf("Hello World\n");
+ * }
+ * @endcode
+ */
+class Serial : public SerialBase, public Stream {
+
+public:
+#if DEVICE_SERIAL_ASYNCH
+    using SerialBase::read;
+    using SerialBase::write;
+#endif
+
+    /** Create a Serial port, connected to the specified transmit and receive pins
+     *
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *
+     *  @note
+     *    Either tx or rx may be specified as NC if unused
+     */
+    Serial(PinName tx, PinName rx, const char *name=NULL);
+
+protected:
+    virtual int _getc();
+    virtual int _putc(int c);
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/SerialBase.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,223 @@
+/* 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_SERIALBASE_H
+#define MBED_SERIALBASE_H
+
+#include "platform.h"
+
+#if DEVICE_SERIAL
+
+#include "Stream.h"
+#include "FunctionPointer.h"
+#include "serial_api.h"
+
+#if DEVICE_SERIAL_ASYNCH
+#include "CThunk.h"
+#include "dma_api.h"
+#endif
+
+namespace mbed {
+
+/** A base class for serial port implementations
+ * Can't be instantiated directly (use Serial or RawSerial)
+ */
+class SerialBase {
+
+public:
+    /** Set the baud rate of the serial port
+     *
+     *  @param baudrate The baudrate of the serial port (default = 9600).
+     */
+    void baud(int baudrate);
+
+    enum Parity {
+        None = 0,
+        Odd,
+        Even,
+        Forced1,
+        Forced0
+    };
+
+    enum IrqType {
+        RxIrq = 0,
+        TxIrq
+    };
+
+    enum Flow {
+        Disabled = 0,
+        RTS,
+        CTS,
+        RTSCTS
+    };
+
+    /** Set the transmission format used by the serial port
+     *
+     *  @param bits The number of bits in a word (5-8; default = 8)
+     *  @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
+     *  @param stop The number of stop bits (1 or 2; default = 1)
+     */
+    void format(int bits=8, Parity parity=SerialBase::None, int stop_bits=1);
+
+    /** Determine if there is a character available to read
+     *
+     *  @returns
+     *    1 if there is a character available to read,
+     *    0 otherwise
+     */
+    int readable();
+
+    /** Determine if there is space available to write a character
+     *
+     *  @returns
+     *    1 if there is space to write a character,
+     *    0 otherwise
+     */
+    int writeable();
+
+    /** Attach a function to call whenever a serial interrupt is generated
+     *
+     *  @param fptr A pointer to a void function, or 0 to set as none
+     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    void attach(void (*fptr)(void), IrqType type=RxIrq);
+
+    /** Attach a member function to call whenever a serial interrupt is generated
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
+        if((mptr != NULL) && (tptr != NULL)) {
+            _irq[type].attach(tptr, mptr);
+            serial_irq_set(&_serial, (SerialIrq)type, 1);
+        } else {
+            serial_irq_set(&_serial, (SerialIrq)type, 0);
+        }
+    }
+
+    /** Generate a break condition on the serial line
+     */
+    void send_break();
+
+#if DEVICE_SERIAL_FC
+    /** Set the flow control type on the serial port
+     *
+     *  @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
+     *  @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
+     *  @param flow2 the second flow control pin (CTS for RTSCTS)
+     */
+    void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
+#endif
+
+    static void _irq_handler(uint32_t id, SerialIrq irq_type);
+
+#if DEVICE_SERIAL_ASYNCH
+
+    /** Begin asynchronous write using 8bit buffer. The completition invokes registered TX event callback
+     *
+     *  @param buffer   The buffer where received data will be stored
+     *  @param length   The buffer length in bytes
+     *  @param callback The event callback function
+     *  @param event    The logical OR of TX events
+     */
+    int write(const uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
+
+    /** Begin asynchronous write using 16bit buffer. The completition invokes registered TX event callback
+     *
+     *  @param buffer   The buffer where received data will be stored
+     *  @param length   The buffer length in bytes
+     *  @param callback The event callback function
+     *  @param event    The logical OR of TX events
+     */
+    int write(const uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
+
+    /** Abort the on-going write transfer
+     */
+    void abort_write();
+
+    /** Begin asynchronous reading using 8bit buffer. The completition invokes registred RX event callback.
+     *
+     *  @param buffer     The buffer where received data will be stored
+     *  @param length     The buffer length in bytes
+     *  @param callback   The event callback function
+     *  @param event      The logical OR of RX events
+     *  @param char_match The matching character
+     */
+    int read(uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
+
+    /** Begin asynchronous reading using 16bit buffer. The completition invokes registred RX event callback.
+     *
+     *  @param buffer     The buffer where received data will be stored
+     *  @param length     The buffer length in bytes
+     *  @param callback   The event callback function
+     *  @param event      The logical OR of RX events
+     *  @param char_match The matching character
+     */
+    int read(uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
+
+    /** Abort the on-going read transfer
+     */
+    void abort_read();
+
+    /** Configure DMA usage suggestion for non-blocking TX transfers
+     *
+     *  @param usage The usage DMA hint for peripheral
+     *  @return Zero if the usage was set, -1 if a transaction is on-going
+     */
+    int set_dma_usage_tx(DMAUsage usage);
+
+    /** Configure DMA usage suggestion for non-blocking RX transfers
+     *
+     *  @param usage The usage DMA hint for peripheral
+     *  @return Zero if the usage was set, -1 if a transaction is on-going
+     */
+    int set_dma_usage_rx(DMAUsage usage);
+
+protected:
+    void start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match);
+    void start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event);
+    void interrupt_handler_asynch(void);
+#endif
+
+protected:
+    SerialBase(PinName tx, PinName rx);
+    virtual ~SerialBase() {
+    }
+
+    int _base_getc();
+    int _base_putc(int c);
+
+#if DEVICE_SERIAL_ASYNCH
+    CThunk<SerialBase> _thunk_irq;
+    event_callback_t _tx_callback;
+    event_callback_t _rx_callback;
+    DMAUsage _tx_usage;
+    DMAUsage _rx_usage;
+#endif
+
+    serial_t        _serial;
+    FunctionPointer _irq[2];
+    int             _baud;
+
+};
+
+} // namespace mbed
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Stream.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,65 @@
+/* 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_STREAM_H
+#define MBED_STREAM_H
+
+#include "platform.h"
+#include "FileLike.h"
+
+namespace mbed {
+
+extern void mbed_set_unbuffered_stream(FILE *_file);
+extern int mbed_getc(FILE *_file);
+extern char* mbed_gets(char *s, int size, FILE *_file);
+
+class Stream : public FileLike {
+
+public:
+    Stream(const char *name=NULL);
+    virtual ~Stream();
+
+    int putc(int c);
+    int puts(const char *s);
+    int getc();
+    char *gets(char *s, int size);
+    int printf(const char* format, ...);
+    int scanf(const char* format, ...);
+
+    operator std::FILE*() {return _file;}
+
+protected:
+    virtual int close();
+    virtual ssize_t write(const void* buffer, size_t length);
+    virtual ssize_t read(void* buffer, size_t length);
+    virtual off_t lseek(off_t offset, int whence);
+    virtual int isatty();
+    virtual int fsync();
+    virtual off_t flen();
+
+    virtual int _putc(int c) = 0;
+    virtual int _getc() = 0;
+
+    std::FILE *_file;
+
+    /* disallow copy constructor and assignment operators */
+private:
+    Stream(const Stream&);
+    Stream & operator = (const Stream&);
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/crc16/crc16.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,51 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+ 
+/** @file
+ *
+ * @defgroup crc_compute CRC compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief    This module implements the CRC-16 calculation in the blocks.
+ */
+ 
+#ifndef CRC16_H__
+#define CRC16_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating CRC-16 in blocks.
+ *
+ * Feed each consecutive data block into this function, along with the current value of p_crc as 
+ * returned by the previous call of this function. The first call of this function should pass NULL 
+ * as the initial value of the crc in p_crc.
+ *
+ * @param[in] p_data The input data block for computation.
+ * @param[in] size   The size of the input data block in bytes.
+ * @param[in] p_crc  The previous calculated CRC-16 value or NULL if first call.  
+ *
+ * @return The updated CRC-16 value, based on the input supplied.
+ */
+uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC16_H__
+ 
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/scheduler/app_scheduler.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,152 @@
+/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/** @file
+ *
+ * @defgroup app_scheduler Scheduler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The scheduler is used for transferring execution from the interrupt context to the main
+ *        context.
+ *
+ * @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
+ *          when using the Scheduler.
+ *
+ * @section app_scheduler_req Requirements:
+ *
+ * @subsection main_context_logic Logic in main context:
+ *
+ *   - Define an event handler for each type of event expected.
+ *   - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
+ *     application main loop.
+ *   - Call app_sched_execute() from the main loop each time the application wakes up because of an
+ *     event (typically when sd_app_evt_wait() returns).
+ *
+ * @subsection int_context_logic Logic in interrupt context:
+ *
+ *   - In the interrupt handler, call app_sched_event_put()
+ *     with the appropriate data and event handler. This will insert an event into the
+ *     scheduler's queue. The app_sched_execute() function will pull this event and call its
+ *     handler in the main context.
+ *
+ * @if (SD_S110 && !SD_S310)
+ * For an example usage of the scheduler, see the implementations of
+ * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
+ * @endif
+ *
+ * @image html scheduler_working.jpg The high level design of the scheduler
+ */
+
+#ifndef APP_SCHEDULER_H__
+#define APP_SCHEDULER_H__
+
+#include <stdint.h>
+#include "app_error.h"
+
+#define APP_SCHED_EVENT_HEADER_SIZE 8       /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the scheduler buffer.
+ *
+ * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
+ *                         that can be scheduled for execution).
+ *
+ * @return    Required scheduler buffer size (in bytes).
+ */
+#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE)                                                 \
+            (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
+            
+/**@brief Scheduler event handler type. */
+typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
+
+/**@brief Macro for initializing the event scheduler.
+ *
+ * @details It will also handle dimensioning and allocation of the memory buffer required by the
+ *          scheduler, making sure the buffer is correctly aligned.
+ *
+ * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
+ *                         that can be scheduled for execution).
+ *
+ * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ *       several times as long as it is from the same location, e.g. to do a reinitialization).
+ */
+#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE)                                                     \
+    do                                                                                             \
+    {                                                                                              \
+        static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)),     \
+                                               sizeof(uint32_t))];                                 \
+        uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF);             \
+        APP_ERROR_CHECK(ERR_CODE);                                                                 \
+    } while (0)
+
+/**@brief Function for initializing the Scheduler.
+ *
+ * @details It must be called before entering the main loop.
+ *
+ * @param[in]   max_event_size   Maximum size of events to be passed through the scheduler.
+ * @param[in]   queue_size       Number of entries in scheduler queue (i.e. the maximum number of
+ *                               events that can be scheduled for execution).
+ * @param[in]   p_evt_buffer   Pointer to memory buffer for holding the scheduler queue. It must
+ *                               be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
+ *                               must be aligned to a 4 byte boundary.
+ *
+ * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
+ *       allocate the scheduler buffer, and also align the buffer correctly.
+ *
+ * @retval      NRF_SUCCESS               Successful initialization.
+ * @retval      NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
+ *                                        boundary).
+ */
+uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
+
+/**@brief Function for executing all scheduled events.
+ *
+ * @details This function must be called from within the main loop. It will execute all events
+ *          scheduled since the last time it was called.
+ */
+void app_sched_execute(void);
+
+/**@brief Function for scheduling an event.
+ *
+ * @details Puts an event into the event queue.
+ *
+ * @param[in]   p_event_data   Pointer to event data to be scheduled.
+ * @param[in]   event_size   Size of event data to be scheduled.
+ * @param[in]   handler        Event handler to receive the event.
+ *
+ * @return      NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t app_sched_event_put(void *                    p_event_data,
+                             uint16_t                  event_size,
+                             app_sched_event_handler_t handler);
+
+#ifdef APP_SCHEDULER_WITH_PAUSE
+/**@brief A function to pause the scheduler.
+ *
+ * @details When the scheduler is paused events are not pulled from the scheduler queue for
+ *          processing. The function can be called multiple times. To unblock the scheduler the
+ *          function @ref app_sched_resume has to be called the same number of times.
+ */
+void app_sched_pause(void);
+
+/**@brief A function to resume a scheduler.
+ *
+ * @details To unblock the scheduler this function has to be called the same number of times as
+ *          @ref app_sched_pause function.
+ */
+void app_sched_resume(void);
+#endif
+#endif // APP_SCHEDULER_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/util/app_error.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,92 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+ 
+/** @file
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler and macros for utilizing a common error handler.
+ */
+
+#ifndef APP_ERROR_H__
+#define APP_ERROR_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for error handling, which is called when an error has occurred. 
+ *
+ * @param[in] error_code  Error code supplied to the handler.
+ * @param[in] line_num    Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name. 
+ */
+void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@brief Macro for calling error handler function. 
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#ifdef DEBUG
+#define APP_ERROR_HANDLER(ERR_CODE)                         \
+    do                                                      \
+    {                                                       \
+        app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__);  \
+    } while (0)
+#else
+#define APP_ERROR_HANDLER(ERR_CODE)                         \
+    do                                                      \
+    {                                                       \
+        app_error_handler((ERR_CODE), 0, 0);  \
+    } while (0)
+#endif
+/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. 
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */    
+#define APP_ERROR_CHECK(ERR_CODE)                           \
+    do                                                      \
+    {                                                       \
+        const uint32_t LOCAL_ERR_CODE = (ERR_CODE);         \
+        if (LOCAL_ERR_CODE != NRF_SUCCESS)                  \
+        {                                                   \
+            APP_ERROR_HANDLER(LOCAL_ERR_CODE);              \
+        }                                                   \
+    } while (0)    
+    
+/**@brief Macro for calling error handler function if supplied boolean value is false. 
+ *
+ * @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
+ */
+#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE)                   \
+    do                                                        \
+    {                                                         \
+        const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
+        if (!LOCAL_BOOLEAN_VALUE)                             \
+        {                                                     \
+            APP_ERROR_HANDLER(0);                             \
+        }                                                     \
+    } while (0)        
+
+#endif // APP_ERROR_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/nordic_sdk/components/libraries/util/app_util.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,234 @@
+/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/** @file
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_H__
+#define APP_UTIL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+
+enum
+{
+    UNIT_0_625_MS = 625,                                /**< Number of microseconds in 0.625 milliseconds. */
+    UNIT_1_25_MS  = 1250,                               /**< Number of microseconds in 1.25 milliseconds. */
+    UNIT_10_MS    = 10000                               /**< Number of microseconds in 10 milliseconds. */
+};
+
+/**@brief Macro for doing static (i.e. compile time) assertion.
+ *
+ * @note If the assertion fails when compiling using Keil, the compiler will report error message
+ *       "error: #94: the size of an array must be greater than zero" (while gcc will list the
+ *       symbol static_assert_failed, making the error message more readable).
+ *       If the supplied expression can not be evaluated at compile time, Keil will report
+ *       "error: #28: expression must have a constant value".
+ *
+ * @note The macro is intentionally implemented not using do while(0), allowing it to be used
+ *       outside function blocks (e.g. close to global type- and variable declarations).
+ *       If used in a code block, it must be used before any executable code in this block.
+ *
+ * @param[in]   EXPR   Constant expression to be verified.
+ */
+
+#if defined(__GNUC__)
+#define STATIC_ASSERT(EXPR) typedef char __attribute__((unused)) static_assert_failed[(EXPR) ? 1 : -1]
+#elif defined(__ICCARM__)
+#define STATIC_ASSERT(EXPR) extern char static_assert_failed[(EXPR) ? 1 : -1] 
+#else
+#define STATIC_ASSERT(EXPR) typedef char static_assert_failed[(EXPR) ? 1 : -1]
+#endif
+
+
+/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */
+typedef uint8_t uint16_le_t[2];
+
+/**@brief type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */
+typedef uint8_t uint32_le_t[4];
+
+/**@brief Byte array type. */
+typedef struct
+{
+    uint16_t  size;                 /**< Number of array entries. */
+    uint8_t * p_data;               /**< Pointer to array entries. */
+} uint8_array_t;
+    
+/**@brief Perform rounded integer division (as opposed to truncating the result).
+ *
+ * @param[in]   A   Numerator.
+ * @param[in]   B   Denominator.
+ *
+ * @return      Rounded (integer) result of dividing A by B.
+ */
+#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B))
+
+/**@brief Check if the integer provided is a power of two.
+ *
+ * @param[in]   A   Number to be tested.
+ *
+ * @return      true if value is power of two.
+ * @return      false if value not power of two.
+ */
+#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) )
+
+/**@brief To convert milliseconds to ticks.
+ * @param[in] TIME          Number of milliseconds to convert.
+ * @param[in] RESOLUTION    Unit to be converted to in [us/ticks].
+ */
+#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+
+
+/**@brief Perform integer division, making sure the result is rounded up.
+ *
+ * @details One typical use for this is to compute the number of objects with size B is needed to
+ *          hold A number of bytes.
+ *
+ * @param[in]   A   Numerator.
+ * @param[in]   B   Denominator.
+ *
+ * @return      Integer result of dividing A by B, rounded up.
+ */
+#define CEIL_DIV(A, B)      \
+    /*lint -save -e573 */   \
+    ((((A) - 1) / (B)) + 1) \
+    /*lint -restore */
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in]   value            Value to be encoded.
+ * @param[out]  p_encoded_data   Buffer where the encoded data is to be written.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+    p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0);
+    p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8);
+    return sizeof(uint16_t);
+}
+    
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in]   value            Value to be encoded.
+ * @param[out]  p_encoded_data   Buffer where the encoded data is to be written.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+    p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+    p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+    p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+    p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24);
+    return sizeof(uint32_t);
+}
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded data is stored.
+ *
+ * @return      Decoded value.
+ */
+static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data)
+{
+        return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | 
+                 (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ));
+}
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded data is stored.
+ *
+ * @return      Decoded value.
+ */
+static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data)
+{
+    return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+             (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ));
+}
+    
+/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts.
+ *
+ *  @details The calculation is based on a linearized version of the battery's discharge
+ *           curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and
+ *           is considered to be the lower boundary.
+ *
+ *           The discharge curve for CR2032 is non-linear. In this model it is split into
+ *           4 linear sections:
+ *           - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV)
+ *           - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV)
+ *           - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV)
+ *           - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV)
+ *
+ *           These numbers are by no means accurate. Temperature and
+ *           load in the actual application is not accounted for!
+ *
+ *  @param[in] mvolts The voltage in mV
+ *
+ *  @return    Battery level in percent.
+*/
+static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts)
+{
+    uint8_t battery_level;
+
+    if (mvolts >= 3000)
+    {
+        battery_level = 100;
+    }
+    else if (mvolts > 2900)
+    {
+        battery_level = 100 - ((3000 - mvolts) * 58) / 100;
+    }
+    else if (mvolts > 2740)
+    {
+        battery_level = 42 - ((2900 - mvolts) * 24) / 160;
+    }
+    else if (mvolts > 2440)
+    {
+        battery_level = 18 - ((2740 - mvolts) * 12) / 300;
+    }
+    else if (mvolts > 2100)
+    {
+        battery_level = 6 - ((2440 - mvolts) * 6) / 340;
+    }
+    else
+    {
+        battery_level = 0;
+    }
+
+    return battery_level;
+}
+
+/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary.
+ *
+ * @param[in]   p   Pointer value to be checked.
+ *
+ * @return      TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise.
+ */
+static __INLINE bool is_word_aligned(void * p)
+{
+    return (((uintptr_t)p & 0x03) == 0);
+}
+
+#endif // APP_UTIL_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/s110_nrf51822_8_0_0/s110_nrf51822_8.0.0_softdevice.hex	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,5649 @@
+:020000040000FA
+:10000000C0070000D1060000D1000000B1060000CA
+:1000100000000000000000000000000000000000E0
+:100020000000000000000000000000005107000078
+:100030000000000000000000DB000000E500000000
+:10004000EF000000F9000000030100000D010000B6
+:1000500017010000210100002B0100003501000004
+:100060003F01000049010000530100005D01000054
+:1000700067010000710100007B01000085010000A4
+:100080008F01000099010000A3010000AD010000F4
+:10009000B7010000C1010000CB010000D501000044
+:1000A000DF010000E9010000F3010000FD01000094
+:1000B00007020000110200001B02000025020000E0
+:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24
+:1000D00008205A49096809580847382057490968CB
+:1000E000095808473C2055490968095808474020E5
+:1000F0005249096809580847442050490968095875
+:10010000084748204D490968095808474C204B4981
+:10011000096809580847502048490968095808479C
+:100120005420464909680958084758204349096836
+:10013000095808475C204149096809580847602068
+:100140003E4909680958084764203C49096809582C
+:100150000847682039490968095808476C20374919
+:100160000968095808477020344909680958084740
+:100170007420324909680958084778202F490968CE
+:10018000095808477C202D490968095808478020EC
+:100190002A490968095808478420284909680958E4
+:1001A0000847882025490968095808478C202349B1
+:1001B00009680958084790202049096809580847E4
+:1001C00094201E4909680958084798201B49096866
+:1001D000095808479C201949096809580847A02070
+:1001E0001649096809580847A4201449096809589C
+:1001F0000847A8201149096809580847AC200F4949
+:10020000096809580847B0200C4909680958084787
+:10021000B4200A49096809580847B82007490968FD
+:1002200009580847BC2005490968095808470000D3
+:1002300003480449024A034B7047000000000020B5
+:10024000C0070000C00700000122D84B5A6000BF61
+:10025000D74A1268002AFBD0016000BFD44A126856
+:10026000002AFBD00022D14B5A6000BFD04A12684E
+:10027000002AFBD07047F0B505460E46174600240D
+:1002800006E0A200B158A2005019FFF7DDFF641C80
+:10029000BC42F6D30020F0BD0120C043C549086030
+:1002A000401048607047014601229204086890425D
+:1002B00001D9102070470020FCE7F0B505460C4638
+:1002C0001646002706E028462168FFF7BDFF2D1DD2
+:1002D000241D7F1CB742F6D3F0BD70B505460C4611
+:1002E0002E460BE0304600F075F9FF2C01D80024B3
+:1002F00001E0FF3C013C012080023618002CF1D1C6
+:1003000070BD0146012292044868904201D909203B
+:100310007047A9484069401C01D10F20F8E7002030
+:10032000F6E7FEB504462068030000F037FA05043E
+:100330002B4249598B00201DFFF7E3FF0546002D96
+:1003400001D02846FEBDFFF7A7FF0120C00200F044
+:1003500041F9042221469948FFF78DFF002801D07A
+:100360000320EFE708222146944800F06DF90028A9
+:1003700006D1002192480068FFF766FF00F00CF9F3
+:100380000320DFE7A768E6686068019031463846D9
+:10039000FFF7A3FF324638460199FFF78EFFB20000
+:1003A0003846019900F050F9002800D1CAE703202F
+:1003B000C8E700F0E3F9834800688349086041E03A
+:1003C00060680190E668A0680090B200009901980A
+:1003D00000F03AF90746002F00D1B3E70E20B1E74D
+:1003E000201DFFF760FF0546002D01D02846A9E734
+:1003F0006068002807D1FFF74FFF0320800200F05C
+:10040000E9F800F0C9F8FFF747FF0120C00200F04B
+:10041000E1F8042221466948FFF72DFF002801D0AA
+:1004200003208FE708222146644800F00DF90028D8
+:1004300006D1002162480068FFF706FF00F0ACF823
+:1004400003207FE700BF00207CE770B505460C461F
+:10045000182D04D12068FFF764FF206002E001201E
+:10046000206000BF00BF70BDF0B589B05248406940
+:1004700003905248806881000398081802900398FE
+:10048000000B01900121090302984018401E000B47
+:1004900000900124002520462946019A00F0C4F866
+:1004A0000022401E91410791069001260027304608
+:1004B0003946009A00F0B8F80022401E914105919B
+:1004C0000490049BDB43059AD2430698184307998E
+:1004D00011430791069037490698086007984860CD
+:1004E00009B0F0BD70B53448446934488568466841
+:1004F000AA003146204600F0A7F8002801D00020CD
+:1005000070BD0120FCE72D484068002801D0012083
+:1005100000E000200546FFF7E5FF002807D0FFF7C1
+:10052000BBFE0320800200F055F800F035F8FFF71D
+:100530009BFF002D0ED020484669204884684768FC
+:1005400021463046FFF7C9FE224639463046FFF7BE
+:10055000B4FE00BF00F020F810B5184844681A48EF
+:100560000460204600F0DCF810BD15480068006803
+:10057000401C01D100BFFEE710480068002802D0EF
+:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B
+:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB
+:1005A000C860BFF34F8F00BFFEE7000000E50140C9
+:1005B00000E40140000600400010001000080000A8
+:1005C000B8070000BC070000000000200400FA0586
+:1005D00000ED00E010B50146104B1A6808460223F2
+:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC
+:1005F00004D0904202D20A4B186101E0084B986087
+:1006000000BF084B1B68002BFBD00023044C636029
+:1006100000BF044B1B68002BFBD010BD0010001066
+:1006200000E5014000E4014010B5202A04DB01464A
+:10063000203A9140002010BD914020239C1A03468F
+:10064000E3401943904010BD034610B50B439B0790
+:100650000FD1042A0DD308C810C9121FA342F8D025
+:1006600018BA21BA884201D9012010BD0020C04328
+:1006700010BD002A03D0D30703D0521C07E000208E
+:1006800010BD03780C78401C491C1B1B07D1037854
+:100690000C78401C491C1B1B01D1921EF1D118463D
+:1006A00010BD70477047704710B500F007F810BDD7
+:1006B000014B1B68DB6818470000002019481A49E5
+:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716
+:1006D0001649174C24688C420BD1164B1B68994263
+:1006E0000CD1154B154A1360186810498842EDD09B
+:1006F0000AE0134880F30888124B18470F4A13602A
+:1007000018680A498842E1D080F308880E49884277
+:1007100004DD0E48026802210A4302605B68184744
+:100720000346DFE7C0070000C0070000FFFFFFFF30
+:10073000000C000014100010001000000000002049
+:10074000000400206B05000000200020240500406C
+:100750000D48704502D1EFF3098101E0EFF3088104
+:10076000886902380078182802D1C046074A104725
+:10077000074A12682C3212681047000000B5054B7A
+:10078000054A9B58984700BDFDFFFFFF4B04000042
+:1007900000000020001000000400000030B4744687
+:1007A000641E2578641CAB4204D3635D5B00E318D0
+:1007B00030BC18471D46F8E7000C00000010000090
+:1010000000150020CD64010025220000336401009A
+:1010100000000000000000000000000000000000D0
+:101020000000000000000000000000003D6501001D
+:101030000000000000000000252200002522000022
+:10104000A9650100AF6501002522000025220000EE
+:101050002522000025220000252200002522000074
+:10106000B56501002522000025220000BB650100B6
+:1010700025220000C1650100C7650100CD650100A2
+:101080002522000025220000252200002522000044
+:101090002522000025220000252200002522000034
+:1010A000D3650100D965010025220000252200003A
+:1010B0002522000025220000252200002522000014
+:1010C00000F002F815F0E3F90CA030C80838241835
+:1010D0002D18A246671EAB4654465D46AC4201D170
+:1010E00015F0D5F97E460F3E0FCCB64601263342A9
+:1010F00000D0FB1AA246AB4633431847B456010052
+:10110000E4560100103A02D378C878C1FAD85207E1
+:1011100001D330C830C101D504680C6070470000AD
+:101120000023002400250026103A01D378C1FBD803
+:10113000520700D330C100D50B6070471FB5C046C1
+:10114000C04615F063F904B00FB41FBDF0B44046BB
+:10115000494652465B460FB402A0013001B506482D
+:10116000004700BF01BC86460FBC804689469246B8
+:101170009B46F0BC70470000C11000008269024924
+:101180008161024810447047911100000100000085
+:1011900001B41EB400B50BF0E6FF01B40198864619
+:1011A00001BC01B01EBD0000401E00BF00BF00BF5B
+:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37
+:1011C00000BFF1D17047000070B505460C461646C9
+:1011D00002E00FCC0FC5103E102EFAD2082E02D31B
+:1011E00003CC03C5083E042E07D301CC01C5361F2E
+:1011F00003E021782970641C6D1C761EF9D270BD45
+:101200008307FF22DB0E9A408907090E99400028C8
+:101210000BDA0007000F0838830828489B001818CD
+:10122000C36993430B43C3617047830824489B0001
+:101230001B181868904308431860704710B504469F
+:1012400000210120FFF7DCFF00211820FFF7D8FF65
+:1012500000210B20FFF7D4FF02211920FFF7D0FF58
+:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F
+:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4
+:1012800003211620FFF7BCFF03211520FFF7B8FF4D
+:10129000204600F019F8002010BD6421018070473D
+:1012A00010B500F020F810BD0648704710B500F0EA
+:1012B00022F810BD704770477047000000ED00E055
+:1012C00000E400E003F9004370B505462D4C07200B
+:1012D0002070A01CFFF7E1FF5920A080294620467E
+:1012E00000F099FB70BD10B500F09EFB2549002071
+:1012F000891E087010BDF8B5224E0446B61E30781F
+:1013000001270D46002807D0204660380B2808D852
+:10131000204600F03DFF2BE0602CF9D01A48086011
+:10132000F8BD20466C38032803D8204600F071FF32
+:101330001EE0204670381F2803D8204600F045F9EB
+:1013400016E0204690380F2803D8204600F0E8F831
+:101350000EE02046A0380F2803D8204600F074F88D
+:1013600006E02046B0380F2804D8204600F0CAF91D
+:10137000286000E02F60602CD2D128680028CFD1EF
+:101380003770F8BD1A000020013000000120244908
+:10139000C003086023490020087007202249C005C7
+:1013A0008860704770B51F4D04462878A04207D06A
+:1013B000002C05D0002803D01CA14D2015F033F8D7
+:1013C0002878A0420ED000211D4A17482C70002C0E
+:1013D00019D01C4B012C06D0022C0BD013A1682075
+:1013E00015F021F870BD11600221116053610321D5
+:1013F000090605E011600321116053610121C9054F
+:101400008160416070BD116011600721C905816074
+:1014100070BD10B505A1712015F005F810BD0000D4
+:1014200080E100E02000002000F501407372635C61
+:1014300068616C5F63636D5F6161722E63000000C1
+:1014400000F500404001002010B5A038030015F061
+:10145000DBF80B070E172028313A414B525C650030
+:101460004B6808788A68194603F0E6F910BD888849
+:101470008A6883B20888194680B203F0ECF910BD7F
+:1014800008884C68CB688A6880B2214603F0E7F987
+:1014900010BD08884B688A6880B2194603F0FBF9D2
+:1014A00010BD88888A6883B20888194680B203F024
+:1014B00007FA10BD88888A6883B20888194680B206
+:1014C00003F041FA10BD08884A6880B2114603F063
+:1014D00080FA10BD088982B2888883B208881946CC
+:1014E00080B203F081FA10BD08884A6880B21146C4
+:1014F00003F09EFA10BD08894C6882B20888CB6858
+:1015000080B2214603F018FB10BD08884C68CB68F8
+:101510008A6880B2214603F02AFC10BD012010BD6C
+:1015200010B59038030015F06FF809060F161D244A
+:101530002C363F464E0088888A6883B20888194650
+:1015400080B204F031F910BD08884A6880B21146B3
+:1015500004F065F910BD08884A6880B2114604F0AD
+:101560006AF910BD08884A6880B2114604F070F923
+:1015700010BD08884B688A6880B2194604F07BF970
+:1015800010BD088982B2888883B20888194680B263
+:1015900004F07AF910BD08894B6882B208881946B0
+:1015A00080B204F090F910BD08884A6880B21146F4
+:1015B00004F09BF910BD888882B20888114680B279
+:1015C00004F0EFF910BD012010BD10B57038030014
+:1015D00015F01AF81B0F15192125282F363B40440A
+:1015E000484C53585F688D707980888D8D8D8D8FB4
+:1015F00096004A680878114608F0FDFD10BD08689D
+:1016000008F04AFE10BD0C790B7B8A6808682146F9
+:1016100008F053FE10BD086808F011FF10BD08F077
+:1016200065FB10BD08884A6880B2114609F043F88E
+:1016300010BD0A790888114680B209F0D3F810BDB0
+:10164000087840B209F0DCF810BD088880B209F0D3
+:10165000F0F810BD086809F0FEF810BD086801F048
+:10166000D2FB10BD086801F0FCFB10BD088982B2F6
+:1016700009C9194609F007F910BD05C9114609F055
+:1016800051F910BD08884A6880B211460AF0A6F9DF
+:1016900010BD0C790888CB688A6880B221460AF0B0
+:1016A000C5FA10BD0B7908888A6880B219460AF01D
+:1016B0006DFC10BD08884C68CB688A6880B22146F2
+:1016C0000AF0D5FC10BD08884A6880B211460AF0BD
+:1016D00018FD10BD0B7908880A7A80B2194609F006
+:1016E00044F910BD088880B209F044F910BD062005
+:1016F00010BD08884A6880B2114609F042F910BD51
+:10170000012010BD10B5B02805D0B12808D0B228EE
+:101710000BD0012010BD088880B20BF0FBF810BD83
+:10172000088880B20BF015F910BD08884B688A68EC
+:1017300080B219460BF01EF910BD000010B5030071
+:1017400014F062FF0A0609060C0C0F0F06060612BB
+:1017500008F0F4FA10BD0AF0C5FE10BD01F03EFA23
+:1017600010BD06F09FFA10BDFAA1FE4814F05BFE12
+:1017700010BD3EB5FC49054603C900900191FF200C
+:10178000C33069460881F94A092310460A212838DE
+:101790000BF0BFFD0024F6480BF0D9FD641CE4B249
+:1017A0000A2CF8D3F14801231A4602A990300BF015
+:1017B000A0F9002804D0FF20E6A13D3014F033FE4C
+:1017C000686800F024FC00211E22084604F06CF931
+:1017D00008F0C3FC02222421E64801F07DFBE54825
+:1017E00001222C214C3001F077FBE2490B20B0396B
+:1017F00001F0FEF9002804D0FF20D6A1513014F0EA
+:1018000012FE0AF03EFE02F097F96B460022082114
+:10181000D9A008F07DFB002804D0FF20CDA15730CF
+:1018200014F001FE284602F0E7FC002804D0FF2057
+:10183000C8A1593014F0F7FDF3218900D14814F004
+:10184000D3FCD04801214171022181710721C1716E
+:101850003EBD10B5CB4CA0780A2804D3FF20BDA113
+:10186000903014F0E0FD20786021484300190021F9
+:101870000173417BF722C908C900C91C1140EF223E
+:10188000114041730121E1700C3010BD70B50E465E
+:1018900000211C4619801546030014F0B5FE0723ED
+:1018A000050B1711231D23002246294630460AF056
+:1018B00037FE70BD22462946304608F095F870BDC7
+:1018C00022462946304601F0E2FF70BD22462946F5
+:1018D000304603F0EAFD70BD22462946304600F04E
+:1018E00010FC70BDFF209BA1EF3014F09CFD032085
+:1018F00070BD70B5A34CE078002818D02078602126
+:1019000048430019407B00254007400F0119087922
+:10191000401E08712078401CC0B220700A2800D1F7
+:101920002570A078401CA0700BF097FEE57070BD8C
+:101930009448C079002800D08BE7704770B5914D6E
+:10194000A86800280CD0FFF7F3FF002862D06022BF
+:10195000A968FFF739FCFFF7CCFF0020A860EFE78C
+:101960006879002856D0FFF774FF044681484C3050
+:1019700001F0C2FA6060002804D17A4875A14A30AB
+:1019800014F051FD606801F01AFB00280DD02046CC
+:1019900007F00BFF6078010703D5C008C000401CAA
+:1019A0002BE0744861684C302DE0724861684C301F
+:1019B00001F0ABFA00F05AFB00282BD1FFF749FFEA
+:1019C00004466C4801F098FA6060002804D1332086
+:1019D00060A1000114F027FD606801F0F4FA00280E
+:1019E00014D060680088608020460AF0CCFD6078E2
+:1019F000010706D5C008C000801C6070FFF779FFA2
+:101A00009EE75C48616801F080FA99E7594861688F
+:101A100001F07BFA70BD10B55B4CE160A0605B48E3
+:101A200000F032FC607010BD57490020087070470C
+:101A300070B5574E0546706A94B00C46401C04D1F0
+:101A4000B06AC0430004000C0BD0306AC007C00F5E
+:101A50002870706A14F0DBFBB06A2071000A6071B4
+:101A600014E02B206946087009A9684601F07BFA4A
+:101A7000002804D03B4837A17E3814F0D4FC012064
+:101A8000287006220AA9204614F04FFB2878002867
+:101A900003D06079C0210843607114B070BDF0B507
+:101AA0003B4C0646206895B00D4637460837401C2B
+:101AB00008D16068401C05D1A068401C02D1E068D4
+:101AC000401C11D02068314614F0A1FB6068311D24
+:101AD00014F09DFBA068394614F099FBE06831468C
+:101AE0000C3114F094FB25E02B206946087009A9FD
+:101AF000684601F038FA002804D01A4815A1553874
+:101B000014F091FC08220AA9304614F00EFB2B2099
+:101B10006946087009A9684601F025FA002804D032
+:101B200010480CA14E3814F07EFC08220AA9384651
+:101B300014F0FBFA20692E460836401C08D1606973
+:101B4000401C05D1A069401C02D1E069401C33D083
+:101B500020691FE07372635C686F73745F636F72F8
+:101B6000652E6300C3020000F866010094010020A6
+:101B70003D170000640800206E524635313832327D
+:101B800000000000E8030020240000203D190000B0
+:101B900080000010294614F03AFB6069291D14F0FA
+:101BA00036FBA069314614F032FBE06929460C315E
+:101BB00014F02DFB15B0F0BD2B246846047009A964
+:101BC00001F0D1F9002803D0F649F74814F02BFCB6
+:101BD000082209AF28460AA914F0A7FA684604703B
+:101BE00009A901F0C0F9002804D0EF48ED49C01D53
+:101BF00014F019FC0822391D304614F096FAD9E782
+:101C000070B5EA4C0546A068002804D0E648E549CE
+:101C1000563014F008FCA56070BD10B50146E448CC
+:101C200001F073F9E1498879401CC0B2887101283C
+:101C300003D1E048407800F04BFB10BD70B504467E
+:101C4000DD4816460D46814204D1D748D549CB30F0
+:101C500014F0E9FB012E05D0D348D249DA3014F054
+:101C6000E2FB70BD6620207000202072A58101205B
+:101C7000A07370BD70B515460C460646FFF758FEBA
+:101C800000280CD066210170468001210172216874
+:101C90000161A18881820573FFF72BFE70BD1321BE
+:101CA000304608F09FFD70BDC2494968884201D2A4
+:101CB00010207047072101700020704770B5BD4C9F
+:101CC00005462078002694B0002801D00820E4E6DC
+:101CD000BA4A6260954201D21020DEE668680028A8
+:101CE00009D00921D82804D3C31C9B089B00834238
+:101CF00005D00846D1E60720000268600EE0012109
+:101D000009074B6B896B4B43AD49511A0122591A94
+:101D1000D202891A814201D20421EAE700F050FF81
+:101D20006178A06806F052F8E068401E07280BD8DA
+:101D3000302269460A708870684607F007F9002863
+:101D400002D009A806F07CFA2846FFF712FD012010
+:101D500020703046A1E6F8B5044696480F46406824
+:101D6000814208D3002C01D0844204D3E01C8008B7
+:101D70008000A04201D01020F8BD8C488178002955
+:101D800011D0398800914178602251430D18287B89
+:101D90000C350007000F3B4600222946FFF776FD71
+:101DA000060004D015E0002038800520F8BD002C86
+:101DB00013D039880098814201D90C260DE028788B
+:101DC0003B460007000F22462946FFF75FFD06004D
+:101DD00005D00C2E01D0002038803046F8BD734C61
+:101DE0006078401CC0B260700A2801D10020607089
+:101DF000A078401EA07068784107490F01290ED0D5
+:101E0000022906D003291AD066496E4814F00BFB4C
+:101E1000E3E7C006E1D46868FFF7FFFEDDE764484A
+:101E200069684C3001F071F86079401CC0B2607193
+:101E30000128D2D15F48407800F04AFACDE7E07936
+:101E4000401CE071C9E7604A10B5904209D3594A75
+:101E50000124A4045268A04201D3904201D39142CC
+:101E600001D2102010BD00F0FCFE10BD564B10B585
+:101E7000994209D34F4B0124A4045B68A14201D3CA
+:101E8000994201D39A4201D2102010BD022803D0FA
+:101E9000102801D0092010BD00F009FF0028FAD059
+:101EA000052010BD484B10B598420DD3414B01247D
+:101EB000A4045B68A04201D3984205D3994203D39E
+:101EC000002A03D09A4201D2102010BD00F015FF65
+:101ED0000028FAD0072010BD10B50446354894B04C
+:101EE0004068844202D2102014B010BD0F2008A90F
+:101EF000087369460BA801F036F80028F4D168464B
+:101F0000007A207068464089608068468089A08099
+:101F10000020E9E710B500290BD0264A526891420B
+:101F200002D30B68934201D2102010BD8A88002A88
+:101F300002D001F05AFE10BD092010BD10B5224A92
+:101F400094B091420ED31B4A01239B0452689942DC
+:101F500001D3914206D3441E1E2C41D8994203D38B
+:101F6000914201D21020BFE7012837D10878002420
+:101F7000C007C00F002803D003206946887001E025
+:101F80006846847038206946087009A9684600F0E0
+:101F9000EAFF002804D041200CA1C00014F043FA4D
+:101FA0002046A1E7541B000093020000E803002034
+:101FB0006408002024000020FFFF0000001900201A
+:101FC000000000200A040000008001007372635CBE
+:101FD000686F73745F636F72652E6300072083E719
+:101FE0000246203A1F2AF9D807F0F9FF7CE710B51E
+:101FF0005F4A5268914201D2102010BD0246203A39
+:102000001F2A02D808F065F810BD072010BD70B572
+:102010000546584C0020207020464619544846601A
+:10202000E01C80088000A04204D0FF2052491330F9
+:1020300014F0F9F901200007C06AC0430006000E41
+:1020400003D14E480068401C03D04D484D49301A1A
+:10205000C862A8B20122214604F039F9002804D050
+:10206000FF204549233014F0DEF970BDF0B595B07E
+:102070003B2008A9087369460BA800F074FF0028EC
+:1020800004D0FF203C496B3014F0CDF93E4E0024C3
+:102090006D4630E02F19B87DC10706D0400704D443
+:1020A00060004019C0880AF08DFB3848807900280C
+:1020B0001FD0B87D80071CD560004019C088002261
+:1020C00006210AF09CFB002813D03C2108A80173CC
+:1020D00060004019C1886846C18569460BA800F0B8
+:1020E00042FF06000BD0FF2023497F3014F09BF9FC
+:1020F00005E0641CE4B268460079A042CAD83046C4
+:1021000058E5F7B505460078002700090C463E461D
+:10211000062804D0FF201849A83014F084F9287A42
+:1021200000280ED0012814D0FF201349C93014F024
+:102130007AF90298002C068001D027806680002062
+:10214000FEBD02270926002C0ED0A889A080A87BFE
+:1021500008E003271426002C06D02869E060A88A2E
+:102160002082287B2072E4E702980680E7E70000DF
+:102170002400002000190020CC1F000000100010D7
+:10218000000000200005004004300000E8030020AB
+:1021900010B56038030014F037FA0A060A0F131856
+:1021A0001F252930353A0868FFF788FD10BD05C99D
+:1021B0001146FFF7D0FD10BD0868FFF775FD10BD93
+:1021C00005C91146FFF73FFE10BD4B6808788A68C5
+:1021D0001946FFF74BFE10BD8A6809C91946FFF77B
+:1021E00061FE10BD0868FFF777FE10BD08884A68D9
+:1021F00080B21146FFF78EFE10BD05C91146FFF7EC
+:102200009DFE10BD05C91146FFF7F1FE10BD01206E
+:1022100010BD0120704700000E4A12680C498A4226
+:102220000AD118470B4A1268094B9A4204D101B5EA
+:102230000AF090FF03BC8E46074909680958084711
+:1022400006480749054A064B704700000000000099
+:10225000BEBAFECA7800002004000020001500204D
+:102260000015002001203F49400608603E490860F3
+:102270003E490A68FF231B029A4383121A430A60ED
+:10228000384980390860704710B502460420384943
+:1022900004E0C3005B181B79002B0AD00346401EE4
+:1022A000C0B2002BF5D133A1432014F0BCF8FF20BD
+:1022B00010BDC300CA50002259184A718A71012208
+:1022C0000A7110BD2A4A0021C000801801717047B0
+:1022D00010B50446042803D326A1522014F0A3F815
+:1022E0002348E1000C182079012803D021A15320B4
+:1022F00014F099F86079A179401CC0B2814200D0F5
+:1023000060710120174940068031086010BD70B52A
+:10231000164804250068164E0004800F1B4C022846
+:102320001AD014A1692014F07EF815E02078C100BD
+:1023300088190279012A07D1427983799A4203D018
+:1023400042798271705880472078401CC0B220705A
+:10235000042801D30020207028466D1EEDB200280D
+:10236000E4D170BD80E100E080E200E018E400E02C
+:10237000E00800207372635C736F635F7369676E5C
+:10238000616C6C696E672E630000000034000020F1
+:1023900010B5EFF31080C407E40F72B6D24841784D
+:1023A000491C41704078012801D10BF07BF9002CC9
+:1023B00000D162B610BD70B5CB4CE07800280AD1D0
+:1023C0000125E570FFF7E4FF0BF074F9002804D055
+:1023D00000200BF047F9002070BDC44865714560CE
+:1023E000F9E770B5EFF31080C507ED0F72B6BE4C7C
+:1023F0006078002803D1BEA18F2014F014F8607813
+:10240000401E60706078002801D10BF04FF9002D5C
+:1024100000D162B670BD10B5B348C178002904D0B0
+:1024200000214171C170FFF7DCFF002010BD10B525
+:1024300004460BF03FF9AC49C978084000D00120B0
+:102440002060002010BDF8B50246A74C0026A671FA
+:102450000820042101251027130014F0D5F80D08D9
+:102460000A0C0E101214161E262123252800257191
+:1024700022E0022001E021711EE020711CE02771A2
+:102480001AE02020F9E7012616E0FFF781FF0BF0A4
+:1024900011F90028FBD002260EE02171A5710BE096
+:1024A0002771FBE7202000E040202071F6E7FF20A5
+:1024B0008FA1763013F0B7FF0BF008F9002809D090
+:1024C0000BF00AF9B04205D130460BF008F90028AC
+:1024D000FAD02CE001208007C560894900224A60BB
+:1024E000884A9661814B02225A608560864802695B
+:1024F000D243D206D517026910231A4302610F4650
+:102500006D1C00E020BF78680028FBD030460BF03F
+:10251000E6F80028FAD0002D04D17B48026910218A
+:102520008A43026171490220886000207860A079A6
+:1025300000280CD00BF0BEF805460BF01BF8734AD0
+:10254000002D02D0A260E06001E0E260A060002EF9
+:1025500001D100F0A5F8F8BD10B504460BF0B0F8B5
+:10256000002805D060490120C8704A78521C4A7082
+:102570002046FFF768FF10BDF8B5614DA86800263A
+:10258000012802D1AE600BF06DF86868012800D117
+:102590006E6028680127544C012812D12E606079A2
+:1025A000002803D000200BF05DF866712078002829
+:1025B00007D00BF07FF8002803D0012080070761C7
+:1025C000A770286901282AD12E6100F05FF8012048
+:1025D00080074761A079002815D00BF06BF80090B8
+:1025E0000AF0C8FF0099002901D0E16800E0A16865
+:1025F000411A022901DA8A1C11DC0099002901D054
+:10260000E06000E0A060FFF7C3FE0BF053F8002885
+:1026100004D0012080070761A77000E02770E868F8
+:10262000012812D100F032F800F030F800F02EF856
+:10263000A078002804D1FF202DA1033013F0F3FE71
+:10264000EE60A6702670FFF7CCFEF8BD10B5264CE4
+:10265000E078002801D10BF029F80120810788617A
+:1026600000F014F8A07800280BD0254CE068002872
+:1026700003D10BF034F80028F8D10020E06000F01E
+:1026800005F800201949C043886010BD08B55020E6
+:10269000694608806A461088411E1180FAD208BD3A
+:1026A000F8B5124819278760154900200860C860EE
+:1026B0000BF000F8BE0701240B4D002802D0346156
+:1026C000AC7000E02C70FFF763FE084847600D49CE
+:1026D00028798863FFF7DAFFB461FFF7D7FF08496D
+:1026E000002008617461F8BD38000020000300403C
+:1026F0007372635C736F635F636C6F636B2E6300F5
+:10270000000100400005004000ED00E0FFFFFF7FFA
+:102710008107C90E002808DA0007000F0838800872
+:102720002E4A80008018C06904E080082C4A80008E
+:1027300080180068C8400006800F704710B50D2053
+:10274000FFF7E6FFC4B20420C043FFF7E1FFC0B2C9
+:10275000844203D023A11A2013F065FE26490120EC
+:10276000486010BD0121254A48031060244B002217
+:102770001A60244A5160244A1060244A11601F499B
+:1027800080390860704701211C4A480310601F4AC5
+:1027900051601B4A002111601B490860704710B549
+:1027A00017490868012804D00EA1572013F03BFEFA
+:1027B00010BD114880680022C0B20A600AF020FCF7
+:1027C00010BD10B50E4801680029FCD0FFF7E7FFE7
+:1027D00001200D494003086010BD000000ED00E03D
+:1027E00000E400E07372635C736F635F68616C5F49
+:1027F000726E672E6300000000D5004080E100E0AB
+:1028000000D1004000D3004080E200E000D0004052
+:1028100030B40121BC48C9020160CD1005604A03F3
+:102820000260BA4803681B021B0A036004680023A5
+:10283000240A24020460B6480468240A24020460BE
+:10284000B448012444608460B34C23606360A36097
+:10285000B24B19601D601A60B14B19601A600121FA
+:10286000016030BC704710B40121A748CA02026061
+:102870000B0203600C060460A64841608160A94811
+:1028800041680029FCD1A4490020086048608860A4
+:10289000A24802600360046010BC704701219F4899
+:1028A000C9020160C91001607047002805D00128E5
+:1028B00005D0022805D19C4870479C4870479C4829
+:1028C000704710B59BA18B2013F0ADFD002010BD0B
+:1028D00070B500219E4C9F4D9F4A8F4B002808D019
+:1028E00001281DD0022822D092A1B32013F09BFD15
+:1028F00070BD01200004A060A86011601960974BB2
+:10290000C2039A60964A90607F4A00121060954810
+:10291000016086480160944801609448017070BD70
+:1029200001204004A060A8605160596070BD012082
+:102930008004A060A8609160996070BDF8B594466D
+:10294000834A8B4F834D00240126002808D001289C
+:1029500032D0022840D077A1E82013F064FDF8BD02
+:10296000891E0902090A0120000490603C64686025
+:102970006C4A1164012B1DD000217C4A7D4B5170A3
+:102980006146DC63DE637C4B5C6002249C60042453
+:102990001C61744B3D31196073490E605F4B8915A2
+:1029A00019606F4B58605E4801606C49C005486013
+:1029B0001670F8BD0121E0E70120704E4004704F11
+:1029C000012B04D13464506068603964F8BD9060B4
+:1029D000346468603964F8BD01206A4E80046A4F2F
+:1029E000012BF4D1EEE74F484068704770B54A4D6F
+:1029F00028680026564C012806D1A068C00303D5DC
+:102A000001200004A0602E606868012809D1A06838
+:102A1000800306D501204004A0606E6001200BF009
+:102A200041FEA868012809D1A068400306D501200D
+:102A30008004A060AE6002200BF034FE70BD10B5C3
+:102A40004A490878002818D00120444AC0079060FD
+:102A5000434AC00B90602C4A00121060414A00208B
+:102A60001060324A1060404A106008704A78002AAC
+:102A700002D048700BF016FE10BD0320FAE70120CB
+:102A8000424900060860704701202449000608609A
+:102A9000704701203D4940050860704701201F49EB
+:102AA00040050860704733490020C86388151B49FA
+:102AB00008607047410A364AC005C00D5043801C6B
+:102AC0005143400A0818704710B4324C430B63431B
+:102AD0001B0C5C020C602E4C6343C31A2E485C0234
+:102AE00058432B4B400D4343E31A0124DB032404DA
+:102AF0001B191B1613700A681018086010BC704769
+:102B000010B50BF0A2FE10BD80E100E008E400E08B
+:102B100018E400E000B0004040B1004080E200E076
+:102B200000E100E000B5004048B1004040810040B5
+:102B300044B100407372635C72656D5F68616C5F85
+:102B40006576656E745F74696D65722E6300000052
+:102B500000B3004040B3004040B5004000F50140E4
+:102B60000083004040850040008200404800002073
+:102B700000B10040C08F00400085004004B100401B
+:102B800004B5004008B1004008B5004000E200E094
+:102B9000093D0000378600006F0C010010B50BF0F6
+:102BA00040FE10BD00200449C8630120012181407E
+:102BB000024A116000BF7047C01F004080E200E081
+:102BC00010B50CF097FA0AF059F9FEF7DFFB12F096
+:102BD00063FA0CF0F5FF0CF081FF10BD70B50C46E8
+:102BE000054603F0D5FA214628460EF026F870BDBA
+:102BF00070B50D46040012D0002D10D021012846DA
+:102C000013F0F0FA10225449284613F08EFA524875
+:102C100001210838018044804560002070BD0120FA
+:102C200070BD70B54C4E00240546083E11E0716839
+:102C300020014018817BAA7B914209D1C17BEA7BAC
+:102C4000914205D10C22294613F042FA002806D001
+:102C5000641C30888442EADB0020C04370BD2046FB
+:102C600070BD70B50D4606000AD0002D08D03A4C54
+:102C7000083C20886188401C884203D9042070BD2C
+:102C8000102070BD3046FFF7CCFF002801DB401C50
+:102C90000AE020886168000140181022314613F0D4
+:102CA00044FA2088401C20802870002070BD70B538
+:102CB00014460D001FD0002C1DD00021A170022849
+:102CC00002D0102817D108E068782978000208435C
+:102CD00011D00121A17010800BE02846FFF7A1FF61
+:102CE000002808DB401CA070687B297B0002084399
+:102CF0002080002070BD012070BD70B505461446CF
+:102D00000E000AD000203070A878012807D004D91E
+:102D1000114908390A8890420BD9012070BD002C56
+:102D200004D0287820702888000A5070022008708B
+:102D300010E0002C0CD049680001411810222046F8
+:102D4000103913F0F2F9287820732888000A60738C
+:102D500010203070002070BD540000205A4910B57A
+:102D6000884207D301218904884205D3574909685D
+:102D7000884201D2102010BD0146012006F0E4FA7D
+:102D800010BD30B5044693B000200D4607901421C5
+:102D90000BA813F029FA1C21684613F025FA6A469D
+:102DA000112010770020507710780221084310700E
+:102DB00007A80C90012008AA907245486A46108521
+:102DC0000AA80B902088108460885084A088908482
+:102DD000E088D084907FF9210840801C40084000A2
+:102DE000907708209086108708A80F9010AA0BA94A
+:102DF000684600F083FF002803D110A800882880CF
+:102E0000002013B030BD3EB5044608206946088056
+:102E10002D48844207D301208004844205D32B48E7
+:102E20000068844201D210203EBD2146012006F0F8
+:102E30008BFA0028F8D12088694688806088C8808D
+:102E4000A0880881E088488107F05FF801AB6A46F6
+:102E5000002101F0E1FB694609880829E4D003203C
+:102E60003EBD1FB504460020029008206946088137
+:102E700015480391844207D301208004844206D37D
+:102E800012480068844202D2102004B010BD07F03E
+:102E90003CF8014602AA0F4801F055FD0028F4D184
+:102EA00069460989082901D00320EEE769460988A7
+:102EB000218069464988618069468988A180694680
+:102EC000C988E180E1E700000080010028000020BF
+:102ED000042A0000FFFF000010B5031D036000205E
+:102EE000521E04E05C181C60401C2346C0B2904295
+:102EF000F8DB0020186010BD01460A680020002A97
+:102F000002D0104612680A60704702680A600160C9
+:102F10007047000000B51E2823D00BDC0C281CD005
+:102F20001FDC030013F070FB090F1D111D1D171787
+:102F300013151D00302814DD3A38030013F064FB2C
+:102F4000030F11091100002000BD214800BD04201D
+:102F500000BD0D2000BD0F2000BD082000BD1120C8
+:102F600000BD032000BD10B50C4605F0EFFF0028A2
+:102F70001ED0204605F064F9002816D022780E2ACB
+:102F80000DD00F2A0BD0022A09D0032A07D0102A0D
+:102F900009D010A17C2013F046FA002010BDA078C3
+:102FA000FFF7B8FF10BD112010BD0AA18220F2E783
+:102FB00008A18820EFE710B504F083FF10BD10B51D
+:102FC00005F03EF910BD10B504F0D9FF10BD0000AA
+:102FD000023000007372635C686F73745F686369CA
+:102FE0002E63000070477047704770477047704706
+:102FF00070477047704770477047704770470000D0
+:1030000010FFFFFFDBE5B151008001006400FFFF0E
+:1030100003B40148019001BD09000020002803D03D
+:103020008178012939D101E0102070470188FE4ADA
+:10303000881A914233D01BDCFC4A881A91422ED068
+:103040000BDC00292BD00320C002081A27D001284E
+:1030500025D001210903401A07E001281FD00228CA
+:103060001DD0FF281BD0FF380138002815D116E0ED
+:10307000FF220132811A904211D008DC01280ED0C3
+:1030800002280CD0FE280AD0FF2806D107E001292B
+:1030900005D0022903D0032901D0002070470F205A
+:1030A000704700B50B2826D009DC030013F0ACFAFA
+:1030B0000B1D2125251B25292325271F1B00112832
+:1030C0001BD008DC0C2816D00D281CD00F2814D0DB
+:1030D000102808D10FE0822809D084280FD0852835
+:1030E0000FD0872811D0032000BD002000BD05208F
+:1030F00000BDCF4800BD072000BD0F2000BD04204B
+:1031000000BD062000BD0C2000BD0D20800200BDCA
+:1031100070B500290BD0CB1FFA3B81241E46CDB2DF
+:10312000112B1BD2012805D0022806D009E000206F
+:1031300010701DE0FF20043001E0FF2003308142C9
+:1031400018D0330013F060FA111613131613161665
+:103150001316161613131313161316000846FF380A
+:1031600081381F2803D9FF39FE39022902D815708A
+:10317000002070BD1470072070BD00B5030013F06F
+:1031800043FA060406040C080A0C002000BD1120B6
+:1031900000BD072000BD082000BD032000BD007851
+:1031A0000207120F04D0012A05D0022A0AD10EE02C
+:1031B000000907D108E00009012805D0022803D042
+:1031C000032801D0072070470870002070470620B0
+:1031D0007047002807D0012807D0022807D003280D
+:1031E00007D007207047002004E0112002E02120D2
+:1031F00000E0312008700020704738B50C4605000B
+:103200004FD06946FFF7CBFF002822D12088032149
+:1032100089028843694609788907090D0843208097
+:103220006946681CFFF7BBFF002812D121880320E4
+:1032300000038143684600788007800C01432180A9
+:10324000A8784007820F2020012A03D0022A03D049
+:10325000072038BD814300E00143218088B2010589
+:10326000890F08D0012189038843A9780907C90F6C
+:1032700089030843208080B28104890F0AD0A9788D
+:103280004004C906C90F400CC903084320808004CC
+:10329000800F02D12088400403D5208840210843B4
+:1032A0002080002038BD70B50446002008801546F7
+:1032B0006068FFF7A2FF002815D12189A08981420B
+:1032C00010D861688978C90708D00121490288426D
+:1032D00008D8491C12F0A3FF298009E0FF21FF3123
+:1032E000884201D90C2070BDFF30FF3003302880A8
+:1032F000002070BD10B5137804785B08E4075B000C
+:10330000E40F23431370FD2423400478A407E40F43
+:10331000640023431370FB24234004786407E40F04
+:10332000A40023431370F724234004782407E40FF8
+:10333000E40023431370EF2423400478E406E40FF1
+:10334000240123431370DF2423400478A406E40FF0
+:103350006401234313700078BF244006C00F23404C
+:10336000800103431370002906D00878C10701D1FA
+:10337000800701D5012000E00020C0015906490E58
+:103380000843107010BD30B50A8803239B020488DF
+:103390009A4323059D0F02D1A3049C0F01D09B0FDC
+:1033A00000E001239B021A4303230A801B039A4374
+:1033B00003889804840F02D11805830F01D0800F71
+:1033C00000E00120000302430A8030BDF3B593B052
+:1033D0000D000FD0139800280FD01221284612F0AC
+:1033E00001FF03AAFF21012003F0E7F8002426468D
+:1033F00037467AE0102015B0F0BD0720FBE768469D
+:10340000807D01280BD16846818A0520C002081AF8
+:1034100010D0012810D0022812D0032812D0042C7A
+:1034200014D0052C15D113E002290000012800005A
+:1034300003300000012400E002246846468A08E0C8
+:10344000032406E068460424478A02E0052400E0DD
+:1034500006246846418A1398814246D12C74002E76
+:1034600041D00DAA0EA905200292019100901023CF
+:103470000022FF21304603F041F9002823D168469D
+:10348000808E2A46C0B20EA9FFF711FC00281AD17F
+:10349000AE81002F27D00DA9052008AE0291009023
+:1034A000132300220196FF21384603F027F9002854
+:1034B00009D16846808EF11CC01EC0B22A1DFFF7DC
+:1034C000F6FB002801D0032095E708A88178427810
+:1034D00008021043E881062C05D16846807DA87259
+:1034E0006846808A2881002085E703A803F06EF8EB
+:1034F000002884D0FFF7D5FD7DE7002805D0F94AE4
+:10350000012903D0022903D003207047518800E02D
+:103510009188814201D1002070470720704770B523
+:103520000C4605461C21204612F05CFE002020803F
+:10353000002D08D0012D04D0EBA1F04812F073FF4C
+:1035400070BD062000E00520A07070BD70B592B07F
+:103550001546064601206A461071107453740846D9
+:1035600008300395029048889082FEF7E1F9040044
+:1035700019D06580172069468883203600940AABED
+:103580007178023307AA01A80DF05FF9064660784A
+:10359000000701D5FEF7ADF9002E0AD03046FFF73F
+:1035A000ECFD12B070BD1321284607F01BF9032073
+:1035B000F7E708A800906846838B0422012128467B
+:1035C00008F035FEEDE770B506468AB000200D46DE
+:1035D00007900590069003A90490052402460291E5
+:1035E0000190102300942946304603F087F8002804
+:1035F0000DD108A804A9009102900194684683891E
+:1036000000222946304602F095FE002801D0FFF73F
+:1036100048FD0AB070BD10B50DF01DFB10BDF0B532
+:1036200089B000260546059600780C460827030059
+:1036300012F0EAFF0CFD070C3A0B77779EC2FCD81C
+:10364000E8FD68680A38FEF7E8FA0DE1A88800236B
+:1036500080B201220321009009F08CFA0290002C24
+:1036600004D0A648A0A16E3012F0DDFE029800281A
+:1036700004D1A2489CA16F3012F0D5FE02980099A7
+:1036800008300CF017FDFEF753F9040007D06078FE
+:103690003843607000986080FEF72BF9E6E0132154
+:1036A000009807F09FF8EFE0002C04D1BD208EA118
+:1036B000800012F0B8FE608800230122032109F087
+:1036C00059FA0090002804D18C4887A1883012F064
+:1036D000AAFE0099002008802A7994461EE0C300C3
+:1036E0005B199B6807936B469B8B1A0708D5DA0614
+:1036F00006D56046C20050194038C08F088006E0E9
+:103700005B0409D50871C2005019C08848806078F0
+:10371000384360700226A7E0401CC0B28445DED862
+:10372000A2E0E888694608800090002C04D1734824
+:103730006DA1983012F077FE2878062814D10098F1
+:10374000C00B11D0608800230122032109F012FA76
+:10375000060004D1694864A1A23012F064FE002082
+:103760003071A88870803BE06078384360707BE0FF
+:10377000002C04D161485CA1B43012F054FE608882
+:1037800000230122032109F0F5F90090002804D15B
+:103790005A4855A1B73012F046FE009808300DF097
+:1037A000ACFA0121484002D1E888C00B5CD00098F7
+:1037B00061880226C180D7E7002C04D14F484AA176
+:1037C000D03012F030FE608800230122032109F07E
+:1037D000D1F9002804D1494843A1D33012F023FE87
+:1037E0000226C1E7002C04D144483FA1DC3012F08E
+:1037F0001AFE0226618801222046FEF71FFA0120E8
+:103800000590B1E7A889002380B20122032100902E
+:1038100009F0B0F90746002C04D0384832A1EE3048
+:1038200012F001FE002F07D12FA101E00FE016E0FA
+:103830003248EF3012F0F7FD686802902889694637
+:103840008881012202A90098FEF714FA0CE0002CEE
+:103850008AD16D2024A1C00012F0E5FD84E727483D
+:1038600021A1FE3012F0DFFD002C0DD060780007A2
+:103870000AD50598002807D18420207020465822B8
+:1038800029460830FDF7A0FC304609B0F0BDF7B579
+:103890000C460546007A224688B00A320292921CF3
+:1038A00004920027811E16323E4601920B0012F050
+:1038B000ABFE08F605F548488DD1F4F5688800237D
+:1038C0000122032109F056F90190002803D106A135
+:1038D0000B4812F0A8FD01980088002812D052274A
+:1038E000072601E1000900207372635C676174744C
+:1038F000735F636F72652E63000000006F0200004B
+:103900008603000051271E26002C7DD06888A080E9
+:103910000120A071019802990079C0004019C08966
+:10392000FFF754FD002870D101980079C0004019BC
+:10393000C089208101980079C0004019408AA08385
+:10394000F2E0698A0091062820D1E889C00B1DD0D9
+:1039500008462230512786B2002CD6D0A889049977
+:10396000FFF734FD002873D16888A0800220A07181
+:10397000A88920810120A072288AE08300982084F1
+:103980006969009A019812F0D0FBCDE0084620301A
+:10399000502786B2002CB8D0A8890299FFF716FDEF
+:1039A000002855D16888A080A889E080287A062858
+:1039B0000AD002202072288AA0830098E083204643
+:1039C00069692030009ADEE70120F3E76888002368
+:1039D0000122032109F0CEF80690688A009006982B
+:1039E000002803D1FD49FE4812F01DFD069808305D
+:1039F0000DF083F90121484002D1E889C00B26D09F
+:103A00000098223086B201E073E021E05127002CBB
+:103A100079D06888A080A8890499FFF7D7FC00288E
+:103A200016D10220A071A88920810420A072288AC2
+:103A3000E083009820846969009A019812F075FB70
+:103A40000699002008710698A98941806CE003203E
+:103A50000BB0F0BD688805F0D2FB019068880023A8
+:103A60000122032109F086F800900198002804D172
+:103A7000DB48DA492C3012F0D6FC0098002804D13B
+:103A8000D748D6492D3012F0CEFC0098D549C088D1
+:103A9000884205D05127222604E01EE03FE035E0B1
+:103AA00050272026002C2ED06888A080502F07D0C9
+:103AB0000220A0712146287B0831FFF730FD33E05A
+:103AC000287BA11DFFF72BFD6A8800230099019830
+:103AD000FFF73CFD0028BBD126E0C349A889C9886F
+:103AE000814207D154270626002C0CD06888A0807C
+:103AF0001AE008E053270826002C04D06888A0802C
+:103B0000A889E08010E00A98068013E05527072670
+:103B1000002CF8D0A889A0800020A07104E08D209E
+:103B2000AE49C00012F07FFC0A98002C068001D03C
+:103B30002780668000208BE7AB4900200870704723
+:103B400030B585B00C4601F0E0F90546FF2804D1F8
+:103B5000A348A249953012F066FC00202080207115
+:103B60006080401EE0802046294608300CF096FA1E
+:103B70006A462946012002F020FD102412E0684622
+:103B8000808800070ED56846C0882946FFF71BFDD0
+:103B900068468188FF2321438180C0882946019A95
+:103BA00002F036FE684602F011FD0028E7D005B0AD
+:103BB00030BD0A46014610B5104608300CF082FAB6
+:103BC00010BD70B5002305461A46032108F0D2FF48
+:103BD000040004D182488149B73012F024FC204609
+:103BE000294608300CF066FA70BDF0B591B00C466D
+:103BF000074605F004FB050005D02878222804D2EA
+:103C0000082011B0F0BD7948FBE700231A460321D4
+:103C1000384608F0AFFF0646002C02D0A0880028E6
+:103C20000CD00120694608710220087400204874F5
+:103C3000002C05D0A0880883206802E00920E0E776
+:103C4000088305903046083003970290FDF770FE18
+:103C5000040018D0678017206946888320350094B7
+:103C60000AAB6978023307AA01A80CF0EEFD0546FD
+:103C70006078000701D5FDF73CFE002D09D02846ED
+:103C8000FFF77BFABDE71321384606F0ABFD0320B2
+:103C9000B7E708A800906846838B042201213846C4
+:103CA00008F0C5FA0021C943F180AAE7FFB585B045
+:103CB0000E9E7788384605F0A2FA054600231A467C
+:103CC0000321384608F056FF0446002D03D143492E
+:103CD000474812F0A8FB002C04D145483F49401C3E
+:103CE00012F0A1FB0834089869460394C1C105A8E5
+:103CF0000DC8203569780CF017FAC6E5F0B5044612
+:103D0000002099B00D4601460D9010A881811646FD
+:103D100001818180344A68469180018510A8018024
+:103D200068460187818581841078012808D002289F
+:103D300006D0032804D0042802D0082019B0F0BD12
+:103D40002C4A944273D32C4F0121890438688C4249
+:103D500001D3844278D3274A954275D3012189043F
+:103D60008D4201D385426FD36168002913D0214A67
+:103D7000914269D301229204914201D3814263D3DB
+:103D800060892189884203D801225202914201D9D7
+:103D90000C20D3E70D9016AA0EA92846FFF783FA48
+:103DA0000028CBD1686880784007800F02280AD1AC
+:103DB0006846008F8004800F05D02869002802D053
+:103DC0003968884240D30AA92069FFF716FA00280B
+:103DD000B4D1206900281CD060780FE0E8380000DA
+:103DE000EE030000FFFF0000000900200230000089
+:103DF0000C050000008001002800002080076846B4
+:103E0000008D03D58004800F68D002E08004800F0D
+:103E100064D16846008D810618D58004800F6068E3
+:103E200006D0002812D0396888420DD302E00BE09A
+:103E300000280BD0FE49884206D30121890488421C
+:103E400004D33968884201D2102077E709A9606954
+:103E5000FFF7D3F900289CD16069002808D0684694
+:103E6000808C0105890F012938D18004800F35D05D
+:103E70000BA9A069FFF7C1F900288AD16846808C98
+:103E800080062BD46846808D810627D4A16900293D
+:103E900006D00105890F012920D18004800F1DD093
+:103EA000E068002804D00078002817D01C2815D21C
+:103EB00004AA611C2046FFF71DFA0121890210A8FF
+:103EC0000180012768468773DA49818104AA033299
+:103ED00017A92868FEF711FF002801D007202DE759
+:103EE00010A8007F15A9C01CC2B200200C9201903E
+:103EF000FF32009003460291FF3203A8033210996B
+:103F000002F0B3FA002826D110A9888A0F902A89D6
+:103F10002969C94801910092029010A90A8B6B8906
+:103F200028680E9902F0A1FA01007DD1C24800254F
+:103F3000001F818868464174090A8174052104A81C
+:103F40006A4623C210A82A46FF21808A0C9B02F0F1
+:103F5000F1F9002802D0FFF7A4F8EFE66846007CEC
+:103F60000322C1090020920290430122920280188C
+:103F70001490002928D0014610A801806846292104
+:103F8000877309028181058608A8007C0023410807
+:103F900060784900C007C00F014308A80174FD20E4
+:103FA00001406078A54A8007C00F4000014308A87F
+:103FB00001740CA9022001910090029503A81099A8
+:103FC00002F053FA01002FD16068002828D0206940
+:103FD00000280DD10AA90EA8FFF7D5F9607880074F
+:103FE00006D46946088D032109038843694608857C
+:103FF000904968468773FE31818190492089891EE6
+:1040000012F00DF962680D9811AB019200900293C5
+:104010000A46002303A80A9902F027FA010003D1F7
+:104020002078C10603D400E086E080062AD56846E1
+:104030000586606900280DD109A90EA8FFF7A3F92C
+:104040006846818C03208002814301208002091888
+:10405000684681846946888CC821084369468884FB
+:1040600074488F73FF30888112AA0CA90220029233
+:10407000019100900023714A03A8099902F0F5F913
+:10408000010059D12078C00729D068460586A0696B
+:1040900000280DD10BA90EA8FFF775F96846818D90
+:1040A000032080028143012080020918684681852F
+:1040B0006846818D40200143684681858773604949
+:1040C000818113AA0CA90220029201910090002381
+:1040D0005A4A03A80B9902F0C8F901002CD1E068F4
+:1040E00000282DD010A8149901805549684687737F
+:1040F000491C8181E16808A80A78027449784174F2
+:10410000E0684122418868464186E06800230179E1
+:1041100008A80175E068D200C18808A84175090A9D
+:1041200081750CA8072101900091029503A81099B0
+:1041300002F09BF9010003D00F9800F0EAFEFDE5C4
+:104140003D480321001F0170002E0AD08088308076
+:1041500010A88088708010A80089B08010A880897D
+:10416000F0800020EAE530B501248BB015460B46FF
+:10417000012802D002281CD104E06846052184737E
+:10418000C90203E02B4968468473891E8181002B94
+:1041900012D003210020890288430121890240189E
+:1041A0006946888405AA04A91846FEF7A6FD0028DA
+:1041B00004D007200BB030BD1020FBE76A46127C0C
+:1041C0001D480092801E05A9FF3201910290FF3226
+:1041D000002303A80332099902F047F9002802D00E
+:1041E000FEF75FFFE6E71448001F002D01D041886D
+:1041F000298004700020DDE770B592B004460126E6
+:1042000008A886700F496846018410AA08A930469C
+:10421000FFF7A9FF00284DD12078074DC0070024E3
+:104220002D1F002848D01C21684611F0DDFF0BE04F
+:1042300000800100032800000409002003020000A0
+:10424000032900000118000068460178202001437E
+:104250006846017008A88670F9496846018411947F
+:104260000794817FF92001406846891C81770020EE
+:1042700001466846017700200146684641770421DF
+:104280008185C485018607A80A9011A80D9008A809
+:1042900009900EAA09A96846FFF730FD002809D148
+:1042A0006846008FE8806846808F2881401C6881BE
+:1042B0002C70002012B070BDEC802C8110A80088FA
+:1042C000F4E7F7B5DF4900260A789EB0012A04D04A
+:1042D000022A02D0082021B0F0BD4A88824201D0D3
+:1042E0000620F8E71F98824201D10720F3E7012258
+:1042F00010A98A75D4488882002003239B020146B6
+:1043000099439302CB1810A90B8669468A81CF4A3C
+:10431000CA8118A9887110A9888419A904916946CD
+:10432000CA820690FF20087503A802F072F90024E3
+:104330002546274608AA052103A802F06DF90028A2
+:1043400010D082286FD1002C6FD0002D6DD010A816
+:104350008480C5800021017418A8807B11AC0128DD
+:1043600065D06DE008A88079002F21D0012857D1B1
+:104370006846818CB44881421CD113AA0DA905203E
+:104380006B4607C36846408C10230022FF2102F0D1
+:10439000B5F9002868D110A88089042801D0062822
+:1043A0004CD16846818E1F98814239D10F2092E707
+:1043B000012835D16846808C0521C902884202D087
+:1043C000491C88422CD19F4841886846408C8142D4
+:1043D00001D1012700E00027002C01D0002D10D0D2
+:1043E0001F9988421CD113AB0DAA05216E460EC63B
+:1043F000044610230022FF2102F080F9002833D167
+:1044000001E035460CE010A88089022801D0102870
+:1044100014D1C0B21BAA0DA9FEF749FC00280DD18A
+:104420006846468C86E71FE0FFE7052053E714A99E
+:104430001BA8221DFEF761FC002801D003204AE7DB
+:1044400010A8007C0023001DC2B210A8027420989E
+:1044500002900194009215A81C9902F006F8002819
+:1044600002D1784902220A70FEF71BFE33E710B52D
+:104470000B46401E86B084B203AA00211846FEF700
+:1044800039FF04AA052103A802920191009001239B
+:104490000022FF21204601F04DFF04466846008AB5
+:1044A000012804D06D206A49000111F0BCFF2046AC
+:1044B000FEF7F7FD06B010BDF0B5624F0446387840
+:1044C00087B00E46032804D0042802D0082007B085
+:1044D000F0BD04AA03A92046FEF7E5FE0500F6D1CB
+:1044E000606880784007800F02280DD16846808977
+:1044F0008004800F08D02069002805D0554909683C
+:10450000884201D21020E2E7208905AA6B46216982
+:1045100007C369460A8A63892068039901F0A5FFE9
+:10452000002802D0FEF7BDFDD1E7002E02D068467C
+:10453000808A3080042038702846C8E738B50C00DF
+:10454000054609D000236A46FF2102F039F9002808
+:1045500004D0FEF7A6FD38BD102038BD69462046C0
+:10456000FEF74BFE0028F8D1A078FF21C307DB0F30
+:104570002846009A02F04CF9EBE73EB50C0009D052
+:1045800002AB6A46FF2102F01BF9002804D0FEF7B7
+:1045900088FD3EBD10203EBD0321204611F022FEC5
+:1045A0006846008801A90005800FFEF712FE00286A
+:1045B0000BD16846007920706846008801A9800404
+:1045C000800FFEF706FE002801D003203EBD68469E
+:1045D00000796070A278EF20024068460088C10B25
+:1045E00009010A43F7210A404104C90FC9000A43DF
+:1045F000A270F9210A40800601D5022000E00120C6
+:10460000400069460243097A50084000C907C90FB3
+:104610000843A07000203EBD7FB5144605220192DC
+:1046200003AD029500930A462388FF2101F082FE24
+:10463000694689892180FEF734FD04B070BD000011
+:10464000052A00000009002002280000FFFF0000EA
+:10465000E838000028000020F3B5002799B068462C
+:104660000C4607873D4600291ED0E068002806D08A
+:10467000A068002818D001886A4611870780199819
+:1046800004F0BDFD002812D0007822287ED31998AE
+:1046900000F03BFC002300901A460321199808F013
+:1046A00069FA060009D104E010201BB0F0BDFD48F6
+:1046B000FBE7FD49FD4811F0B6FEA078012803D0C4
+:1046C000022801D00720F0E72088002808D0401EEB
+:1046D00080B203AA009901F070FF002859D11DE0B3
+:1046E000F048401CE1E76946498A228891420BD292
+:1046F0006846807D0025012810D16846808AEC49F3
+:1047000088420BD1012509E0914203D1002D2AD026
+:104710006D1C01E0022D0BD0032D04D203A801F083
+:1047200055FF0028DFD082281BD0002831D11DE0A2
+:104730006946897D0129F1D16946DD4B8A8A5B1E74
+:10474000D11A9A420FD005DCDA48101A0BD0012892
+:10475000E4D108E0012906D0FF390129DED1032583
+:10476000E1E7022D15D10D2080029EE7E0680028C8
+:1047700016D00EA9052202910192009069460B8F76
+:10478000A2882088FF2101F0D5FD00E01EE000286E
+:1047900002D0FEF786FC88E76846A168008F088093
+:1047A0006846008AC00601D5C3487EE707980028FE
+:1047B00003D06846008B022801D0032075E70798D4
+:1047C000A1780078012903D0800710D408206CE775
+:1047D000C007FBD000220721199808F010F8002824
+:1047E00002D00725022004E0AE48801C5DE70225C8
+:1047F000032008A908702188684681851998083621
+:104800000A90099617216846818712AB02330FAAD6
+:10481000052108A800970CF018F8002802D0FEF730
+:10482000ACFC42E710A800906846838F042229461A
+:10483000199807F0FCFC38E770B5064615460C469B
+:104840000846FEF7EBFB002804D12A4621463046F5
+:10485000FFF789FCF2E610B5FFF733FD10BD70B528
+:104860001E4614460D0014D0002C12D06168002999
+:104870000FD00121FEF741FE002809D12068FEF784
+:10488000CDFB002804D1324621462846FFF736FAF0
+:10489000D4E61020D2E670B515460C000ED00221E9
+:1048A000FEF72BFE002808D12068FEF7B7FB002892
+:1048B00003D129462046FFF7FFFDBFE61020BDE6E5
+:1048C000F8B506467D480D46016814468A4231D344
+:1048D0006068002808D07A4A90422BD301229204C3
+:1048E000904201D3884225D37648864204D0304690
+:1048F00004F085FC00280CD0304600F006FB06468C
+:10490000284600F0BFFA002804D16068002802D0D1
+:1049100012E06448F8BD00236A463146284601F09B
+:104920004FFF002802D0FEF7BCFBF8BD68460088A8
+:10493000800601D41020F8BD6188224628466368AD
+:10494000FFF76AFEF8BDF7B55C4E0746306886B0E3
+:104950001446824202D2102009B0F0BD384600F061
+:10496000D4FA05465748874201D0FF2D08D00023CE
+:1049700004AA2946079801F023FF002826D101E068
+:104980004848E9E76846008AC00601D54A48E3E797
+:1049900003A9002002910527019000976288494BE6
+:1049A0002946079801F0AAFE00280FD161683268F5
+:1049B000914208D30191029000972388628829468A
+:1049C000079801F09BFE694689892180FEF769FB03
+:1049D000C2E7002907D03C4B0A881B899A4202D8BB
+:1049E0003048401C704737E610B586B004236C464B
+:1049F000A382354BDC88002C07D01B898B4201D267
+:104A0000914204D92748401C54E5062052E56B46E4
+:104A100019825A820021009101911C800221997013
+:104A200005A9029104A903916946FFF715FE41E526
+:104A3000F3B50C4685B0812069460873002C1BD065
+:104A4000059804F0DCFB070018D03878222869D3D9
+:104A5000059800F05AFA049000220121059807F009
+:104A6000CEFE00280CD000231A460321059808F03A
+:104A700081F805000AD105E0102028E5094826E55F
+:104A8000112024E50849114811F0CDFC28460830D2
+:104A90000BF032FB06462078012819D0022838D0C6
+:104AA000072014E502300000E8380000E1080000AB
+:104AB0000328000000280000013400002800002026
+:104AC00000800100FFFF000000090020840A0000B0
+:104AD000A18803AAFEF71CFB0028CED1B00721D580
+:104AE0006846007B00281FD1A079C0071CD0E06871
+:104AF000002205216B4607C36389228968880499CF
+:104B000001F018FC6946087300280DD0FEF7C9FAB9
+:104B1000DDE4A18803AAFEF7FBFA0028ADD134201A
+:104B2000064201D10820D2E46846037B2946384674
+:104B3000059AFEF70BFDCAE4FFB597B0002001907F
+:104B40001F4615460C460E46179804F058FB0028E1
+:104B500004D00078222803D20820A6E5F448A4E572
+:104B6000B80801D00720A0E5032F00D1002717982F
+:104B700000F0CBF90890002C1BD0022D77D3ED4824
+:104B8000006884427CD361190091012902D0491E3A
+:104B9000814275D3AD1EAAB22146E74810F036F81F
+:104BA00000991E394A7F0B7F11021943884267D151
+:104BB000ADB2E248B90702D50189491C00E00121E4
+:104BC00089B20091F90701D0078900E0DA4F03AA02
+:104BD0000899009801F0F1FC0DE0F078B17800023E
+:104BE000084310284CD80199091D401880B2019043
+:104BF000A84245D82618002E60D07078317800027F
+:104C0000084300998842E8D358E06946098A0A07B0
+:104C100054D5002C3FD0019AA618121D92B20992C9
+:104C2000F278B37812021A439446102A28D8099AC7
+:104C30006244AA4224D87278337812021A4390420E
+:104C40001ED1C8061ED509980AAA052120186B4650
+:104C500007C3707831780002084363460022089940
+:104C600001F068FB002803D0FEF71BFA1DE507E002
+:104C7000F078B178000208436946098D884201D076
+:104C80000B2012E5F078B17800020843099940182A
+:104C900080B2019006E0C90604D50899FEF793FC9E
+:104CA0000028E3D16946088A1021884369460882B2
+:104CB000488AFF23049A089901F0AAFD03A801F08D
+:104CC00085FC002803D16846408AB8429DD900235C
+:104CD0001A460321179807F04DFF040003D19849A5
+:104CE000984811F0A0FB20880028BFD0012108A817
+:104CF00001700173002646732188684601862046AC
+:104D00000830099017980A90FCF712FE05001BD096
+:104D10001798688017206946888010AB023301AA73
+:104D2000052108A800950BF090FD0746687800075C
+:104D300004D584488249223011F075FB002F09D038
+:104D40003846FEF71AFAB0E41321179805F04AFD29
+:104D50000320AAE40EA8009068468388042201215B
+:104D6000179807F064FA00288BD126809DE4F0B5EF
+:104D700000248DB01F4615460E46002A04D0B908FF
+:104D800004D007200DB0F0BD1020FBE7032F00D1A9
+:104D9000002700F0BAF80390FF2804D06749B8074D
+:104DA00003D5488902E06248ECE70120FA0702D007
+:104DB0004989491E00E0604906AA8FB2039901F0B3
+:104DC000FCFB38E06946898B090734D504AB052123
+:104DD0000022029300910192574B039901F08EFC3F
+:104DE000002821D1002E21D06A46128A2988A218D3
+:104DF0003019121D914234D36946CA8B0270120ACF
+:104E000042700A8A8270120AC27004A90522001D2B
+:104E10000092029101906946C88B0B8A0022039987
+:104E200001F06CFC002801D00320ABE76846008A43
+:104E30002018001D84B206A801F0C8FB002804D089
+:104E4000822806D0FEF72DF99CE76846C08BB84251
+:104E5000B8D9002C07D0002E10D02988A01C814280
+:104E600003D20C208EE705208CE7224631463248DB
+:104E70000FF0CCFE31190870000A4870A41C2C8079
+:104E800000207FE700B585B06946FEF79FFA00284D
+:104E90000AD16846007C030011F0B6FB08052F2FED
+:104EA0002F2F08080531032005B000BD6846807823
+:104EB000012807D1684600880321C902401A1CD086
+:104EC00001281AD068468079012806D16846808872
+:104ED00015214902401A05280FD96846807A012811
+:104EE00011D16846018929200002081A05D002283C
+:104EF00003D0032801D0042805D10F20D4E712A144
+:104F0000164811F090FA0020CEE710B507F028FE01
+:104F100010BD10B50C4601F023FB002803D00AA1F8
+:104F20000F4811F080FA2046FEF7BBF810BD0000D4
+:104F30000230000028000020FFFF000000090020D0
+:104F4000E83800003F0B00007372635C67617474A3
+:104F5000735F636F72652E63000000002202000021
+:104F6000BB060000F8B500780C46164610340E3625
+:104F7000069F022809D0032836D005287ED0FF20BE
+:104F8000F6A1E53011F04FFAF8BDCD890A2068434B
+:104F90000E30188031203880002AF5D0087B9581AA
+:104FA000801FC7B21AE020886168308048780A788C
+:104FB00000021043F080C8788A78000210433081E4
+:104FC000B21C3846091DFDF772FE002F01D00028E3
+:104FD00002D000203071708008340A3628466D1ED9
+:104FE000ADB20028DFD1F8BDCD890A2068430E306C
+:104FF000188032203880002AF5D0087B9581401F28
+:10500000C7B243E0616822880878F2803279C3072A
+:1050100052085200DB0F1A43FD231A408307DB0FAF
+:105020005B001A43FB231A404307DB0F9B001A4324
+:10503000F7231A400307DB0FDB001A43EF231A4064
+:10504000C306DB0F1B011A43DF231A408306DB0F65
+:105050005B011A43BF231A404306DB0F9B011A432F
+:105060003271C00970718A784B7810021843308110
+:1050700032463846C91CFDF71AFE00E00CE0002855
+:1050800002D00020B070308008340A3628466D1EE9
+:10509000ADB20028B6D1F8BD087BCD89801E86B29E
+:1050A0003046083068431030188034203880002A99
+:1050B000F1D0174695811037E800D681C0190090CD
+:1050C0000DE020883880009878603246616800984A
+:1050D00011F02BF800980834801908370090284602
+:1050E0006D1EADB20028ECD1F8BDFFB581B00A9DB0
+:1050F0001E460C46002A05D0607AFF300130D08071
+:10510000E089108101980E270078030011F07CFAE5
+:105110000B7E0719293541536C7878787E00009210
+:10512000087B082805D0032803D091A1954811F0E9
+:105130007AF9378030200FE000990020888105B08F
+:10514000F0BD0092087B042804D08E4888A114305A
+:1051500011F069F937803120288000980028EBD1C0
+:10516000EDE70092087B042804D0932080A1800002
+:1051700011F059F937803220EEE70092087B0228BF
+:1051800004D080487AA13A3011F04DF937803320AD
+:10519000E2E7087B1746042804D07A4874A14C3013
+:1051A00011F041F91020308034202880002FC6D023
+:1051B0000020B88116E0207B1746052806D0062877
+:1051C00004D070486AA1603011F02DF912203080AF
+:1051D00035202880002FB2D0E089B88100203882A5
+:1051E00001984088F881AAE70092087B072804D03C
+:1051F00064485FA1713011F016F937803620ABE7B3
+:1052000033460095019800F00EFC98E72F2053A13B
+:10521000000111F008F992E770B50C46054603F05D
+:10522000EEFF002804D00078222803D2082070BDA9
+:10523000554870BD00231A460421284607F09AFC01
+:105240002060002801D0002070BD032070BDFFB594
+:105250008BB00D4607461720694608850E98032631
+:105260001446002805D10EA93846FFF7D5FF0028BF
+:1052700034D1002D0BD000220321384607F0BFFAAD
+:10528000002834D00E980078002830D108E020782B
+:10529000092819D00F2823D030A13C4811F0C3F8B9
+:1052A0000E98A760801D03AA606002320AA92046FA
+:1052B00000F00FFC002827D0030011F0A5F9071A11
+:1052C000182323211C1E23000726002231463846BE
+:1052D00007F095FA0028E3D12B48801C0FB0F0BDF1
+:1052E00000220321384607F08AFA0028D8D111207D
+:1052F000F4E70020F2E70820F0E72348401CEDE740
+:105300000720EBE70320E9E701A800906846038D3A
+:1053100004223146384606F08AFF0028DED1002DEF
+:10532000DCD00E990D70D9E730B587B01D460C461C
+:10533000002A11D0042369460B7013888B81528890
+:10534000CA81A2788A7422880A8200236A46294682
+:10535000FFF77DFF07B030BD1020FBE77372635C81
+:1053600067617474635F636F72652E630000000091
+:105370007372635C67617474635F636F72652E63DD
+:105380000000000025020000023000004F03000072
+:10539000F3B581B001980C4600780826030011F09F
+:1053A00033F9125F47471B134B0A0A0A0A0A0A0A13
+:1053B0000A0A0A0A0A5F002C02D1F849F84808E0F4
+:1053C0006078304360703CE0002CF9D1F448F34938
+:1053D000083011F028F8F3E70198002380880122B3
+:1053E00087B20421384607F0C5FB0546002C04D0DF
+:1053F0007520EA49C00011F016F8002D04D1E848E4
+:10540000E649143011F00FF83946A81D00F058FB9A
+:10541000FCF78EFA040006D0607830436070678035
+:10542000FCF767FA0FE01321384605F0DBF915E0C9
+:10543000DB48DA49283002E0D948D8492D3010F04D
+:10544000F2FF002C0AD06078000707D59320207067
+:105450002046582208300199FBF7B6FE0020FEBD19
+:10546000CF48CE493130EAE710B500210170801DE8
+:1054700000F023FB10BD0A4610B50146901D00F058
+:1054800027FB10BD70B5002305461A46042107F01E
+:1054900071FB040004D1F920C049800010F0C3FF63
+:1054A0002946A01D00F00CFB70BDF7B5054684B081
+:1054B0000C4600206946088188806F8803460122D7
+:1054C0000421384607F056FB060004D1FD20B349FD
+:1054D000800010F0A8FF002C03D0A7800020E080FF
+:1054E0002081297A20461230C91E142700900B0013
+:1054F00011F08AF80FFEFDFC3809A95E657A2FB21B
+:10550000C9E99191FC003078012804D0A3497020AA
+:10551000143110F088FFA9896A46C8000E309080C7
+:1055200030201081002C13D0A18100200DE0C1009B
+:10553000327909190A747288CA8182005319DA898A
+:105540004A821A8A401C8A8280B2A1898142EED89E
+:10555000F1E002A8009001AB22462946304600F057
+:105560002BFAE8E03078042804D08C49BD201431AF
+:1055700010F059FFA8890622014650436A460E30B2
+:10558000908033201081002CE2D0A18100200BE01C
+:10559000062141434F190919FA89CA81BA7C8A74D4
+:1055A0003A8A401C0A8280B2A1898142F0D8C2E0C6
+:1055B000307806280BD079491431D72005E03078AF
+:1055C000062804D07549EB20143110F02CFFE8892F
+:1055D00069461230888035200881002CB8D0A9890E
+:1055E000A1817188E18126E03078072804D06B49D9
+:1055F000FF20143110F017FFA8896A4601460E30CB
+:10560000908036201081002CA2D0A1812046AA894A
+:105610000E30296954E0E8896946123080B2382298
+:1056200088800A81002C7ED0A989A181287A10283F
+:1056300007D00221A173E9892182EA8929690098AA
+:105640003EE00121F6E702A8009001AB2246294680
+:105650003046FFF787FC6EE03078082805D04F49C8
+:10566000FF201431EE3010F0DEFE684637218780CF
+:105670000181002C5FD0A989A18100206082208255
+:105680000120A07357E03078092805D04349FF2056
+:105690001431FF3010F0C7FE288A69461430888024
+:1056A00037200881002C46D00421A173A989A1814B
+:1056B000E9892182298A618220462A8A143069690F
+:1056C00010F033FD37E030780A2804D033493548EC
+:1056D000143110F0A8FE6846372187800181002C24
+:1056E00029D00521A1730020A08102E01EE003E083
+:1056F0000CE0208260821EE002A8009001AB2246EE
+:1057000029463046FFF7F1FC15E00CE00D20694614
+:10571000392288800A81002C05D00120E0800020F9
+:105720002081207307E00699088019E01C481B4976
+:10573000A43010F078FE6846069980880880002C16
+:105740000ED0684600892080684680886080287A6C
+:10575000032805D0102803D0112801D00020307074
+:10576000002007B0F0BDF7B5568815460F46002358
+:1057700082B01A460421304607F0FCF9040004D137
+:1057800007480649C43010F04EFEA41D33462A4691
+:1057900039460094029800F022FBD0E45C530000EC
+:1057A0009503000013020000F7B58CB00D461446B7
+:1057B00007A90C98FFF730FD002812D1B64E01273B
+:1057C000002C0FD00321684601701021818208A8A7
+:1057D00002460690204605A9FDF78FFA00280BD057
+:1057E00007207BE50821684601708581C681052177
+:1057F0008774C90201820BE00798A17801712188A2
+:105800004180684605218774C90201828581C6816D
+:1058100002460121079B0C98FFF719FD5EE508B5CC
+:1058200001236A4693709D4B13800A460223694602
+:10583000FFF77AFD08BD08B501236A469370974BC0
+:105840005B1C13800A4603236946FFF76DFD08BD04
+:1058500000B587B000290CD002236A4613700B886C
+:1058600093814988D18100230421FFF7F0FC07B020
+:1058700000BD1020FBE710B5002903D00523FFF77A
+:1058800053FD10BD072010BD70B588B00D461446FD
+:10589000064607A9FFF7C0FC00280DD1002C0DD04B
+:1058A0000621684601708581C481079B02465C80A1
+:1058B00006213046FFF7CBFC08B070BD05216846D5
+:1058C00001708581F1E710B588B000290BD007245D
+:1058D0006B461C709A81049100236A462146FFF7AB
+:1058E000B6FC08B010BD1020FBE770B500241722ED
+:1058F00088B0002914D00D782B0010F085FE062307
+:10590000050519041B231522D21E93B2CA88002A4A
+:1059100002D08E68002E03D09A4203D90C20CBE728
+:105920001020C9E7042D05D08A88002A0AD101E099
+:105930000620C1E7012D11D0022D05D0042D18D06D
+:10594000052D23D00720B7E709236A4613704B883B
+:105950009381CB88D381896804911DE00C236A462A
+:1059600013704B889381CB88D38189680824049174
+:1059700012E00D236A4613704B8893818B88D38184
+:10598000CB88138289680924059105E00E236A46B5
+:105990001370497811730A2400232146FFF757FC3E
+:1059A0008AE700B587B00F236A4613709181002300
+:1059B0001946FFF74CFC5AE7FEB50078089D1C46D7
+:1059C00016460F46012803D03549912010F02BFDD3
+:1059D000F889C0000E30208030202880387B001FDE
+:1059E000C0B20190002E1DD0F889B081002516E0CC
+:1059F000E8008419C0190090224641690E320198CE
+:105A0000FDF755F9002802D000202074E0810098AD
+:105A10006D1C008A60820098ADB2408AA082B08975
+:105A2000A842E5D8FEBD70B514461425049A1D8021
+:105A300037231380002C0ED0CA89A28100226282F3
+:105A40000078082808D0092810D00A2819D014494D
+:105A5000144810F0E8FC70BD087B0C2804D01148F5
+:105A60000F490C3810F0DFFC012008E0087B0D28FE
+:105A700004D00C480A49083810F0D5FC0420A07363
+:105A800070BD087B0E2804D006480549001F10F0A1
+:105A9000CAFC0520F3E70000FFFF00000228000019
+:105AA00070530000BB02000010B5FE4B5860197225
+:105AB0001A80C90010F098FB10BD002101807047CA
+:105AC00010B50022D2430280032007F0F8FC10BD7D
+:105AD0007047F0B50E460446017801208840F2492F
+:105AE00099B008400090616815460888EF4A9042D6
+:105AF00006D0009A002A06D0EB4A521E104202D06D
+:105B0000012019B0F0BD009A10430880002D12D07A
+:105B1000002028702178EA1C0027681C01920B00E5
+:105B200010F072FD10F30E16233A59616F3CB4B0B9
+:105B30008AB8F2F1F0F320780B28EBD00420E0E7EC
+:105B400002212970A1890170090A4170032097E0A0
+:105B500004212970A1890170090A41700198E18925
+:105B60000170090A417005208AE006212970A18987
+:105B70000170090A41700199E2890A70120A4A709B
+:105B8000218A0171090A4171A28AE81DA16910F0F8
+:105B9000CCFAA08AC01D73E0082129702178082959
+:105BA00001D110212970A1890170090A4170019861
+:105BB000E1890170090A41700520308020466A1D84
+:105BC00002A91030FDF799F800287DD16946308888
+:105BD000097A401854E00A212970A1890170090A44
+:105BE000417003200BE00C212970A1890170090A82
+:105BF00041700198E1890170090A417005203080E7
+:105C00009CE0A08984464000401C81B230888842D4
+:105C10005AD3052958D30E202870002008E02369A4
+:105C200042009B5A521953701B0A401C937080B259
+:105C30006045F4D33180B9E09A48417A002973D0A5
+:105C4000491E4172217B4068C9004518A98828680F
+:105C5000082240180838216910F067FA02216846C6
+:105C600001710021417128680390A988684601816B
+:105C7000002101A8FFF78CFB0020A880002E00D097
+:105C8000308093E0297880221143297029784022BE
+:105C90001143297029788909890112312970A18954
+:105CA0000170090A4170E289E81C216910F03DFA8F
+:105CB000E089C01C3080287841063FD5C00975D0E6
+:105CC00001216846017200E02CE000214172318818
+:105CD000091D81810495E189019808180590001D2E
+:105CE00006907048017A68460177002102A8FFF704
+:105CF0004FFB074630880C303080022F06D0002F33
+:105D000054D065E03DE033E01CE05EE06548694664
+:105D1000097F4268CB00D218037A994202D2918857
+:105D2000002902D0042753E02FE0417A491C417238
+:105D30001560308890800020308049E06168A0893B
+:105D4000888033E029788909890116312970A18971
+:105D50000170090A41700198E1890170090A4170D6
+:105D6000228A681D616910F0E0F9208A401D46E72B
+:105D700028788009800118302870207B6870022004
+:105D80007EE760680188090401D4052720E0C08807
+:105D9000A189884201D006271AE01E202870012020
+:105DA0003080606801884904490C0180009800280F
+:105DB0000ED03C4800220088A1688300032007F031
+:105DC000D9FA61682078887007E0002030800327C6
+:105DD0006068009902888A430280384691E6FFB5E0
+:105DE0009FB0289D0E46002805D0172803D82A8882
+:105DF0002E4B9A4202D1072023B0F0BD32785306D1
+:105E000001D4D20901D00820F6E700226B461A71AE
+:105E10005A7114463278431E1D939BB2189303ABFC
+:105E20001A939706CB1CBF0E1B93821E711C3B005E
+:105E300010F0EAFB209011EE66EE74EEB0EED4EEB8
+:105E4000EDEEECEEEBEEEAEEE9EEEEEEE8EEE7EE8E
+:105E5000E6EEE5EE90EE05287CD10421684601715E
+:105E6000A9780172F078B278010211436846418145
+:105E70003179417170788006800E0C282ED009DCB3
+:105E8000801E030010F0C0FB0919661C6621662401
+:105E90006627660012282AD00ADC0E2821D0102896
+:105EA000DAD121E00C090020FF710000FFFF0000A3
+:105EB00016281FD01828CFD11FE02878800701E0CE
+:105EC00028784007002845DA45E128780007F9E7F7
+:105ED0002878C006F6E728788006F3E72878400699
+:105EE000F0E728780006EDE72888C005EAE728886B
+:105EF000C004E7E728888004E4E728884004E1E755
+:105F00002A78920726D50328A6D105206A46107163
+:105F1000487809780002084310811CE12978490774
+:105F2000F0D5062816D3717890B2012902D0022943
+:105F300092D101E0022100E01021189106216A4669
+:105F400011710021118102AF189AB11C0237921C05
+:105F50001B921AE0B3E04A780B7812021A433A8097
+:105F6000801E891C1790BA1C1A911898FCF79FFE86
+:105F70001A991898189A091817986B46801A1A894E
+:105F800080B2521C1A811B9ABF1D8242E3D900289D
+:105F900086D1E0E028780007B4D51D98694682B222
+:105FA0000720087100200881701C0A3111E0437835
+:105FB00007781B023B430B80C37887781B023B4367
+:105FC0004B806F463B89121F5B1C001D92B23B81C8
+:105FD000091D042AEBD2002A71D1BCE02978C90638
+:105FE0006DD502286BD308206946087100204881CE
+:105FF00070780872844692B2B01C1A9919E089E050
+:1060000090E07EE067E05BE030E025E019E013E03F
+:10601000BCE0437807781B023B430B80831C4B603A
+:106020006346D21A6F467B8960445B1C92B27B81C7
+:1060300008319445EDD9CEE7287880063FD509226E
+:1060400003E0287840063AD50A2268460271AA88F9
+:106050000281189A428107E0287800062FD50B208C
+:106060006A46107118981081039174E02988C90557
+:1060700025D5022823D30C206946087100204881C9
+:1060800070780872844692B2B01C1A9914E0437872
+:1060900007781B023B430B80C37887781B023B4386
+:1060A0004B80031D4B606346D21A6F467B89604468
+:1060B0005B1C92B27B8108319445E8D98BE763E0A1
+:1060C0002988C90460D501285ED10D216846017177
+:1060D000A98801813FE02988890455D5052853D333
+:1060E0000E2269460A71AA880A811B99401F4A78C4
+:1060F000097812020A4369464A818881701D04901A
+:1061000029E0298849043FD501283DD10F2069465F
+:10611000087120E02A88120436D44A780B781202DB
+:106120001A43EA8003282FD332789206920E1B2A54
+:1061300026D011226B461A712A880123DB031A43E9
+:106140002A804A78097812020A4369460A81C01EE9
+:1061500048811B98039030788006800E1B2809D058
+:106160001D2807D00320229907F0A9F92888C00B21
+:10617000C003288001A82199FFF70AF920463BE6D1
+:1061800010226B461A71DCE70724F7E70824F5E7CD
+:1061900000B597B0032806D16A461070019100211E
+:1061A0006846FFF7F5F817B000BD000010B58B7812
+:1061B000002B11D082789A4207D10B88002B0BD08C
+:1061C00003E08B79091D002B08D08B789A42F8D117
+:1061D00003880C88A342F4D1002010BD812010BD9B
+:1061E000052826D0002A02D0012A0DD102E0098814
+:1061F000090501E009888904890F07D0012918D011
+:10620000022909D003290ED081207047002A01D02D
+:10621000032070470220704703280AD0042808D0C2
+:10622000002804D007E0042803D0022803D005206A
+:106230007047002070470F20704770B513880546DF
+:1062400014460B8018061DD5FE481022807AA842FD
+:1062500003D813430B80002070BDA06893430078DF
+:10626000E840C007C00E03430B802078A178800768
+:10627000800D0843F4490FF0D2FFA0686943081865
+:10628000401C70BD906870BD37B569468B8813801F
+:1062900019061BD5EB4C0125A47A9168844209D8D4
+:1062A000FE280FD1D80602D5A5406D1E00E00025BE
+:1062B0000D7007E085400C78DB06DB0FAC438340B4
+:1062C0001C430C7010881021884310803EBDF8B527
+:1062D0000746C81C80080E468000B04201D08620C8
+:1062E000F8BD082A01D90E20F8BDD64D00202E6039
+:1062F000AF802881AA723446E88016E0E988491CFC
+:10630000E980810610D48007A178800D0843CE492A
+:106310000FF085FF206800F0BAFA2989401880B292
+:106320002881381A8019A0600C3420884107E5D4F0
+:106330000020F8BDFFB589B09F041646139DBF0C21
+:106340000193099800F095FA04000AD0207800061D
+:1063500009D5BC48817A0A98814204D887200DB0BB
+:10636000F0BD0120FBE7224669460A98FFF765FF6A
+:106370000690002069460872052D14D0012221469E
+:106380002846FFF72DFF0028E9D1207840060AD5DE
+:10639000022168460172099981810188C1810682C2
+:1063A0004782129805900198000404D500273E46C4
+:1063B0000125079709E02078A1788007800D084320
+:1063C000A14907900FF02BFF0D46019840040AD514
+:1063D0000798A84207D12088E1788005800F000245
+:1063E0000843B04201D3AE4201D90720B7E7B8193C
+:1063F00080B20190A84201D90D20B0E76846007A2A
+:10640000002804D002A8FDF706F90028A7D10798B4
+:10641000A8420BD1208803210902884301998905EC
+:10642000890F0902084320800198E0701498002821
+:1064300000D007801298002815D006983A46801997
+:1064400012990FF072FE224669460A98FFF7F5FE90
+:1064500069460888102188436946088022460099C9
+:106460000A98FFF711FF002079E7FFB5754D0C2260
+:10647000E8882968504383B00C180D9F724905982D
+:106480000FF0CDFE0091049800F001FA29682A89E6
+:106490008E46611A0C310918944651188AB2A9889F
+:1064A000914202D8842007B0F0BD6A46168A3206AF
+:1064B00003D5B20601D58520F5E7EA88521C92B2D1
+:1064C000EA800E9B002B00D01A80B20601D5A7608F
+:1064D00006E0604480B22881091A70460818A0605E
+:1064E0002246FE200499FFF7CFFE0598A070009881
+:1064F000E07020880599800889058000890F08438D
+:1065000003210902884300998905890F090208437C
+:1065100004210843208003988078A07103980088A4
+:10652000A08000202073310601D5AC7A00E0012460
+:10653000B10600D5002700260EE0052100200191BC
+:1065400002900097E88831460C9B069AFFF7F2FE0E
+:106550000028A8D1761CF6B2A642EED30020A2E70E
+:10656000F1B5009800F085F9060002D00025009CE6
+:1065700014E00120F8BD204600F07BF907460078C2
+:1065800031498007820DB87810430FF048FE386813
+:1065900000F07DF94019641C85B2A4B22948C18875
+:1065A000601E8142E7DC00992648491EC1800189AE
+:1065B000491B018100203070F8BD002804D0401E26
+:1065C00010809170002070470120704710B504467C
+:1065D00001881C48C288914201D3822010BD006806
+:1065E0000C22514342189079A07290882081108823
+:1065F000D1788005800F00020843A081A078211D7A
+:10660000FFF71BFE20612088401C2080E0800020D6
+:1066100010BD012101827047F7B50546002084B006
+:10662000C043108068681746817868468170686842
+:1066300001886846018000218171288A2C88A04247
+:1066400005D303E0180900200102000004462C8253
+:1066500035E0288A401C2882301D6968FFF7A6FDB6
+:1066600000282AD139889248814201D1601E3880A1
+:106670006888A04228D33088F1788005800F000216
+:10668000084302906946301DFFF790FD002814D1A1
+:106690006989874881421BD0002231460598FFF75F
+:1066A0009FFD002809D16A890298824205D1E968D4
+:1066B000B0680FF00DFD00280AD0641CA4B220467B
+:1066C00000F0D7F80600C4D1641E2C828220EAE6CE
+:1066D0007C80B079B871B088B8803078B1788007A4
+:1066E000800D084378810298B8813946287A32466D
+:1066F0000831FFF7A2FD38610020D4E6FFB585B070
+:106700001C460F46059800F0B4F8050009D028781B
+:10671000000608D56748807AB84204D8872009B0B7
+:10672000F0BD0120FBE707982A468605B60D6946AD
+:106730003846FFF782FD07460E98052816D000223E
+:106740002946FFF74DFD0028E9D1287840060DD5F0
+:106750000121684601710599018101884181868185
+:10676000C48101A8FCF757FF0028D8D12888AA784F
+:106770008107890D11438005800FEA7800021043DC
+:10678000079A964207D04C4A914204D3611E814237
+:1067900001DD0B20C3E7864201D90720BFE7801B3C
+:1067A00082B2A24200D922461098002800D002806E
+:1067B0000F98002802D0B9190FF0B7FC0020AEE7FF
+:1067C000F8B51D4617460E4600F053F8040008D0F1
+:1067D0002078000607D53748807AB04203D8872052
+:1067E000F8BD0120F8BD224639463046FFF725FDA9
+:1067F000002D0BD02078A1788007800D08432E490A
+:10680000884201D2012000E0002028700020F8BD5D
+:10681000F8B51E4617460D4600F02BF8040008D0C8
+:106820002078000607D52348807AA84203D887201D
+:10683000F8BD0120F8BD224639462846FFF724FD61
+:10684000FF2E14D02588A178A807800D08431A4987
+:106850000FF0E5FC002E03D1FF31FF31033189B287
+:10686000A170A80880008905890F084320800020B6
+:10687000F8BD1049CA88824207D3002805D00C22EF
+:10688000096850430C38081870470020704703B55A
+:106890000846694609888A0607D4090604D50549C9
+:1068A000897A4143491C88B20CBD00200CBD000010
+:1068B000FFFF00001809002001020000F8B507786A
+:1068C0000D460446012F19D0072F02D00C2F19D1E5
+:1068D00014E0A068216906780B2E0BD0052006F085
+:1068E000EEFD052E0ED0782300220520216906F04A
+:1068F00041FD07E0782300220620F8E70520216902
+:1069000006F0DDFD002D0ED000202870294620461F
+:1069100004F0AEF9FE482978C05D884201D1032019
+:10692000F8BD0220F8BD0021204604F0A1F90020A6
+:10693000F8BD70B50E460C462036317901208AB07C
+:106940001546002909D0012905D12978042902D149
+:106950000520107000200AB070BD6068019005A885
+:1069600002900D21C01C0FF03DFC032205A8A16878
+:106970000FF0DBFB01203071062069460870206AA9
+:10698000049029466846FFF799FFE4E770B50C4686
+:10699000154620310A790120062686B0002A2CD01F
+:1069A000012A28D12978042925D169681022A068F4
+:1069B00001F0B4F96868C07B000606D5D44AA06827
+:1069C0001023103A014601F09EF91022A168E068F8
+:1069D00001F0A4F9A068C07B000606D5CC4AE068A7
+:1069E0001023103A014601F08EF92E70A0686860FD
+:1069F000E068A860002006B070BD60680190C448DF
+:106A0000203802900120087168460670206A0490C0
+:106A100029466846FFF752FFEDE7027B032A06D0BE
+:106A2000002224235A540B78092B02D003E00420BF
+:106A300070470A76CA61027B9300521C0273C150F0
+:106A400003207047F0B50E4615460C462036024628
+:106A500031790120072393B000290CD0012924D0DB
+:106A600002292ED0032904D12978042901D12B70C1
+:106A7000002013B0F0BD01203071606800280DD0F7
+:106A8000A1690B7060684860206988606069C860AF
+:106A9000206A08621046FFF7C0FFEAE70620287068
+:106AA000206968606069A86009E029780629E0D15A
+:106AB0000220307104202870954820386860032037
+:106AC000D7E729780429D4D1A08910280AD9103809
+:106AD00080B2A081A1681023091805A86A6801F096
+:106AE00012F923E010282FD0C2B21020801AA1681A
+:106AF0000DAF1190C0190FF018FB11980006000E91
+:106B000006D0401EC1B28020785438460FF06AFB90
+:106B1000626910230DA909A801F0F5F8102309A94D
+:106B200005A86A6801F0EFF80320307160680190F1
+:106B300005A80290062069460870206A049029463C
+:106B40006846FFF7BBFE94E710232269A168E2E7DD
+:106B5000F0B50E460C4620363179012006278FB05D
+:106B6000154600290BD0012932D0022905D12978F8
+:106B7000042902D10820107000200FB0F0BD217D43
+:106B800008A8CA07D20F02718807C10F08A80171AF
+:106B90006846027041700722801CE1680FF0C5FA58
+:106BA00002A80722013021690FF0BFFA6068059042
+:106BB0000AA8069010236A46A16801F0A4F80120F3
+:106BC000307168460774206A0890294604A820E0BE
+:106BD00029780429D1D1062205A8E1690FF0A5FA88
+:106BE00006A806220230A1690FF09FFA0020089043
+:106BF0006068019009A80290102305AA696801F055
+:106C000082F80220307168460770206A0490294695
+:106C10006846FFF753FEB0E770B50D460C462035C9
+:106C2000297901208CB01646002909D0012905D107
+:106C30003178042902D10920107000200CB070BDF9
+:106C40006068019006A802900822E1680FF06DFAD2
+:106C5000082208A8A1680FF068FA01202871062010
+:106C600069460870206A049031466846FFF726FEA0
+:106C7000E4E770B50D460C462035297901208CB02B
+:106C80001646002908D00129D8D131780429D5D158
+:106C90000A2010700020D1E76068019006A80290D9
+:106CA0000822A1680FF041FA002008900990012005
+:106CB0002871062069460870206A049031466846AB
+:106CC000FFF7FCFDBAE730B50B4620331C790120F5
+:106CD0008BB0002C09D0012C05D11178042902D1E8
+:106CE0000B20107000200BB030BD4868019005A843
+:106CF00002908C6868462578057564784475CC6880
+:106D0000257885756478C47500200690079001E0A9
+:106D10002867010008900120187106236846037057
+:106D2000086A049011466846FFF7C8FDDBE770B5B6
+:106D30000C462034034625790120002D0AD0012D70
+:106D400014D0022D05D111780A2902D10C2010701F
+:106D5000002070BD01202071C868052202704A68B9
+:106D60004260F84A8260921CC2600BE015780B2DDD
+:106D7000EFD102202071C868042404705268426078
+:106D80008A688260096A016201461846FFF745FE7B
+:106D900070BD30B5011D02463132947803258379E8
+:106DA000ED432C4323408371DB070DD04B7954799D
+:106DB00023404B710B79127913400B718278C9789B
+:106DC0008A4200D9817030BD00224A710A71F5E70C
+:106DD000F7B50C4686B00020694626460870203676
+:106DE000317901271E2015461F2977D24B007B449D
+:106DF0009B885B009F441E0017023E0256026902F8
+:106E000088029A02D102F5022E03590371037F030F
+:106E1000AE03C303CC03F7031A0464049A04AB045F
+:106E2000DF04FE0410052A0565059B05C6058305DC
+:106E300087058B056069002802D0007813287DD073
+:106E4000A0680590002849D0012168460170206A99
+:106E500004900321684601710A214171E0690290A2
+:106E600020790028EFD0059909780029E7D00C296E
+:106E700064D20B000FF0C8FB0CFD1A4B90B5E8FC78
+:106E8000FBFAF9F807FD022828D16069002802D032
+:106E90000078082852D1022168460170206A0490C7
+:106EA00005984178684601710021B9E20620216AFF
+:106EB00006F005FB20790728E6D1606900F050FF55
+:106EC00002280CD0606900F04BFF042807D06069ED
+:106ED0000028B8D000780128D6D103E01BE2616910
+:106EE0000120087005980079C11F0A2901D30A20E2
+:106EF00050E06169072288706069059930300FF0B1
+:106F000014F90120307161690320087034E007280A
+:106F1000BAD16069002896D001780929B4D10599C1
+:106F2000C978890707D1059949790029DFD10599E1
+:106F300089790029DBD105994A7900E04EE20146C2
+:106F400020314B7D9A43D2D1059A8B7D92799A4319
+:106F5000CDD1059A1279D31F0A2BC8D20979914253
+:106F600036D80722C01C05990FF0DFF801203071D8
+:106F700061690A200870032069460870206A04903D
+:106F80006069313001906069001D029060691C30B9
+:106F90000390A1E22076F2E311288DD1606900F020
+:106FA000DFFE042804D0606900F0DAFE0B2893D1DC
+:106FB0006069059910223730491C0FF0B6F86069F6
+:106FC000017804297CD12421095C8278914201D97D
+:106FD0000620DFE70521017003203071684601704B
+:106FE000E2E3112894D1606900F0BAFE062804D0CB
+:106FF000606900F0B5FE0C288AD1E068002813D043
+:107000002069002810D060690178062910D00D2170
+:1070100001706069059910225730491C0FF085F8FE
+:107020006069573009218CE100206946087072E1DF
+:10703000072101706069059910224730491C0FF043
+:1070400074F860694730EDE70228F0D1606900F01C
+:1070500087FE0028EBD0606900F082FE0128E6D0B0
+:10706000606900F07DFE05E0B1E08DE06CE02AE0B3
+:107070000AE0D6E00828DAD00521684601710598B3
+:1070800041786846417146E11128D0D160690028F5
+:10709000CDD001780E29CAD1C16A4078022810D01B
+:1070A0000020142250431430085805991022491C1E
+:1070B0000FF03BF80520216A00F040FE0F205EE053
+:1070C000F1E10120EDE70B28B1D160690028AED0D5
+:1070D00001780F29ABD1C16A4078022826D0002060
+:1070E000142250430C300958059842780A70807871
+:1070F00048706069C16A4078022819D000201422C3
+:1071000050431030085805990822C91C0FF00DF89B
+:107110000520216A00F012FE60694178022909D039
+:1071200000220832825C5208520073E00120D7E747
+:107130000120E4E70122F4E7012100E00021083109
+:107140004254BCE30267010011289CD16069002809
+:1071500099D00178102996D1C16A4078022811D0BF
+:107160000020142250431830085805991022491C59
+:107170000EF0DBFF0520216A00F0E0FD11206169BF
+:107180000870B4E30120ECE7082884D16069002886
+:107190009DD00178112997D10599C06A497801706D
+:1071A00060690599C06A0622401C891C0EF0BDFF6B
+:1071B0000520216A00F0C2FD60694178022904D0EF
+:1071C00000220832825CFD2323E00122F9E7112826
+:1071D000BBD160690028BBD001781229B5D1C16A42
+:1071E0004078022819D00020142250431C3008583F
+:1071F00005991022491C0EF098FF0520216A00F025
+:107200009DFD60694178022909D000220832825C24
+:10721000FB231A40022991D18EE70120E4E70122E5
+:10722000F4E70720B6E6287801288ED160696968FE
+:1072300014221C30F9F7C8FF6069017F002901D0D2
+:107240002176ACE30178032901D0032037E002273F
+:10725000C77081794907490F8171017A4907490F40
+:107260000172417A4907490F41726069FFF791FD48
+:10727000377196E228780F28E3D107206946087015
+:10728000216A049191680291694608716169072237
+:10729000C91C02980EF049FF6169042008700020A3
+:1072A0003071BBE028780328CBD1606901780529CB
+:1072B000696807D0082247300EF037FF042030718C
+:1072C00005206FE208225730F6E728780328B8D166
+:1072D000606901780529696811D008224F300EF0E5
+:1072E00024FF052030716069006A00280AD002205E
+:1072F0002870002028716069006AA860F9E00822FF
+:107300005F30ECE704204DE22878022899D12879F3
+:10731000002801D0207642E36069A96801626069B3
+:10732000002901D1F949016206200BE228780F28D3
+:1073300087D1A868E0616069017805292BD04730C2
+:1073400007213171E16802220A706269126A4A609B
+:10735000886060693030C8606069C01C086162691B
+:10736000087D926A400812784000D207D20F10437D
+:1073700008756269926A521C8A61FD221040626936
+:10738000D26A1278D207920F104308756069C06AFA
+:10739000401CC86153E25730D2E728780828BAD198
+:1073A0006069017805291AD00B2101700720694610
+:1073B0000870206A0490E069029011200871029818
+:1073C0000321017051681022401C0EF0AEFE002116
+:1073D0006846FFF773FA00203071E06187E206210A
+:1073E000E3E728780F2896D1072069460870206ABD
+:1073F0000490A8680290112008710298042101707D
+:1074000061690A78072A0ED0002232710C220A70B4
+:1074100061691022401C47310EF087FE002168464A
+:10742000FFF74CFA63E21022401C57310EF07DFE4C
+:1074300000216846FFF742FA0A203071E168032014
+:1074400008706069006A48606069573088606069E8
+:107450004730F3E128780828A1D1606969681022D3
+:1074600037300EF035FE002801D0042092E5606927
+:107470000078072817D00A203071E16803200870CF
+:107480006069006A486060695730886060694730A9
+:10749000C860206A08620698FFF7BFFA074660696D
+:1074A000FFF777FC6BE208207AE1287809289AD167
+:1074B0000B20307161696868897810224018511A70
+:1074C0000EF090FE082069460870206A04906868F3
+:1074D000019060698078087268E129780D29BBD134
+:1074E00061698979C90703D00C20307109203EE019
+:1074F0003071032770E228780E28ADD1606914221C
+:10750000291D1C30F9F760FE6069018DC06A417267
+:10751000090A817260698178C06AC1716169CA6A49
+:10752000081D117AC909C9011172437962691943A9
+:107530008378D26A9B079B0F012B00D00023007930
+:107540009B01C00003431943117260694078012810
+:1075500076D0B4E160694178022901D0012100E0D0
+:1075600000210831405CC00707D00E20EAE06946E0
+:107570000870206A1146049019E11320B8E72878B2
+:107580000F2894D1A868E0610F2030710520EEE744
+:10759000287803288BD16069C16A4078022801D01D
+:1075A000012000E000201422504310300858082227
+:1075B00069680EF0BAFD10203071E168062022697A
+:1075C00008706069406A48606069C36A4078022850
+:1075D00001D0012000E00020142778431030185813
+:1075E000CA6088602BE128780C2886D16069C26A5D
+:1075F0004078022801D0012000E0002014214843F7
+:107600000C30105802230932696800F07CFB11200D
+:107610003071E168052008706069006A486060693F
+:10762000C06A093088603948001F07E128780B28B4
+:10763000A7D161694878CA6A022802D0012001E016
+:1076400059E1002014235843143010588A7869688F
+:107650000EF06BFD60694178C26A022901D00121F8
+:1076600000E00021142359431431525881785018F6
+:107670001022511A0EF0B6FD072069460870206AE4
+:107680000490E069029011200871029806210170AF
+:107690006169CA6A4978022901D0012100E000210C
+:1076A00014235943143151581022401C0EF03DFD53
+:1076B00000216846FFF702F90020E06112206FE028
+:1076C00028780F2891D1072168460170206A04901C
+:1076D000906802900B2268460271029801706169FD
+:1076E000CA6A4978022901D0012100E0002114234F
+:1076F00059430C3151580A78427049788170616958
+:10770000CA6A4978022903D0012102E00867010012
+:10771000002114235943103151580822C01C0EF087
+:1077200004FD00216846FFF7C9F826E76069417843
+:10773000022901D0012100E000210831405C8007CE
+:1077400003D5142030710A2011E71620D0E62878DE
+:107750000F287AD1A868E061072069460870206A7E
+:107760000490E069029011200871029808210170CC
+:107770006169CA6A4978022902D0012101E011E158
+:10778000002114235943183151581022401C0EF087
+:10779000CCFC00216846FFF791F80020E06115203D
+:1077A00030710A2069460870206A049029466846AC
+:1077B000FFF784F82BE028780F2846D10720694688
+:1077C0000870206A0490906802900820087102985E
+:1077D0000921017061690622C969097841706169EE
+:1077E000801CC969491C0EF0A0FC00216846FFF707
+:1077F00065F8AAE760694178022901D0012200E01A
+:1078000000220832805C400703D51720C8E70746EE
+:10781000B5E0012953D070E028780F2815D1A86869
+:10782000E06118203071E168052008706069006A25
+:1078300048606069C06A09308860F848C860206A9A
+:1078400008620698FFF7E9F8E1E76FE028780B286F
+:107850006CD16069C16A4078022801D0012000E043
+:107860000020142250431C300858102269680EF082
+:107870005CFC072069460870206A0490E069029069
+:107880001120087102980A2101706169CA6A497859
+:10789000022901D0012100E00021142359431C31A9
+:1078A00051581022401C0EF040FC00216846FFF7A2
+:1078B00005F80020E0616069407801281DD1192099
+:1078C00016E660694278022A09D000210831411881
+:1078D000097800290DD0CA0703D00E2106E0012146
+:1078E000F4E7890701D5102100E01221017000277B
+:1078F00072E0012A01D00D20FAE51C20F8E51D20D8
+:1079000030710B2033E62978102948D1F0E5606901
+:107910000178012943D0082941D00021317100F0BC
+:1079200019FA0C2069460870206A049037E028781C
+:107930000F2805D01020107003271B2030714BE05A
+:10794000072168460170206A0490A868029002210D
+:1079500068460171029805210170217E4170002165
+:107960006846FEF7ABFF0B2168460170206A049061
+:1079700029466846FEF7A2FF07461B203071012FFB
+:107980000DD029E0012168460170206A049004218D
+:1079900068460171217E41710020207612E0207E30
+:1079A00000280FD06169132008701A2030710A2056
+:1079B00069460870206A049029466846FEF77EFFF3
+:1079C000074609E06069002801D01421017068466B
+:1079D0000078002800D021E5384609B0F0BDF7B5A1
+:1079E0000F4620373879012686B00C46002804D08F
+:1079F000012828D002281CD197E02079012804D042
+:107A0000022811D0032814D10AE0A0684078012888
+:107A10000ED10620216A05F02CFD00287FD10CE054
+:107A2000A1681320087008E0A0684178022901D0FD
+:107A3000052674E00078082871D1012038710A20E9
+:107A40006946087033E0089800780F2867D107214D
+:107A500068460170206A049008988568029522792A
+:107A60000220012A04D0022A29D0032A57D10FE08C
+:107A70000646684606710B202870207B00214007CF
+:107A8000400F68706846FEF719FFA068067045E071
+:107A900006466846067105202870207B6870002124
+:107AA0006846FEF70BFF3E710B2168460170206AA5
+:107AB000049068460899FEF701FF06462FE06846E5
+:107AC000017101202870207C6870607CC007C00FA5
+:107AD000A870A07C4007400FE870E17C2971C007C6
+:107AE0001FD0207D4007400F6871607D4007400F28
+:107AF000A87100216846FEF7E1FEA068072229462A
+:107B000030300EF012FBE068017AA068203001717D
+:107B1000A16828798870A16809200870002630467D
+:107B20005BE70020A8716871E3E7A1681420087082
+:107B3000012168460170206A0490042168460171A1
+:107B4000217B41710021FEF7B9FEE7E7F0B585B072
+:107B50000F4605460124287B800040198038C66FF7
+:107B60003078411E0A290AD22C498000323140184F
+:107B70008038C36F3A463146284698470446002C61
+:107B800001D0012C11D1287B401E0006000E287365
+:107B900001D00324DFE70D2069460870306A0490A5
+:107BA000002101966846FEF789FE032CD3D02046BB
+:107BB00005B0F0BD70B515460A4604462946104684
+:107BC000FFF7C4FF0646002C0FD0207814280CD1F4
+:107BD000207E002806D000202870204629460C3040
+:107BE000FFF7B4FF204600F0B5F8304670BD70478F
+:107BF00010B5012903D0022901D0052010BD417024
+:107C000000F0A8F8002010BD002809D0027E002A4C
+:107C100006D00A4601460C31CCE700000667010099
+:107C20000120704730B5044687B00D46062005F0A8
+:107C300046FC2946052005F042FC2078142805D092
+:107C40000020694608702046FFF7DEFF07B030BD10
+:107C50007FB50E4600216A4611730178092903D0C9
+:107C60000A2903D0002407E0446900E08468002C5E
+:107C700002D0217E002912D0154601462846FEF783
+:107C8000CCFE032809D1324629462046FFF792FF51
+:107C90006946097B002900D0042004B070BD254648
+:107CA0000C35EAE700B50023012285B005280CD089
+:107CB000062808D1684602700491022101714371BF
+:107CC0000021FEF7FBFD05B000BD6846027004917F
+:107CD0000271F4E710B590B00C4605216A461170A8
+:107CE000019022480290001D03900AA96846FFF700
+:107CF000AFFF002805D1102220460B990EF015FA8F
+:107D0000002010B010BD30B505E05B1EDBB2CC5CCE
+:107D1000D55C6C40C454002BF7D130BD10B50024A5
+:107D200009E00B78521E5B00234303700B78401C64
+:107D3000DC09D2B2491C002AF3D110BD70B50C4643
+:107D4000054605F0BCFB782300222146284605F0B5
+:107D500011FB70BD4178012900D0082101707047E6
+:107D6000002801D0007870470820704700670100A4
+:107D700038B50446002069460870204609F053FDD6
+:107D8000002803D1FBA1A3200EF04DFB204609F0F3
+:107D900099FC002803D1F7A1A8200EF044FB684607
+:107DA000007838BD70B5F84D002428462C77203077
+:107DB0008471C47101F09AF928464038047020306B
+:107DC0008473847484772C75AC7170BD10B50C46C7
+:107DD000EE4982888A8042884A8000780870084686
+:107DE0000E38847009F050FC08F0FDFFFFF7DAFF51
+:107DF00020460BF013F8E449A8310846813809F011
+:107E0000ADFEE2480CF021FBE0480A3808F0FEFF26
+:107E1000002803D0D7A1C5200EF005FB01F066F9BC
+:107E200010BD7CB50E461D46144601A909F008F8A0
+:107E3000002807D10AF091FB022803D1D248007D27
+:107E4000002801D001207CBD01988030807C09F0A1
+:107E50004DFC00280CD0684609F052FC0028F2D0F6
+:107E6000002C03D009F011FCA04206D200207CBDFA
+:107E7000C0A1C7480EF0D7FAF8E7009809F0D8F883
+:107E80003146009809F0DBF8E2B22946009809F083
+:107E9000F0F909F045FC002804D1BD48B5A11E3019
+:107EA0000EF0C1FAB94C00250E3C6068A030417953
+:107EB000002902D045710BF0D8F860688030458306
+:107EC000C0E730B40179002904D0012907D030BCC3
+:107ED00000207047831D42880488022103E0428805
+:107EE0000488831D0121204630BC9AE7F8B51D4661
+:107EF00014460E4607460AF030FB022803D0A2487B
+:107F0000007D002823D0A1480E3841684988398077
+:107F100040688030807C09F069FD002804D153203E
+:107F200094A1C0000EF07FFA684609F069FD0028B0
+:107F30000DD0009809F0BAF83070022808D0012856
+:107F400006D093488BA167300EF06DFA0020F8BD83
+:107F50002946009809F0A4F92080002804D1552072
+:107F600084A1C0000EF05FFA09F05DFD002804D185
+:107F7000874880A160300EF056FA0120F8BD38B570
+:107F80000446831D821C6946FFF7B0FF00280DD010
+:107F90000020607168460078012808D0022806D0C9
+:107FA000FF2074A101300EF03EFA012038BD20718F
+:107FB000FBE7F8B50AF0D1FA744D734C0E3D022878
+:107FC00002D0207D00287DD0207F0026102818D1E7
+:107FD000A079002803D067A16E480EF024FA6868E3
+:107FE00001464030827F92070BD526724988618115
+:107FF000C17F2173018CE181408C20820120A0711E
+:108000002677614F203FB87C00285ED168686946BA
+:108010008030807C09F007FC002805D0694668782C
+:1080200009784018687004E05A4852A119300EF0DF
+:10803000FAF9207D00283AD06868418852484038D3
+:10804000806D4088814204D00F204AA1C0010EF00B
+:10805000EAF968688030807C09F0C8FC002804D107
+:108060004C4844A124300EF0DEF909F0EEFC002863
+:108070001DD068688030807CFFF77AFE69784018F0
+:10808000687041484038806D4030417A01290DD1F7
+:108090002670696849886180807A20710120B877EC
+:1080A000207F102801D0282800D1267726756978EE
+:1080B00000290AD06868428833484038C286018760
+:1080C000012000E001E0B8746E700AF029FA00287F
+:1080D00005D1207D002802D0A878FAF7F9F8F8BD7C
+:1080E000F8B50446FFF765FF274D0026203DA87E22
+:1080F000002808D0667010202070E87EA070287FCD
+:10810000E070AE769AE0204F403F3878002808D0E3
+:108110002C22B91C20460EF008F80E2020703E706C
+:108120008CE0A87B184F002815D0387F102808D085
+:10813000282806D0002804D0FF200EA1C2300EF05F
+:1081400072F90120E070E87BA070287C60700F203D
+:108150002070AE7372E00121204609F099FC0028DE
+:108160001AD0387D002857D10021204609F090FC14
+:10817000F8BD00007372635C6C6C5F6374726C2E8C
+:1081800073302E630000000094090020720000206C
+:108190004F02000062070000A97CF8480090F848F0
+:1081A000002910D0017805290DD2491C0170667094
+:1081B0000D202070012028750622A01C00990DF0CA
+:1081C000B4FFAE743AE0EE480670B879002812D0D9
+:1081D000387F002804D00120EA4940020EF023F93C
+:1081E00066700120E54920700A221431A01C0DF0B0
+:1081F0009CFFBE7122E020460CF083F800281DD1C0
+:10820000A87C002802D0DE480178CEE7A87F0028AD
+:1082100002D0387D002801D00020A9E7387F00284F
+:1082200003D0D849D8480EF0FEF866700A202070B6
+:1082300006223946A01C0DF078FFAE77012097E7A3
+:108240004EE710B5CD4C343C2178002904D01321E1
+:108250000E2000F052FF10BDC9490088091D08F02A
+:10826000EFFD002801D0022007E0C5484068014624
+:1082700020318A79012A02D00C20207105E00022E9
+:108280002271097E21724088E080012060711321F3
+:10829000E1700E21A170207010BDB84810B53438BF
+:1082A0000178002904D024210E2000F026FF10BD03
+:1082B000012101702422C2700C220271417110BD93
+:1082C00070B5AE4C0546343C2078002804D03E21E1
+:1082D0000E2000F012FF70BD0AF03FF9002808D10F
+:1082E0000AF03EF9002804D1A4480C30007F002891
+:1082F00001D00C2003E0287809F033FD0020207124
+:10830000012060713E21E170207070BD9B4810B566
+:1083100034380178002904D03C210E2000F0EDFE15
+:1083200010BD00210171012141713C22C270017018
+:1083300010BDF8B5914C343C2078002804D03B2186
+:108340000E2000F0DAFE13E70020A0710AF005F914
+:108350008A4E01250C36022802D0307D002840D0FC
+:10836000874F694678688030807C09F073FA00286E
+:1083700003D1844985480EF056F8307D002806D098
+:10838000A06D4030407A002801D0012600E0002690
+:1083900078688030807C09F029FB002804D17B4874
+:1083A000784908300EF03FF809F04FFB684031463D
+:1083B000014316D07968FD2249882181217E400041
+:1083C000490849003143114001432176684600784D
+:1083D000002802D00420014301E0FB200140217667
+:1083E000A5710020207165713B20E0702570BFE60B
+:1083F00010B5624C343C2078002804D00E21084689
+:1084000000F07BFE10BD5E4906220831A01D0DF074
+:108410008CFE00202071012060710E21E17020701F
+:1084200010BD70B5554C0546343C2078002804D06A
+:1084300038210E2000F061FE70BD50480C30007FE6
+:10844000002807D00C202071012060713821E170D4
+:10845000207070BD287809F072FC28780CF05BF968
+:108460000020F0E770B5454D0446343D28780028DB
+:1084700004D037210E2000F040FE70BD3F480C3084
+:10848000007F002801D00C200AE03D4E2188706852
+:108490004088884203D10AF060F8022807D0022001
+:1084A0002871012068713721E970287070BD7168EA
+:1084B0007F2020310876487600208876A2788A715D
+:1084C000E278CA7122790A72EAE710B52B4C343C83
+:1084D0002078002804D039210E2000F00EFE10BDB7
+:1084E0000AF03BF8032808D00AF03AF8032804D031
+:1084F00022480C30007F002801D00C2003E01F49E7
+:1085000000202C31C8712071012060713921E17087
+:10851000207010BD70B5194C0646343C20780028F8
+:1085200004D03A210E2000F0E8FD70BD0AF015F8E5
+:10853000032808D00AF014F8032804D00F480C30A0
+:10854000007F002801D00C2011E00C4D2C35E8797B
+:1085500008280BD20001001910223146683000F0C3
+:10856000D6FDE879401CE871002000E0072020716A
+:10857000012060713A21E170207070BD88090020EF
+:108580006400002074810000210200001708000030
+:10859000F8B5FA4E04463078002804D03D210E206C
+:1085A00000F0ABFDE4E5F5484030007F002801D045
+:1085B0000C2034E0F24D218868684088884203D15D
+:1085C00009F0CBFF022801D0022028E06F68648800
+:1085D000FD883A896800B988401C844218D3E9486C
+:1085E00041431046E84A50430DF019FE401EFF215A
+:1085F00080B2F531884200D90846844200D2204634
+:10860000691C401C0DF00BFE6D1C6843401E85B2BA
+:10861000E620C05D002800D1BD84F58000203071C7
+:10862000012070713D21F1703070A1E5F8B5D34C97
+:1086300005462078002804D035210E2000F05DFD8D
+:1086400096E5CE484030007F002801D00C2016E08F
+:10865000A878002801D0012804D1A888FF21F5318D
+:10866000884201D912200AE0C54F298878684088DD
+:10867000884203D109F071FF022807D0022020713F
+:10868000012060713521E170207071E57968002664
+:108690000846C0310E70AA884A800122A0300271BB
+:1086A000AA78012A00D000220A704079002801D05F
+:1086B0000AF0DBFC2671E3E770B5B04C0546207884
+:1086C000002804D030210E2000F017FD55E709F0F6
+:1086D00044FF002804D1A9484030007F002801D081
+:1086E0000C2003E028780AF0E0FB00202071012034
+:1086F00060713021E17020703FE770B59F4C0546F6
+:108700002078002804D033210E2000F0F6FC34E756
+:1087100009F023FF002804D198484030007F00284A
+:1087200001D00C2018E02978002911D00A290FD097
+:1087300014290DD01E290BD0282909D0322907D0A1
+:108740004B2905D0642903D0FF2901D0122003E072
+:1087500028460AF023FC002020710120607133219B
+:10876000E170207009E770B5844C06462078251D1D
+:10877000002804D032210E2000F0BFFCFDE6314677
+:10878000002009F0AEFA2870002805D17C480622A6
+:10879000314608300DF0C9FC012060713221E170D2
+:1087A0002070EAE670B5754C2178002904D031219B
+:1087B0000E2000F0A2FCE0E600214156012504292C
+:1087C00012D0002910D0081D0ED0001D0CD0001DA5
+:1087D0000AD0001D08D0001D06D00A3004D00A308F
+:1087E00002D01220207103E0084606F079FD657181
+:1087F0003120E0702570C0E6FEB5604C0746207859
+:10880000002804D025210E2000F077FCFEBD38881A
+:10881000694608F015FB594D01460020083500292E
+:1088200004D002212171286028710FE00098009E79
+:108830000A30019060360020B07105222846019967
+:108840000DF073FCB0790028F5D13888E0800E2057
+:10885000A0702520E070012060712070FEBD10B571
+:10886000464C2078002804D005210E2000F045FC5D
+:1088700010BD0020207108F008FFE08008F0D1FF53
+:108880002072012060710521E170207010BDF1B5EA
+:108890003A4C2034A07B002804D010210F2000F097
+:1088A0002CFC65E4354D4035A8790C2610270028AE
+:1088B00016D1287F002813D109F04FFE022824D1B9
+:1088C0002F4800994068098842888A421DD1014694
+:1088D000C0310A7A002A05D04030807F80070DD44D
+:1088E000E6730EE05E22125C920707D406220A723B
+:1088F000A0304079002801D00AF0B7FB2F77002084
+:10890000E07327740120A07332E40220F8E710B569
+:108910001A480178002904D00F210E2000F0EDFB49
+:1089200010BD00210171FF2181710021C943018126
+:1089300013490E310A7882728A8882814988C181FE
+:10894000012141710E2282700F22C270017010BD90
+:1089500010B50A4C2078002804D02B210E2000F0FE
+:10896000CCFB10BD0821A01D04F024FB00202071C9
+:10897000012060712B21E170207010BD540900208E
+:1089800064000020C40900001027000070B5FA4DF3
+:1089900004462878002804D02A210E2000F0ADFBE0
+:1089A000EBE5F54810222146303800F0B0FBF248E4
+:1089B0001022A118203800F0AAFBEF4830380CF044
+:1089C000BCFBED49102210392C46A81D00F09FFB7E
+:1089D000002020710E20A0702A20E070012060711C
+:1089E0002070CAE5F8B50546E348E34C40300090F6
+:1089F000007F0C2628272034002801D0E6733EE0B3
+:108A0000A07B002804D028210F2000F076FB04E48E
+:108A1000A87805280DD013280BD0142809D01528C4
+:108A200007D01A2805D0292803D03D2801D03B289B
+:108A300003D12888D149884201D912201EE009F0CB
+:108A40008CFD0228DAD1CE482A88406841889142BC
+:108A500013D10146C0310A79002ACFD1AA784A71D0
+:108A600001220A710099A0300F770021E17340794B
+:108A7000002804D00AF0F9FA01E00220E07327741C
+:108A80000120A0735FE4F8B5BB4F064638783D1D62
+:108A9000002804D017210E2000F02FFB53E43146AC
+:108AA000012009F01EF901242870002807D1B248DE
+:108AB00006226030314605460DF037FBAC717C7103
+:108AC0001720F8703C703EE470B5AB4C0646207839
+:108AD000002804D00B210E2000F00FFB4DE509F01B
+:108AE0003CFD032808D009F03BFD032804D0A24830
+:108AF0004030007F002801D00C2016E03378002B96
+:108B000003D0012B01D012200FE09B4DE035297AD4
+:108B1000082909D22846721C0C3006F097FB287AE7
+:108B2000401C2872002000E00720207101206071A5
+:108B30000B21E170207020E510B58F4C20780028C3
+:108B400004D00A210E2000F0D8FA16E709F005FD3E
+:108B5000032808D009F004FD032804D086484030DB
+:108B6000007F002801D00C2002E000F0BFFA0020B6
+:108B70002071012060710A21E1702070FDE610B5BE
+:108B80000AF032F9002803D07E497F480DF04BFCF3
+:108B900008F04BFD0BF051FC002804D01720794958
+:108BA00040010DF040FC08F0ACFF002804D0B920D3
+:108BB000744980000DF037FC00F098FAFFF7F2F8E6
+:108BC0006D4800210171012141710222C2700170C2
+:108BD000D3E610B5684C2178002904D020210E205E
+:108BE00000F08BFAC9E601781F290ED8411C0CD081
+:108BF000002121710278411C104609F08FF80120F4
+:108C000060712021E1702070B7E612202071F6E734
+:108C1000F8B5594C2178002904D01B210E2000F012
+:108C20006CFABFE401216171534E0C212171403671
+:108C3000317F00296FD10078514F0025012804D0E1
+:108C400000284AD01220207165E009F086FC002837
+:108C500003D109F085FC002804D009F07EFC02282D
+:108C600022D058E008F08FFF002854D0307D002833
+:108C700051D1786801224580032108F0B4FB78685F
+:108C800009F05AF97868923008F001FD002803D104
+:108C90003C493E480DF0C7FB0AF00BF9002839D0DB
+:108CA00085203849C00015E009F05AFC002832D16F
+:108CB000707F00282FD001282DD004282BD008F059
+:108CC00062FF002827D00AF0F4F8002822D02F48AD
+:108CD0002C4918300DF0A7FB1CE009F03EFC0328DE
+:108CE00004D009F03DFC03280FD014E000200AF066
+:108CF00005F800280FD12571307D00280BD1786848
+:108D00008030807CFFF734F805E0002009F0F6FFA2
+:108D1000002800D125711B20E0700120207041E463
+:108D200010B5154C2178002904D01A210E2000F02E
+:108D3000E4F922E601781F290ED8411C0CD000214D
+:108D400021710278411C104608F0FDFF012060717E
+:108D50001A21E170207010E612202071F6E770B53C
+:108D6000054E044630780C25002811D018210E201D
+:108D700000F0C3F9AAE4000054090020FF0E00002F
+:108D80006400002074810000D3020000240400006D
+:108D900009F0E3FB03285AD009F0E2FB032856D080
+:108DA000E14A107F002852D16079002801D00128C3
+:108DB0002DD1A079002801D0012828D1A07B00283E
+:108DC00005D0012803D0022801D003281FD1607BE1
+:108DD00000281CD0C0081AD161880120800381427C
+:108DE00002D82388834203D9207901280FD119E0C2
+:108DF0002079002806D0012814D0022805D00328A5
+:108E000005D102E020290BD30CE0A02B0AD2207957
+:108E1000042805D12088202802D36188884201D9FE
+:108E2000122514E0207950776079002802D00128BB
+:108E300003D00CE0BD4A002105E0BB4A2032907906
+:108E4000002804D00121204608F0CEFE054601206E
+:108E5000357170711821F170307037E470B5B24C13
+:108E60000546403C2078002804D02E210E2000F03A
+:108E700044F92BE409F071FB0C22022815D1AA4811
+:108E8000007F002811D1A9482B88083841684888FC
+:108E900083421AD10846C030037A002B05D1203115
+:108EA000C97E0F2903D0102901D0227103E00521CA
+:108EB0000172002020710E20A0702E20E070288802
+:108EC000E08001206071207016E40220F2E770B5A6
+:108ED000954C0546403C2078002804D02D210E20DA
+:108EE00000F00BF908E409F038FB0C21022814D13A
+:108EF0008D48007F002810D18C4E2A88083E70686B
+:108F000043889A4220D1C822125C002A05D13B2214
+:108F1000125C0F2A03D0102A01D021710AE010221E
+:108F2000A91CD6300DF001F970680421C03001721F
+:108F3000002020710E20A0702D20E0702888E08095
+:108F40000120607120700DE40220F2E710B5017875
+:108F50000B000DF059FB3F9E9E399E9E599E9E9E92
+:108F60009E3C3F9E9E8752559E9E999E9E9E432963
+:108F70009E2D319E9E9E9E359E9E9E955C9E9E47FA
+:108F80009E4B4F9E21259E6C6064689E709E7F83E1
+:108F90007C788A8D74919E00801CFFF798FF76E0A4
+:108FA000801CFFF75BFF72E0801CFFF7D8FE6EE0CD
+:108FB000801CFFF7B5FE6AE0801CFFF729FE66E023
+:108FC000801CFFF706FE62E0FFF7D9FD5FE0FFF7C8
+:108FD000B3FD5CE0801CFFF777FD58E0801CFFF7D5
+:108FE00052FD54E0801CFFF7FDFC50E0801CFFF7B1
+:108FF000CDFC4CE0FFF7ACFC49E0FFF788FC46E015
+:10900000801CFFF744FC42E0FFF729FC3FE0801C96
+:10901000FFF7F2FB3BE0801CFFF7C4FB37E0801C4E
+:10902000FFF7A1FB33E0801CFFF767FB2FE0801CFC
+:10903000FFF742FB2BE0801CFFF7F8FA27E0801CCB
+:10904000FFF7A6FA23E0801CFFF764FA1FE0FFF7A2
+:109050003CFA1CE0801CFFF705FA18E0801CFFF7C3
+:10906000E0F914E0FFF7C4F911E0FFF762F90EE050
+:10907000801CFFF74BF90AE0801CFFF721F906E09E
+:10908000801CFFF70AF902E0801CFFF7DAF80120E4
+:1090900073E4002071E470B52349244C054640393F
+:1090A000083C0A460126403260682B000DF0ACFAFD
+:1090B00005171A1A04171A000122002108F093F963
+:1090C000616800220846C0310A724A7209F067FFDF
+:1090D000002803D016A11B480DF0A5F960E4167511
+:1090E00088655DE4174812A13330F5E70E4900208A
+:1090F000C031C8612039087270470B4A203A937E0C
+:10910000002B03D1D076117701209076704730B5CF
+:10911000134606E0CC18203CE47FD51A44555B1E6C
+:10912000DBB2002BF6D130BD940900206C0000208A
+:109130007372635C6C6C5F6374726C2E73302E633D
+:10914000000000005108000070B5FD4D040008D07B
+:10915000012C10D0022C07D0032C05D0F9A17020CF
+:1091600007E0F8A1672004E02878012803D0F5A1E2
+:109170006D200DF058F92C7070BD70B5F04D04469F
+:1091800010280AD0112C16D028468178122C07D02E
+:10919000132C0AD0EBA19F200BE0EAA1942008E059
+:1091A000112908D0E7A1992003E0112903D0E5A1F6
+:1091B0009C200DF038F9AC7070BD10B5E04894B04B
+:1091C000007B002819D0172069460870DC4900A8E8
+:1091D00006220D3102300CF0A8FF09A96846F9F704
+:1091E000C2FE0446112805D0002C03D0D5A1BB2017
+:1091F0000DF019F9204614B010BD3220E4E710B587
+:1092000001220023114603F0B5FC10BDFFB595B057
+:109210001D460E460746FFF7F2FF04000AD02078ED
+:10922000222804D3A07F8006C00FA84204D10820C2
+:1092300019B0F0BDC748FBE7372168460170478089
+:10924000002D05D00121017146711799817102E04D
+:1092500000206946087109A96846F9F784FEA07FD5
+:10926000DF21084069010843A0770020E0E770B5DE
+:109270000446084620380D4603000DF0C5F90A06DD
+:109280000A11232C334249505761FF20ADA1083009
+:1092900052E02078202851D1FF20AAA10B304BE0CA
+:1092A000A7480178032949D08078132846D0207830
+:1092B000242843D0252841D023283FD0FF20A1A136
+:1092C0000E3039E02078222838D0232836D8FF20E5
+:1092D0009CA1153030E0207822282FD0FF2099A1C2
+:1092E000193029E02078222828D0242826D02628C2
+:1092F00024D0272822D0292820D0FF2091A11C305B
+:109300001AE02078252819D0FF208EA1233013E001
+:109310002078252812D0FF208AA126300CE0207862
+:1093200025280BD0FF2087A1293005E020782828A8
+:1093300004D0FF2083A12C300DF075F8257070BD8E
+:10934000FF2080A12F30F7E730B5834C0B88834A8C
+:10935000022801D0934204D09D1FA54225D20228A5
+:1093600002D04D88954203D04D88AD1FA5421CD236
+:109370004C88A34219D88B88FF25F435AB4214D80A
+:10938000022802D0C888904205D0C888724D0A3899
+:109390002D1FA84209D2C888904208D0944206D016
+:1093A0005B1C63438000834201DB072030BD00204B
+:1093B00030BDF0B56A49884245D36A4A0125AD04FB
+:1093C0001368A84201D398423DD30279002A06D0FF
+:1093D000082A02D8067B082E05D90720F0BD047B99
+:1093E000002CFAD0F6E7002A06D004688C422AD373
+:1093F000AC4201D39C4226D3002E06D084688C4216
+:1094000021D3AC4201D39C421DD300240CE005685B
+:10941000A700ED598D4216D30127BF04BD4201D3E9
+:109420009D4210D3641CE4B2A242F0D80022012570
+:10943000AD040CE084689700E4598C4203D3AC423D
+:1094400003D39C4201D21020F0BD521CD2B29642EE
+:10945000F0D80020F0BDFFB50022099B002802D003
+:10946000994205DC58E0002902D1002004B0F0BD8B
+:109470000920FBE7845C002C12D087187D78112D21
+:1094800043D010DC2B000DF0BFF80A401726262C25
+:109490002C2E2E363640835C002B30D1521CD2B29B
+:1094A0008A42F8DBE1E71C2D2FDA123D2B000DF08C
+:1094B000ABF8042C2C121A2C022CD9D1BB78039CAB
+:1094C000072B237001D25B0701D40A20CEE7029B51
+:1094D00001241B7816E0E343DB0708E0012C08D0E9
+:1094E00013E00620C2E70F2523072D075B19002B89
+:1094F000F4D03046BAE7029B1B789C0701D50B20BD
+:10950000B4E702242343029C2370835C521C9A1804
+:10951000D2B28A4202DDABE7192676028A42A9DB83
+:10952000A3E710B504780B46002C1FD001210E4A8A
+:10953000012C1ED0022C22D0032C2AD125E00000C1
+:10954000740A00207372635C6761705F636F726599
+:109550002E630000023000007B0C0000FFFF0000C3
+:109560000080010028000020023200000021197054
+:1095700011E019708179890903290AD10BE019706A
+:1095800081798909012904D105E019708179890956
+:1095900001D0104610BD411C0622581C0CF0C5FD20
+:1095A000002010BD08B51346002806D0FEA00068B4
+:1095B000009048796A468009105C18700622581C91
+:1095C0000CF0B3FD08BD30B50C46097895B02229E2
+:1095D00002D2082015B030BD282369460B704880A0
+:1095E000132A03D03B2A01D00720F3E708460A716B
+:1095F00009A9F9F7B8FC050003D121212046FFF79E
+:1096000036FE2846E6E700B595B0232369460B7081
+:109610004880108888805088C880D0884881908889
+:10962000088100208881C88109A96846F9F79BFC58
+:1096300015B000BD70B50C00064610D0FFF7DFFD79
+:10964000050003D1D949DA480CF0EDFEA68028893F
+:10965000E0802889208168896081A889A08170BD07
+:1096600070B50E46050003D00021092003F027FF46
+:109670000120D04C022E207324D0032E04D0CC48DD
+:10968000CA491E300CF0CFFECA4806210D3003F047
+:1096900091FCA07C8006800EA074FFF78EFDA08B4D
+:1096A00000280ED0002D0CD08300012200210920BB
+:1096B00003F060FE092804D0BD48BC4928300CF0F6
+:1096C000B2FE70BDBB480321103003F073FCA07CD8
+:1096D00040218006800E0843A074B6480C3002F08A
+:1096E00015F9DAE77FB501A9012003F0C3FA0028D4
+:1096F00004D0AF48AD4967300CF095FEAE4E01A8DE
+:1097000003F0C6FA050002D0052D4CD048E0029CBB
+:10971000A07F01072CD520462230009068462346C2
+:10972000628E80882146343301F07BFA0546A07FA3
+:10973000F7210840A077002D05D0B5422FD09C48D6
+:109740009A49783029E0E17F480889074000C90F2D
+:1097500008432021095D4007400FC9000843E07716
+:10976000207828281CD129212046FFF780FD17E00A
+:109770004007C4D568462246808821460E32FFF74E
+:1097800042FF0546A07FFB210840A077002D07D0AF
+:10979000B54204D08648854992300CF044FE00253D
+:1097A000284604B070BD0020FBE7F8B5040004D1E2
+:1097B000ED207E4980000CF036FE7220207060683B
+:1097C00008250178091F0B000CF01EFF11F90A3D56
+:1097D0005FF83D0EF8F83E3D3D3D3DF986F93D0010
+:1097E00073487249AA3074E087883846FFF707FD4E
+:1097F000060004D16E486D49B2300CF014FE60785A
+:109800000421284360706B4CA07F0843A07721217E
+:109810003046FFF72CFDB07F8007800F012801D173
+:10982000801EA080384602F057FE3846FBF72AFE1D
+:109830003846FAF7C6F93946022003F040FEB07FF9
+:10984000EF210840B077F8BD86883046FFF7D7FC97
+:10985000002804D156485549D0300CF0E4FD60682A
+:109860008078012804D052485049D2300CF0DBFDFA
+:1098700060688179304602F04EFF0028E3D06178BD
+:10988000294361706168C880F8BD87883846FFF752
+:10989000B6FC060004D146484449E3300CF0C3FD51
+:1098A00060783946284360706068C088308160689D
+:1098B0000089708160684089B081022003F0FFFD5B
+:1098C0000020B075FFF70EFF0028DDD001203749DA
+:1098D00080020CF0A8FDF8BD80783C2815D0002748
+:1098E000022815D00026002804D031482F49F8302E
+:1098F0000CF099FD0021084603F0E1FD002107204E
+:1099000003F0DDFD002E05D046E001270026F1E73B
+:109910000126EAE76078284360702648817F294362
+:109920008177002F38D160688688304601F055F87D
+:109930000546807F6168800889798000012900D010
+:1099400002210843A87760680622C08A28816068DF
+:10995000008B68816068408BA8816068C079E87579
+:1099600061682846183008310CF0DFFB6068062279
+:10997000807B68706168A81C0F310CF0D6FBA87F53
+:109980008107890F304602F090FDA87F8007800F85
+:10999000012801D10748868006480178032913D0A1
+:1099A0008078132814D00BE00302FF0144950000D7
+:1099B00013030000740A0020023000000CE00FE0E6
+:1099C000FF20FCA1453084E70120FFF7BDFBF8BD77
+:1099D0001120FFF7D2FBF8BD204601F02AFCF8BDAC
+:1099E000607828436070F8BDF7B505460078002719
+:1099F00000090C463E4601287ED00022F14902288B
+:109A00007BD0072804D00A2878D0EAA1EE482DE1BF
+:109A1000686803780D2B31D006DC042B6FD0072B40
+:109A200036D00A2B6AD106E0122B38D0132B40D047
+:109A3000142BF7D1B2E011270726002C72D08088B2
+:109A4000A0806968FB238979A171E04905468A7F76
+:109A50001A408A77032103F0C5F80421284603F051
+:109A6000C1F80021284603F0BDF80221284603F082
+:109A7000B9F80121284603F0B5F8F9E001270926D5
+:109A8000002CDBD08088A080686880792072EFE0AD
+:109A900012270E2680882146FFF7CCFDE8E01A2722
+:109AA0000726002CCAD04088A08068680079A07181
+:109AB000DEE081783C2936D010271E26002CBDD050
+:109AC0008088A0806868C08A20836868C08AE08235
+:109AD0006868008B60836868408BA0836968207D1C
+:109AE000497F4008C9074000C90F084320756968CD
+:109AF000C007C00F497F03E05FE08AE0ADE01CE0F3
+:109B000049084900084320756968A21DC8790831D1
+:109B1000FFF748FD69682246887B0D320F31FFF759
+:109B200041FD05E074E019270726002C70D0A271D2
+:109B3000A648F722817F11407DE01B272E26002CAE
+:109B400066D0A1806968A21D0879491DFFF72AFD2A
+:109B500068682030C07A60736868C0780428A07B89
+:109B600019D040084000A073F921084069681F22FD
+:109B7000C9788907490F0843A07369684007C97A03
+:109B8000400FC9000843A073696820460F300C31AC
+:109B90000CF0CBFA6CE001210843E4E71E270E2607
+:109BA000002C6DD0A1806868E21D407AA0716968C0
+:109BB0008878C91CFFF7F6FC5AE0287A012805D0FE
+:109BC000022815D080487BA132384FE01D270E2691
+:109BD000002C55D06888A080A889E080E889208181
+:109BE000288A6081688AA0817848DF22817FA2E785
+:109BF00012270E266888FFF71DFD002C40D06878DC
+:109C00004007400F032833D17048FD22817F92E73F
+:109C100036E0287A03000CF0F7FC06041010202030
+:109C2000202619270726002C2AD0A1806748A27178
+:109C3000817F4908490081771AE019270726002CFF
+:109C40001ED0A180287A012805D00320A0715F488A
+:109C5000EF22817F6FE70220F8E721462846029A2B
+:109C600001F04BFCFEBD532052A100010CF0DBFBC8
+:109C70000298002C068001D0278066800020FEBD5F
+:109C800002980680FAE710B5504894B080781328FF
+:109C900002D0082014B010BD22206946087009A91E
+:109CA0006846F9F760F904460021072003F007FC35
+:109CB0002046EFE700B5454895B08078122801D0DE
+:109CC0000820B5E41E216846017000218170C17032
+:109CD00009A9F9F748F90028F3D10021072003F07A
+:109CE000EEFB1120FFF749FA0020A1E400B5374848
+:109CF00095B00078022801D0032818D11B2108A8AC
+:109D000001730021817369460BA8F9F72CF900282B
+:109D100004D1684640781B2801D0032088E4002144
+:109D2000084603F0CCFB68468078002801D0082064
+:109D30007EE40120FFF708FA002079E4F8B5234C0F
+:109D400003000CF061FC0A068017808080804B3590
+:109D50006E80FFF7CBFF00282AD1F7F7E9FD002836
+:109D600026D02221017000210172F7F7C2FDA07FE9
+:109D7000012152E08EB23046FFF741FA050004D1CE
+:109D800011480CA12E300CF04EFB287821280FD062
+:109D9000F7F7CEFD00281BD01221017002270772B1
+:109DA00046800020A875F7F7A4FDA07F3843A07770
+:109DB000F8BD00007372635C6761705F636F72650A
+:109DC0002E630000FFFF000036050000740A00202B
+:109DD000132229463046FFF7F6FBE9E7A578122D56
+:109DE00006D0132D07D0FA49FA480CF01CFBDFE728
+:109DF000FFF760FF01E0FFF746FF0028D8D1F7F733
+:109E000097FD0028D4D022210170122D07D0022105
+:109E10000172F7F76EFDA07F10210843C7E701210B
+:109E2000F6E7A07C810901290BD0800904D0E9481C
+:109E3000E74922300CF0F7FA03210020FFF710FC6D
+:109E4000B6E70221F9E7E348E1492930CDE7F7B564
+:109E500014460D0004D1DF48DD4931300CF0E3FA3F
+:109E600028780827012807D002281FD0D948D849C8
+:109E700062300CF0D8FAFEBD0098FFF7C0F906007A
+:109E800004D1D448D24938300CF0CDFA0220B07554
+:109E90001030207060783843607007CD083407C4F4
+:109EA000CD482022817F11438177FEBD0098FFF7C6
+:109EB000A6F9060004D1C748C54946300CF0B3FAEC
+:109EC000A988C648814208D1EA88824205D1132276
+:109ED00031460098FFF777FBFEBD814202D1E8884A
+:109EE000002809D01220207060783843607007CDB8
+:109EF000083407C4002006E07823002202200099DD
+:109F000003F038FA0120B075FEBDB34840897047B0
+:109F1000FFB591B01498F8F721FF00285DD1012416
+:109F2000684603218471C9028180002201A920466C
+:109F3000FAF719F9002850D16846152184714902B1
+:109F4000818000261C2102A800960CF04DF901200A
+:109F50000146684610310170002001466846417094
+:109F60008178F9273940891C21438170017A0225C3
+:109F70002943017212998186C6861F2101870C90A0
+:109F800011980F9001A80B9009AA0BA902A8F9F744
+:109F9000B5FE002821D168468F4E808CF08068463F
+:109FA00084718F498180807809AA3840801C4108DB
+:109FB0004900684681708586058713A80F900BA914
+:109FC00002A8F9F79BFE002807D16846808C3081F3
+:109FD00031460A311498F8F7D4FE15B0F0BD30B50B
+:109FE0000C46804995B08C4241D37F4901229204AE
+:109FF0000968944201D38C4239D3203800220125CC
+:10A0000003000CF001FB06042F494D535C64002152
+:10A01000082003F02EFA002802D0112015B030BD20
+:10A0200024206946087000A80522A11C02300CF00B
+:10A030007CF809A96846F8F796FF050002D0082DBC
+:10A040000ED031E0082300221146184603F092F9A1
+:10A05000082829D05F485E49D6300CF0E4F923E0A7
+:10A060000620DBE76068002803D0884201D2102078
+:10A07000D4E73D2168460170218841806188818054
+:10A0800009A9F8F770FF05000ED1606800280BD011
+:10A090006946098D018007E0206801F079FC02E043
+:10A0A000204600F0D8FC05462846B7E73E2007E0EA
+:10A0B000857000E0827009A9F8F755FFF3E73420B6
+:10A0C000694608702078C0076846F3D0F0E707209B
+:10A0D000A4E730B50C46444995B009688C4201D2DA
+:10A0E00010209BE7203803000CF08EFA0504212194
+:10A0F000232132002088FFF782F8002804D000785E
+:10A10000222803D2082089E7384887E725216846B6
+:10A1100001702188418009A9F8F725FF050015D1B4
+:10A120000AA905220231A01C0BF0FFFF0EE0062554
+:10A130000CE02068002805D0884201D2102505E0F7
+:10A1400001F01BFC24480025808BA080284665E791
+:10A15000072063E720481330704710B520211E48C0
+:10A160000CF040F80120FEF7EFFF1120FFF705F893
+:10A1700000211948C943818000218176E1218900AD
+:10A18000818301460C300D310446F7F751FC12482B
+:10A190000722214613300BF0C8FFFFF70EF8002806
+:10A1A00003D00B4912480CF03EF900F0D5FF10BD6A
+:10A1B00010B504463C210CF015F8A07F8008800003
+:10A1C000A077202020700020A0752034607010BD82
+:10A1D000B49D00008C050000740A0020FFFF000001
+:10A1E000012A000000800100280000200230000049
+:10A1F000FB0600007047FEB50546FF480C4681424D
+:10A2000007D301208004844205D3FC4800688442BF
+:10A2100001D21020FEBD002D02D0012D32D126E04A
+:10A22000F74908220F4668460BF07FFF3946204663
+:10A23000FFF777F90028EDD1FEF7BFFF060006D043
+:10A240000722694638460BF070FF3046FEBD207885
+:10A25000002801D0012805D1E94807223946C01D50
+:10A260000BF063FF0021092003F029F90FE00978C2
+:10A27000002907D0012905D0022905D0032903D0E0
+:10A28000E048FEBD0720FEBD0120FFF7E9F9DC48EC
+:10A290000C3885760020FEBD10B5D8490968884283
+:10A2A00001D2102093E7D64902460C390B7B0D31C1
+:10A2B0001846FFF777F9002089E7FFB599B0054602
+:10A2C000002069460871087208A9087408751446C8
+:10A2D000CA480122C849920400681E46002D05D0D4
+:10A2E0008D420BD3954201D3854207D3002C08D071
+:10A2F0008C4203D3944204D3844202D210201DB076
+:10A30000F0BD2846204318D01F270CAB01AA0097A8
+:10A3100028461A99FFF79FF80028F0D10DAB02AA42
+:10A32000314620460097FFF796F80028E7D16846A7
+:10A33000007AC10703D00A20E1E70720DFE78007A2
+:10A3400005D568460079800701D50B20D7E703AF14
+:10A35000002D0FD01A20694608731A988873294671
+:10A36000F81C1A9A0BF0E1FE0EA903A8F8F7FBFD02
+:10A370000028C4D1002C0ED02021684601738673BA
+:10A3800032462146F81C0BF0D0FE0EA903A8F8F7C0
+:10A39000EAFD0028B3D19A4908A8007C0C3948701E
+:10A3A0000020ACE770B504460A2020700D46204618
+:10A3B000F8F7D9FD002805D139202070294620461C
+:10A3C000F8F7D1FD70BDF7B500260C4605460B2702
+:10A3D0001AE02968B00009580978002903D001293A
+:10A3E00001D00720FEBDA170296806220958E01C93
+:10A3F000491C0BF09AFE277020460299F8F7B3FD2E
+:10A400000028EFD1761CF6B22879B042E1D80026B8
+:10A410003A270FE0A868B10041581022A01C0BF0A9
+:10A4200084FE277020460299F8F79DFD0028D9D1B7
+:10A43000761CF6B2287BB042ECD80020FEBDF0B509
+:10A44000044671A003C897B06B4B00271591149078
+:10A450009C4211D369480125AD040268AC4201D386
+:10A46000944209D32078012809D16168994203D325
+:10A47000A94204D3914202D2102017B0F0BD604926
+:10A480000C390A78012A0CD18A88614B9A4203D090
+:10A49000002806D0012804D08A7F13079B0F06D11D
+:10A4A00001E00820E9E7D30701D1910701D5112088
+:10A4B000E3E7218A574B0A46203A9A4207D30128FC
+:10A4C00075D1002973D1628A002A70D111E0022867
+:10A4D00001D0032801D1A02969D3012809D0484A15
+:10A4E0000C3A5278D20704D0628A002A5FD0B42A8C
+:10A4F0005DD8002806D0012808D0022804D00328FF
+:10A5000055D117E0002518E0022516E0002902D1F8
+:10A51000608A00280CD004256068007800280CD0E0
+:10A52000012809D0022807D0032805D03548A4E720
+:10A530000125F1E7032500E00127207A002806D055
+:10A54000012806D0022806D003287CD105E0002689
+:10A5500004E0012602E0022600E00326002D01D0DF
+:10A56000022D14D1002E12D0E068FEF722FF002841
+:10A5700083D123480C384078800702D02148401E00
+:10A580007BE7022D03D1022E5DD0032E5BD0182174
+:10A5900068460170218A4180218A8180857118482E
+:10A5A0000C38007B002803D001286FD104E04AE07A
+:10A5B00000216846C17102E001206946C871684601
+:10A5C000077221780930012937D006210BF00AFEE5
+:10A5D00069460E74207D8207C107D20F4007C90F5C
+:10A5E0005200C00F11438000014314A8405C69462B
+:10A5F000C873002827D00FE0008001002800002049
+:10A60000800A002002320000070605040302010050
+:10A61000FFFF0000E13F000009A96846F8F7A3FC2E
+:10A62000002884D109A96846FFF7BCFE0028A7D1FD
+:10A63000002D0AD0022D08D010E061680622491CC6
+:10A640000BF073FDC4E7072017E7002E06D009AA18
+:10A650006946E068FFF7B7FE002891D11B206946E4
+:10A6600008700120887009A96846F8F77CFC00286A
+:10A6700086D108A840791B2819D12B000BF0C4FF04
+:10A680000504040707040A00032001E00FE002208C
+:10A69000FEF75AFD012D0CD0608A002809D0002257
+:10A6A00083001146104602F065FE002801D0032009
+:10A6B000E3E60020E1E6F3B5032687B00D46002966
+:10A6C0000AD0FA4885426FD301208004854203D323
+:10A6D000F7480068854267D30798FEF790FD0400AD
+:10A6E00005D02078222804D2082009B0F0BDF14816
+:10A6F000FBE7A07F8707BF0F002D05D0294638460E
+:10A70000FEF722FE0600F0D139460027EA4801296B
+:10A7100007D0022931D0E949E9480BF084FE3046E0
+:10A72000E3E7A27D2946012A02D0827F920701D564
+:10A730001120DAE700291BD108216A46049711820B
+:10A740000592418904AADF48FAF7FDF80028CCD128
+:10A750006846008A082801D00320C6E768460188B9
+:10A7600001814188418181888181C188C18102A99B
+:10A77000079801F061FF0646D1E7A17D022916D1B5
+:10A78000807F800613D4002D04D0A07F40070CD416
+:10A79000002100E00121079801F08FFF0600BED1E3
+:10A7A000A775002DBBD004E01AE01126B7E7002DF5
+:10A7B00016D02A4621460798FEF725FF064611289F
+:10A7C000ADD1A07F4007AAD42046082229460E30EA
+:10A7D0000BF0ABFCA07F04210843A07700269EE786
+:10A7E000102082E770B50C460546FEF708FD010013
+:10A7F00004D022462846FEF7E6FE70BDAD4870BD87
+:10A8000000B50146143195B0192901D2810707D04E
+:10A8100001461E3104D00A3102D0072015B000BD18
+:10A82000312269460A70887009A96846F8F79BFBCF
+:10A83000F4E701B582B00220694608809E4802AB69
+:10A8400000896A460021F9F7E7FE6946098802296E
+:10A8500000D003200EBD1CB50021009102216A46E4
+:10A860001180934901900968884201D210201CBDD3
+:10A87000914801899348FAF766F8694609880229E0
+:10A88000F5D003201CBDF0B50E46884985B01746AB
+:10A8900005468E4207D386480122920400689642FC
+:10A8A00004D3864202D2102005B0F0BD1F2F01D97B
+:10A8B0000C20F9E7804C8D4226D3954201D3854286
+:10A8C00022D3E08803A9F9F758FE0028ECD12878B4
+:10A8D00069464873E08803A9F9F730FE0028E3D100
+:10A8E0006946009008780221084369460870497B50
+:10A8F000090703D00821084369460870E0886946C3
+:10A90000F9F7B5FD0028CFD169468F80E08833463E
+:10A9100001AA0021F9F780FE69468988B942C3D0AF
+:10A920000320C1E71CB50C4600210091019122884B
+:10A9300069460A805E4901900968002801D0884272
+:10A9400001D38C4201D210201CBD002801D0002A66
+:10A9500009D059486A46C1885A48F9F7F4FF694650
+:10A96000098821801CBD0C201CBD10B50123FEF7F9
+:10A970004DFC2CE4002310B51A461946FEF746FCA0
+:10A9800025E430B505464A4895B000680C4681423A
+:10A9900002D2102015B030BD2846FEF730FC00284A
+:10A9A00007D00178222902D3807F800603D40820B3
+:10A9B000F0E74048EEE7132168460170458009A999
+:10A9C000F8F7D1FA0028E5D108AA0A2151567F29C3
+:10A9D00001D02170DEE70520DCE7F8B5012304464D
+:10A9E0001A46194602F0C6F8074601231A46022104
+:10A9F000204602F0BFF8064601231A4604212046ED
+:10AA000002F0B8F8054601231A460321204602F059
+:10AA1000B1F80446002F03D128492B480BF003FD61
+:10AA2000002E04D1AD20254980000BF0FCFC002D48
+:10AA300004D125482149801C0BF0F5FC002C04D1E1
+:10AA400021481E49C01C0BF0EEFC22213846FEF7BF
+:10AA50000EFC3846F8BD10B50446006800280CD03E
+:10AA60001249884207D301218904884205D310493D
+:10AA70000968884201D2102014E400F071FFA08818
+:10AA80000D4CA083A07E01280DD10021092002F0E9
+:10AA9000F0FC002800D00120A17C8909012915D0F3
+:10AAA0000321FEF7DDFD002006E400000080010028
+:10AAB0002800002002300000740A0020B49D00002D
+:10AAC000C6090000FFFF0000B30200000221E8E712
+:10AAD00030B5F74B9A4207D301239B049A4205D322
+:10AAE000F44B1B689A4201D2102030BD1578EB065A
+:10AAF0005B0F042B07D85478072C04D39378102BC2
+:10AB000001D8A34201D2072030BDD3785B0702D41D
+:10AB100013795B0701D5062030BDC37FAC075B0806
+:10AB20005B00E40F2343C3770878EF2318401378C2
+:10AB30009B06DB0F1B0118430870F12318401378A4
+:10AB4000DB065B0F5B001843087050780873002029
+:10AB500030BD30B500240C70C378DB07DB0F0B7001
+:10AB6000C578AD07ED0F6D002B430B70C5786D07F1
+:10AB7000ED0FAD002B430B7014700179C907C90F9D
+:10AB8000117003799B07DB0F5B001943117000798B
+:10AB90004007C00F80000143117030BD70B51446EE
+:10ABA0000D460646F6F7C4FE002809D0A221017022
+:10ABB000142221460830F6F707FBF6F79AFE70BD1F
+:10ABC000132229463046FEF7FEFC70BD70B51446D0
+:10ABD0000E460546F6F7ACFE002809D0222101708A
+:10ABE00045802178017261784172F6F782FE70BD6E
+:10ABF000132231462846FEF7E6FC70BD10B5AE4C78
+:10AC0000207C00280CD1204621461038FDF762F840
+:10AC1000002803D0A9A1F2200BF005FC012020742C
+:10AC200010BD70B594B015460C462C226946189E8E
+:10AC30000A704880002B17D00822194601A80BF093
+:10AC400074FA68468581102231460E300BF06DFA99
+:10AC500009A96846F8F787F9002803D1A17F1022D7
+:10AC60001143A17714B070BD002001900290E8E775
+:10AC7000F0B50646008A97B080B20D460190FEF707
+:10AC8000BEFA04468C48317848380746E8370990C0
+:10AC90000B000BF0B9FC0EFCFB48085F8798B8D995
+:10ACA000FAF9F8F7F6FC002301221946019801F0A1
+:10ACB00061FF050004D1FF2080A130300BF0B3FB11
+:10ACC000002C04D1FF207DA131300BF0ACFB387E8D
+:10ACD000C00904D078486030C06DA86112E02B2014
+:10ACE000694608720BA902A8F8F73DF9002804D0BC
+:10ACF000FF2072A13C300BF096FB74490C980BF0CE
+:10AD00008EFAA9617068A862B068E862A07F8007C7
+:10AD1000800F012820780DD0252804D0FF2067A1BE
+:10AD20004D300BF080FB324621460198FFF736FF8D
+:10AD300017B0F0BD2528F6D0222806D0242804D04C
+:10AD4000FF205EA146300BF06EFB25212046FEF76A
+:10AD50008EFAE8E7002301221946019801F00AFF64
+:10AD6000060004D1FF2055A158300BF05CFB002CED
+:10AD700004D1FF2051A159300BF055FB2078252834
+:10AD800004D03078012108433070D1E702202870C8
+:10AD9000B068A860B068002802D000202871C7E71A
+:10ADA0000120FBE72B2069460870434968464C396F
+:10ADB000F8F7D9F8002804D0FF2040A178300BF034
+:10ADC00032FB03201BE02A206946087000A81022ED
+:10ADD000023071680BF0A9F904A810220230B168A2
+:10ADE0000BF0A3F9344968464C39F8F7BCF8002851
+:10ADF00004D0FF2031A189300BF015FB042028700E
+:10AE00000998686094E7B068002804D1FF202BA15E
+:10AE100095300BF008FBE07F400704D5FF2027A109
+:10AE200096300BF000FBB06806220A3800903379A8
+:10AE30000421019801F0FBF90028A6D0FF201FA1F2
+:10AE40009B300BF0F0FA73E7002C04D1FF201BA11C
+:10AE5000A3300BF0E8FA2046223010220546716834
+:10AE60000BF063F928212046FEF701FAA07F800746
+:10AE7000800F022814D100231A462146009501981C
+:10AE800006E04BE1BAE0B0E095E03FE071E05FE161
+:10AE9000FFF7C7FE11281BD029212046FEF7E7F94E
+:10AEA000E07F317A4007400FC9000843E0773FE771
+:10AEB0000080010028000020400B00207372635CBA
+:10AEC0006761705F7365632E6300000040420F008E
+:10AED000A07F000704D5FF20FD49B0300BF0A3FA96
+:10AEE000A07F08210843A0770020608620463430E8
+:10AEF0000BF078F9E07FFD220146C9071040890F69
+:10AF00000843E077307A2034207011E700230122D3
+:10AF10001946019801F02EFE040004D1FF20EC49EF
+:10AF2000CD300BF080FA2B2069460872E94902A85F
+:10AF3000F8F719F8002804D0FF20E549D2300BF0CB
+:10AF400072FAE4488188204621300176090A417668
+:10AF50000E2129702146FC316960017E2974407EF2
+:10AF60006874DC482C30A860103030346C61E860C4
+:10AF7000DEE6002C04D1FF20D549E6300BF053FA71
+:10AF80002078212893D93079012802D0022808D1CD
+:10AF900003E0E07F04210843E077387E0121084385
+:10AFA0003876324621460198FFF7F8FD23212046E6
+:10AFB000FEF75DF9BCE601220421019801F01FFCB7
+:10AFC0000028A2D0002301221946019801F0D2FDE9
+:10AFD000040003D1BE49C0480BF025FA0F202870A9
+:10AFE000172028716E34AC60A2E60421019801F0AC
+:10AFF00056FC002889D11020287099E600230122F0
+:10B000001946019801F0B6FD050004D18720B0492A
+:10B0100080000BF008FA2E462036307E41064DD5D2
+:10B02000A17F8F07BF0FC00713D029468031486F1B
+:10B0300000280ED0027CF37DD207D20F5B001A43AA
+:10B040000274486F5108E27F4900D207D20F1143C2
+:10B050000174307E000713D52A468032116F002913
+:10B060000ED0087CF37DC007C00F5B001843087446
+:10B07000116FE27F40084000D207D20F10430874DE
+:10B08000307E80070BD5F8204259002A07D0012FC7
+:10B0900005D02946307C31311032FEF783FA307EFC
+:10B0A000C0060BD5F8204259002A07D0012F05D140
+:10B0B0002946307C31311032FEF774FA0523684698
+:10B0C0000370357E4570834822216038019A0170F3
+:10B0D0004178C908C900C91C417042800372457299
+:10B0E000F6F78EFD2078252809D021280BD07A4844
+:10B0F00077495B300BF097F92078222803D9222179
+:10B100002046FEF7B4F80021019801F06BFD0028FD
+:10B1100000D10DE670486E49633092E674686D4D5B
+:10B1200020786035092802D00A28F2D10BE0E168C6
+:10B13000002902D02846F7F7E8FE2169002902D04D
+:10B140002846F7F7E2FE21462846F7F7DEFEEFE550
+:10B1500061485F49883074E65E4810B504222821B2
+:10B160006030F7F7B9FE5B480024EC30017E4906F9
+:10B17000490E01764038C465FCF739FD55493C312C
+:10B1800008461038F6F78BFC52484C30047410BD5A
+:10B1900070B50D46FEF733F8040004D14E484C4913
+:10B1A000A7300BF040F9FF21053128460BF01CF8C1
+:10B1B000A07F8007800F01280CD00221284688300C
+:10B1C000FCF716FD002804D043484149AC300BF091
+:10B1D0002AF970BD0121F1E70A46014610B5104673
+:10B1E0008830FCF71FFD10BD70B5054611200C46D8
+:10B1F0000870002161702121495D002908D00329D0
+:10B200000ED0042910D034483149C6300BF00BF968
+:10B2100020780009012802D9E87FC008607070BD5D
+:10B220000007000F203002E00007000F30302070D0
+:10B23000EEE7F0B504464068082601789BB008297F
+:10B240000DD00B2903D00C294BD1012181716068ED
+:10B2500087883846FDF7D3FF05004CD147E0478883
+:10B260003846FDF7CCFF050004D1172018494001EE
+:10B270000BF0D9F82878212833D0282833D16068FA
+:10B2800002210C3000F050FF00282CD0606808210B
+:10B29000001D00F049FF002825D02D2168460170CF
+:10B2A000478029461022223101A80AF03EFF0FA94B
+:10B2B0006846F7F758FE002804D007480449EF30E5
+:10B2C0000BF0B1F8A87F10210843A877292105E0E9
+:10B2D000BCAE0000F40A0020030200002846FDF77F
+:10B2E000C6FF1BB0F0BD607830436070F9E7FE49DF
+:10B2F000FE480BF098F8A87FEF210840A87729783E
+:10B3000021290FD061688A79002A02D08978002922
+:10B3100012D08007800F022849D0F448F249343017
+:10B320000BF081F8FEF7DEF90028DAD0EF48EE499D
+:10B330003F300BF078F8D4E7607830436070E87FF6
+:10B34000C00701D0042100E00321212041552878C5
+:10B3500029280BD03946062002F0B1F82878242895
+:10B36000E0D122212846FDF782FFDBE700230122FE
+:10B370001946384601F0FEFB040004D1C920DA4921
+:10B3800080000BF050F825212846FDF770FF0D20B6
+:10B3900008A90871204609A98830FCF735FC022865
+:10B3A000C0D00028BED0D148CF491D30B8E7607862
+:10B3B00030436070B6E7F7B58AB015460646FDF72C
+:10B3C0001EFF002841D0017822293ED323293CD0FA
+:10B3D000C17F490739D4807F8007800F01280DD0B5
+:10B3E000002301220021304601F0C4FB0746C0487B
+:10B3F0000290F7F781FD040007D101E00123F0E797
+:10B40000BA48B94959300BF00EF8002F1FD08837D1
+:10B4100067610298F7F770FD07460298F7F76CFD31
+:10B4200009212170266225710B99E760A1602061D6
+:10B4300003A92046FCF70CFC022806D0002804D003
+:10B44000AA48A94975300AF0EEFF0DB0F0BD002002
+:10B4500007466061E4E730B5002387B00546012266
+:10B46000194601F087FB04462846FDF7C8FE007820
+:10B4700022281BD9002C04D19C489B4981300AF01A
+:10B48000D2FF0F21684601701721017120466E30EE
+:10B49000029069461A30FCF7B7FB022806D0002854
+:10B4A00004D0E520904980000AF0BDFF07B030BD10
+:10B4B00030B5002387B005460122194601F05AFB3A
+:10B4C00004462846FDF79BFE00782228EED9002C82
+:10B4D00004D18648844993300AF0A5FF10206946BC
+:10B4E000087020468830FCF78FFB0028DED0E9206A
+:10B4F0007D4980000AF097FFD8E7F7B50546007848
+:10B500000027000982B00C463E4602287ED007285C
+:10B5100002D00A284AD14AE068680178082907D091
+:10B520000B2930D00C292ED070486F49D33060E100
+:10B5300014271A26002C6AD04088A080FDF75FFEF1
+:10B540000090002804D169486749AF300AF06BFFCA
+:10B5500000980099C07DA21D1831FEF723F8686895
+:10B5600008228089E081696820461030091D0AF0B0
+:10B57000DCFD207E01210843F92108402076009857
+:10B580004021807F47E018270826002CD3D08088F0
+:10B59000A080FDF734FE050004D1F7205249800059
+:10B5A0000AF041FFA11D2846FFF71EFE23E1002CF3
+:10B5B00001D0288BA080287A01287DD0022804D0D1
+:10B5C00003282FD048494B4813E11C270726002C9D
+:10B5D000B1D0A088FDF713FE0090002804D1FD2013
+:10B5E000414980000AF01FFF287B8007800F012857
+:10B5F000A07914D040084000A071FD210840297BAB
+:10B600004907C90F49000843A07101E0E3E0DFE00A
+:10B6100000988021807F084300998877EBE0012122
+:10B620000843E9E713270B26002C84D0A088FDF7F8
+:10B63000E6FD00900023A0880122194601F09AFA45
+:10B6400005460098002804D12A48274960380AF0A6
+:10B65000EAFE002D04D181202349C0000AF0E3FE58
+:10B660000098807F8007800F012859D0E86A817890
+:10B670008907890F0129A17954D049084900A1718E
+:10B680008278FD255207D20F294052001143A17143
+:10B69000E322114002785207D20E1143A171DF223A
+:10B6A00011404278D207920E1143A1710021E1713D
+:10B6B000C1782172427900E037E00179607AD307DE
+:10B6C00040084000DB0F18439307DB0F28405B0066
+:10B6D00018435207FB23D20F1840920010436072A8
+:10B6E000A07A4008400007E0BCAE00000E03000056
+:10B6F000540B002067040000CA07D20F10438A07CA
+:10B70000D20F2840520049071043C90F1840890042
+:10B710000843A0720098007823286CD92621AFE056
+:10B72000A86AA4E701221143A9E7297BFE48022960
+:10B7300010D017270C26002C4AD0012911D003293C
+:10B740001ED004291FD005291DD0F849F8480AF059
+:10B750006AFE23E019270726002C4CD00121A17195
+:10B7600005E00121A171E17989088900E171017E7B
+:10B77000CA094906D201890E49000A4302760DE042
+:10B780000220A07106E0687B0007000F8030A071E6
+:10B79000052918D0E07980088000E071A088FDF7C5
+:10B7A0002EFD05460078212825D0232804D0E04826
+:10B7B000DE490C300AF037FEA088002101F012FAB1
+:10B7C000222128465DE0E07980088000401CE4E703
+:10B7D0000498068015E0002C01D06888A080287AA3
+:10B7E000032828D004280FD005284DD0D048CF49B1
+:10B7F00064300AF018FE0498002C068001D02780DF
+:10B800006680002005B0F0BD15270C26002CDFD087
+:10B810000023A0880122194601F0ACF9050004D1EB
+:10B82000C348C2492A300AF0FEFD0622A11DA869BC
+:10B8300009F0DCF9DFE716270726002CC8D0A0881E
+:10B84000FDF7DDFC00900023A0880122194601F0DD
+:10B8500091F905460098002801D0002D04D1B44884
+:10B86000B24938300AF0DFFD2878C00601D5022041
+:10B8700000E00120A071009800782328BBD927217F
+:10B880000098FDF7F4FCB6E717270C26002C9FD094
+:10B89000A088FDF7B4FC00906D7A002804D1A4487C
+:10B8A000A2494B300AF0BFFD0621A01D0AF09AFC08
+:10B8B0000020A071207A032108432072FB21084058
+:10B8C0000099C97FC907490F08432072680692D5BD
+:10B8D000E07904210843E071A07AE90740084000BC
+:10B8E000C90F0843E17A2A0749084900D20F1143DA
+:10B8F000FD22AB07DB0F10405B001843A072E80687
+:10B90000C00F114040000143E17274E710B50446D6
+:10B91000807990B08009012804D04D20834900012E
+:10B920000AF081FDFFF76AF90120694608707E4838
+:10B930000AA9A0380190201D0290601C0B90684657
+:10B94000FCF786F9002804D07948784987300AF056
+:10B950006AFD0322601C0B990AF0E7FB10B010BDD2
+:10B9600010B5714CA03C002805D00146102220469D
+:10B970000AF0DBFB0120207410BD10B50446FFF770
+:10B980003DF969491022A03920460AF0CEFB10BDCE
+:10B9900070B50025644C00281CD06649884207D346
+:10B9A00001218904884205D363490968884201D28C
+:10B9B00010250DE0062109F003F9411C07D05A4972
+:10B9C0004039C865207E80210843207600E00725A5
+:10B9D000284670BD207E4006400EF6E7F3B50020F5
+:10B9E00089B00D46029000290AD0524885421CD3E6
+:10B9F00001208004854203D34F480068854214D358
+:10BA00000998FDF7FCFB060003D03078222815D1F9
+:10BA100002E04A480BB0F0BD002D08D1B07FC1094B
+:10BA200003D08007800F022801D01020F2E7B07FFA
+:10BA3000C10601D4000703D5002D01D00820E9E795
+:10BA40003948007EC00712D1F07F400701D50D2094
+:10BA5000E0E7002201231146099801F08BF8070066
+:10BA600005D0B07F8007800F022802D00BE01120A4
+:10BA7000D0E7002D07D02A4639463046FFF728F890
+:10BA800002900028C6D128488C38F7F735FA040010
+:10BA900003D126492A480AF0C6FC0A2020700998DA
+:10BAA000206238468830A060B07FFB218007800F7D
+:10BAB000012829D0002D4CD002202071381DE060D3
+:10BAC00038780007400F20743878C006C00F6074C3
+:10BAD000A07C2A788008D2078000D20F1043A0747F
+:10BAE0000840F17F01AAC907490F0843A074A8784C
+:10BAF000E07469462846FFF72CF8684600792075FF
+:10BB000068460078607528E001202071207B2A7843
+:10BB10008008D2078000D20F104320730840297894
+:10BB20008907C90F89000DE0E00B0020BCAE0000C2
+:10BB300053040000008001002800002002300000B3
+:10BB4000630500000843207324213046FDF78FFB76
+:10BB50000BE0032020710520207325213046FDF7DE
+:10BB600086FBB07F4006400EB07703A92046FCF765
+:10BB70006FF8022805D0002803D0FD49FD480AF0DF
+:10BB800052FC029846E7FFB581B00A9D06461C4666
+:10BB90001746142128460AF027FB0B980021016064
+:10BBA000F8070ED0F44920680968884239D312306A
+:10BBB00028602068143068602068A8600B982168AD
+:10BBC0000160B80726D56068002803D0EA490968F3
+:10BBD000884226D3029900290AD0FC3600280ED0CC
+:10BBE00031461030FDF79DFC00281BD1606810E045
+:10BBF000002816D0E86080366068B0670AE0FEF77B
+:10BC0000A9FA0146072230460AF08FFAFEF7F6FF3E
+:10BC1000DA48E860780707D5D749A06809688842FC
+:10BC200001D21020EEE528610020EBE5FFB5D44AF3
+:10BC30000E4607CA97B002AB07C3002700970197CB
+:10BC40001798FDF7DCFA050005D02878262804D0DF
+:10BC500008201BB0F0BDCB48FBE700231A4619466D
+:10BC6000179800F087FF040004D1C248C049803013
+:10BC70000AF0D9FBA87F8007800F1690012814D006
+:10BC8000022824D0BB48BA4999300AF0CCFB0121E4
+:10BC90000022852E31D01EDC002E26D0812E26D00B
+:10BCA000822E26D0832E1ED125E0002EEFD12146F4
+:10BCB0002846199AFEF70CFF0028CAD119988078F7
+:10BCC000009019980078C007C00F0190DFE719981D
+:10BCD000002808D1DBE7862E11D0882E11D0892EBE
+:10BCE00011D08A2E11D00720B3E710460EE0084687
+:10BCF0000CE002200AE0032008E0052006E0062010
+:10BD000004E0082002E0092000E00A20002222715D
+:10BD100001216A461176211D0791002801D020716A
+:10BD2000FAE0169801280CD0A66AE06A02220121E6
+:10BD300010900020A0602846173002291AD0012157
+:10BD400019E0E66AA06A1090032030702078FB2387
+:10BD5000C006C00F7070B07801221840009BF370CD
+:10BD60008008019B800018430221B0700020707190
+:10BD70003071DEE70021890009190861681C022A78
+:10BD800001D0012100E00021890009190861B07883
+:10BD90008007800F01285ED1109880788007800F7F
+:10BDA000012858D110980079844610984079009065
+:10BDB000169801281DD0317908A801747179017590
+:10BDC00008A8027C6046024008A8007D009908404F
+:10BDD000139010433FD06C491A98884207D3012131
+:10BDE0008904884215D364490968884211D2102019
+:10BDF0002FE70CAA0DA91998FEF7ABFE08A8007C46
+:10BE000061460840307108A8007D009908407071B3
+:10BE1000D6E720463C3021460090F031169801913B
+:10BE2000022834D000211A9B20460C33FFF7ABFECA
+:10BE30000028DDD12046503021460090F43116987C
+:10BE40000191012825D0002120461A9B139AFFF763
+:10BE50009AFE0028CCD110988078400702D4E87F61
+:10BE6000C0072BD0169902A8012914D0109909787F
+:10BE70004900405A21780907490F4900C8408707FF
+:10BE8000BF0F2AD0012F14D0022F0FD113E00121B0
+:10BE9000C9E70121D8E721780907490F4900405A2D
+:10BEA000109909784900C8408707BF0F032F04D0B5
+:10BEB00004E0022711E001270FE00227169801286D
+:10BEC0000BD1B078FB210840E97FC907490F08432F
+:10BED000B07020780007400F3070207810224008A2
+:10BEE000400020701099D2434978C907C90E114308
+:10BEF00008402070C00623D4022F21D0012F21D06A
+:10BF00000020A061E0612062606220461830A060DD
+:10BF1000E87F40084000E877204606A98830FBF714
+:10BF200073FE002806D0022804D06F2010490001BB
+:10BF30000AF079FA25212846FDF799F9002088E6CC
+:10BF4000032008E020460D211B300AF04BF9204663
+:10BF50001830A060042069460875E87F0121084375
+:10BF6000E87705AA29461798FEF730FED4E70000C7
+:10BF7000BCAE00008E05000028000020400B002011
+:10BF8000606701000230000000800100F0B587B05A
+:10BF900015460E0004460DD06A48854207D301209D
+:10BFA0008004854206D368480068854202D210208A
+:10BFB00007B0F0BD2046FDF722F9070004D038781D
+:10BFC000272803D00820F3E76048F1E700231A464A
+:10BFD0001946204600F0CEFD040003D15C495D48BF
+:10BFE0000AF021FA0020002E05D0022E08D0012EE2
+:10BFF00011D00720DCE701216A461171A06018E02A
+:10C00000234618336946A360087110222946184652
+:10C010000AF08BF80DE021461831A16069460871DD
+:10C02000A061E061206260620621284608F0C8FD38
+:10C03000A0612078C10714D0400840002070022081
+:10C04000694608702046183002907030FBF7DCFD1E
+:10C05000022806D0002804D03E483D4923300AF08B
+:10C06000E2F925213846FDF702F90020A0E770B576
+:10C0700094B00D460646002B02D0072014B070BDC8
+:10C08000FDF7BDF8040007D02078222802D3A07F56
+:10C09000400603D40820F1E72C48EFE7002D19D023
+:10C0A0002D216846017046801022294601A80AF019
+:10C0B0003CF8E07F297C4008C9074000C90F0843CD
+:10C0C000E077297C40078906400FC90EC900084364
+:10C0D000E07703E02E2168460170468009A9684692
+:10C0E000F6F741FF694609782D2905D1002803D1CB
+:10C0F000A17F10221143A177A17FBF221140A17718
+:10C10000BCE710B50C46FDF77AF8002805D00E49BB
+:10C1100009688C4203D2102010BD0C4810BD214686
+:10C12000FFF762F8002010BD05E00278401C002AED
+:10C1300001D0002070470A46491E89B2002AF4D176
+:10C14000012070470080010028000020023000001C
+:10C15000BCAE00000F07000030B50346072903D02E
+:10C160000820DA781C7916E00720FAE707290BD0B7
+:10C170005500ED186D79072D01D0401EC0B2521C3C
+:10C18000D2B20F2A07D105E05500ED186D79072DC1
+:10C19000F3D0F4E700222546641EE4B2002DE5D179
+:10C1A00030BDFFB581B00C461646114620460A9FA9
+:10C1B0000B9DFFF7D1FF00280AD020790F2803D369
+:10C1C000FEA1A0200AF02FF9A078C00907D019E03D
+:10C1D000072E02D0112005B0F0BDFD48FBE7019805
+:10C1E0002880381D6880002068712871EF800498CD
+:10C1F00028812846F6F7DFFE002803D1EFA1AD2005
+:10C200000AF011F9E07821794018491CC0B2217177
+:10C210000F2801D30F38C0B2400000194671817950
+:10C22000F12249084900114081710020D3E7FFB590
+:10C2300083B01C4616460F4600231A4602210C9D69
+:10C24000039800F097FC010008D033463A46019568
+:10C2500000940398FFF7A5FF07B0F0BDDC48801EEF
+:10C26000FAE7F0B5054616460F4650888DB0002314
+:10C270000122022100F07EFC040003D1CFA1DF20C7
+:10C280000AF0D1F8002069460871A078400603D171
+:10C29000CAA1E3200AF0C7F8042F5ED32A78D0079A
+:10C2A000C017401C06D161786B78994255D121782E
+:10C2B000090752D00121142A46DA012A42D0122A53
+:10C2C00002D0132A40D128E00C2F3DD1A27852068B
+:10C2D000520E012A38D0207800090001401C20703D
+:10C2E000687860706846017168792A7901021143A3
+:10C2F00068460181E879AA790102114368464181C3
+:10C30000687A2A7A0102114368468181E87AAA7A1A
+:10C31000010211436846C1811AE0062F14D120782A
+:10C320000009000120707188012001F0C8F8022185
+:10C3300068460171C91E018168792A790102114399
+:10C3400068461FE0062F0AD06A461279002A1BD0E1
+:10C350007088324601A9FDF77AFD0DB0F0BD207856
+:10C360000009000120707188012001F0A8F8022165
+:10C370006846017168792A79010211436846018192
+:10C380000021C9434181E3E70028E6D0748868466C
+:10C3900081766978C176022181830021C18304A856
+:10C3A00005220090062311462046FFF740FF002893
+:10C3B000D3D088A1D6200AF036F8CEE7F7B58CB0F6
+:10C3C00015460C990D98F9F7CEF9C0B2082851D14D
+:10C3D000002069468885688800230122022100F038
+:10C3E000C9FB040004D1FF2074A163300AF01BF8DC
+:10C3F00001230021E07822790BE046003619767996
+:10C400009E4201D1491CC9B2401CC0B20F2800D1C4
+:10C4100000201646521ED2B2002EEED1002902D1C3
+:10C4200017206946888504AB02330BAA00950C9946
+:10C430000D98F7F73BFC0006000E07D002281BD032
+:10C44000032817D0FF205DA1893011E06846808D58
+:10C4500000280FD002A901910090688804230122CE
+:10C460002146FFF79EFE002804D0FF2053A176301E
+:10C4700009F0D9FF0FB0F0BD68781021084368704B
+:10C48000F8E70020584902464300401CCA520828D9
+:10C49000FAD3704700218170017809090901017000
+:10C4A00000214170C1700171704770B50D460023C5
+:10C4B0000122022100F05EFB040004D1FF203FA115
+:10C4C000CF3009F0B0FFA0786906C009C001490E5D
+:10C4D0000843A07070BD704710B50146012000F000
+:10C4E000EEFF10BD3EB58DB2002301220221284689
+:10C4F00000F040FB040004D1FF2030A1E43009F03B
+:10C5000092FF20786946000900012070022008701F
+:10C5100036488880C88000222846FDF798FC3EBD3A
+:10C52000F7B505460078002700090C463E4601286D
+:10C5300004D0FF2021A1F33009F075FF287A0328E9
+:10C540000CD041201DA1C00009F06DFF0298002C05
+:10C55000068001D0278066800020FEBDEA89702712
+:10C5600010460A3086B2002C0AD06888A080A889BC
+:10C570002081E28020460A30296909F0D6FDE5E7EE
+:10C5800002980680E8E7F8B543680246D9799C79B5
+:10C59000090221435C7A1E7A25025C88981D354386
+:10C5A000241FA14238D11B79022B35D1042D34D060
+:10C5B000052D3DD0062D34D0402D19E07372635CFB
+:10C5C0006C326361705F636F72652E630000000000
+:10C5D000043000007372635C6C326361705F636F80
+:10C5E00072652E6300000000000C0020FFFF0000B9
+:10C5F00012D3061D0F461446284600F0E9F9082814
+:10C600000AD01120207003202072A581E7812661C5
+:10C610006078082108436070F8BD001DFFF7CEFE6A
+:10C62000F8BD031D50880A461946FEF7C4FEF8BD42
+:10C63000001DFFF716FEF8BD70B50D4600238CB047
+:10C6400006461A46022100F095FA040031D02078FF
+:10C650000007000F01282ED01220694688746078E8
+:10C660000523801CC874082088822888C8826888AE
+:10C670000883A8884883E888888302A90C20019150
+:10C6800000901A4621463046FFF78BFD00280ED158
+:10C69000F02300223146012000F06CFE20780009D2
+:10C6A0000001401C20706078801C607000200CB07D
+:10C6B00070BDCD48FBE71120F9E770B50D460023AA
+:10C6C0008CB006461A46022100F054FA040006D047
+:10C6D00020780007000F012803D00820E7E7C248B0
+:10C6E000E5E71321684681746178C1740221818273
+:10C6F000C58202A906200523019100901A46214611
+:10C700003046FFF74EFD0028D1D120780009000106
+:10C7100020700020CBE7F3B581B00D460023012245
+:10C720000221019800F026FA00260446002803D1D1
+:10C73000AE49AF4809F077FE2079A8423BD2AC4819
+:10C74000AA49401C09F06FFE35E0E07841000F195E
+:10C75000401C7979C0B20091E0700F2801D100200F
+:10C76000E0702079401E2071B879C00708D0009889
+:10C770000199042815D09D498220183109F053FEF3
+:10C78000B8790007410F08D0400F019904280CD058
+:10C7900096498F20183109F046FE009807280AD1E3
+:10C7A00007E00846FEF784FEEAE70846FEF753FE78
+:10C7B000F3E7761CF6B228466D1EEDB20028C4D110
+:10C7C0003046FEBD10B500230122022100F0D2F94F
+:10C7D000040004D1B5208549800009F024FEE078EA
+:10C7E00021794018C0B2E0700F2801D30F38E070F3
+:10C7F00000202071A07880210843A07010BDF8B5FA
+:10C8000017460D4600231A46022100F0B3F9040032
+:10C8100005D0002D0CD0002F07D0062006E0072DF4
+:10C8200001D00820F8BD0720F8BD0820A84204D890
+:10C830006F486E49423009F0F6FD29462046FFF761
+:10C840008BFC0646002F28D0002E26D1E0782179D7
+:10C850001CE0420012195379072B03D093791B0770
+:10C860005B0F04D0401CC0B20F280CD00CE040007D
+:10C8700000198079F12318406B071B0F1843907142
+:10C8800000290AD104E00020491EC9B20029E0D1E4
+:10C89000574856495A3009F0C6FD3046F8BDF8B53C
+:10C8A0000D4600231A46022100F064F9040004D169
+:10C8B0004F484E49683009F0B6FD681E052804D37C
+:10C8C0004B484A49693009F0AEFD0F21E2782079E2
+:10C8D000002310E0560036197779AF4206D1B179BE
+:10C8E00049084900B1715B1CDBB21146521CD2B23F
+:10C8F0000F2A00D100220646401EC0B2002EE9D108
+:10C900000F2905D248000019817901221143817154
+:10C910001846F8BD10B50446402801D2072010BDC6
+:10C9200000F056F8082802D03120000210BD002186
+:10C93000304802E0491C082903D24A00825A002AE2
+:10C94000F8D1082903D049004452002010BD04202A
+:10C9500010BD10B5402801D2072010BD00F038F8F6
+:10C96000082805D00021234A40001152084610BD76
+:10C97000052010BDF0B58BB016460C00074607D059
+:10C98000002E05D06188402904D207200BB0F0BDED
+:10C990001020FBE72088002801D0172801D90C209F
+:10C9A000F4E7084600F014F808280FD0258803A8FB
+:10C9B0002A463146023009F0B8FB01A8009062888F
+:10C9C0002B4607213846FFF732FCDFE70520DDE77D
+:10C9D00001460020074A02E0401C082803D2430019
+:10C9E000D35A8B42F8D1704702300000BCC500001A
+:10C9F000AD020000000C0020F8B50546E54C079E8E
+:10CA0000069821706270A370E6702071681C42085D
+:10CA10005200E14B0021880000198446C261605C2D
+:10CA200040008218002D0AD0002005E0664647002D
+:10CA3000F669401CF353C0B2665C8642F6D8491CC6
+:10CA4000C9B20529E7D30026D21C9708B000BF0061
+:10CA500000198760304600F042F9A15D761C48431A
+:10CA6000C219F6B2052EEFD3501B80B2F8BDF0B557
+:10CA70000546C84F8C460020FF247E5DA9009646DF
+:10CA80000346CF190CE0F9695A008A5AC2498A4212
+:10CA900004D1401CC0B2FF2C00D11C465B1CDBB291
+:10CAA0009E42F0D86146002909D100280BD0002D04
+:10CAB00007D0B84949788E4203D2401EC0B2002840
+:10CAC00001D071460C70F0BD70B5B24C8D000023E2
+:10CAD0002D19615C09E0EC695E00A45B844202D11F
+:10CAE0001370012070BD5B1CDBB29942F3D80020AB
+:10CAF00070BDFEB51C4617460D46060008D0002D39
+:10CB000006D0F01C80088000B04203D01020FEBD8B
+:10CB10000E20FEBD002F03D0002C01D0A74201D96A
+:10CB20000720FEBD0094234622463946002001948A
+:10CB3000FFF762FF2988814207D0814201D2042198
+:10CB400000E0092128800846FEBD009423462246C5
+:10CB5000394630460194FFF74FFF28800020FEBD84
+:10CB600010B5044600F0C5F8002801D0E0B210BDB1
+:10CB7000FF2010BDFFB50546874881B01E460C4614
+:10CB8000854204D0052C02D20398022802D300204B
+:10CB900005B0F0BD002769460F7028466A46214659
+:10CBA000FFF792FF00280ED068460178204600F07B
+:10CBB000A8F8002EECD00028EAD1284600F099F819
+:10CBC000002809D103E03846002EF6D1E0E7FF2027
+:10CBD00072A15C3009F027FC21462846039A00F038
+:10CBE0009CF8D5E7F8B505460C4600206A4E694624
+:10CBF0006E4F0870B5423BD0052C01D30720F8BD1D
+:10CC00000A4621462846FFF75FFF002830D06846D5
+:10CC10000178204600F075F8230009F0F5FC0504C2
+:10CC2000090C11161B0001462846FEF7D5FA15E03F
+:10CC3000FDF7E0FA12E001462846FFF74CFC0DE054
+:10CC400001462846F6F7B5FF08E001462846F8F702
+:10CC500012FC03E056A17B2009F0E5FB4D4A684633
+:10CC6000A10000788918C96940000E520020F8BD63
+:10CC70003846F8BD524A1268914201D210207047DE
+:10CC8000052801D3072070470872002048727047BA
+:10CC9000F8B504464A480068844201D21020F8BD25
+:10CCA000207A3C4A83009B18617A3B4D125C11E06C
+:10CCB000DE694F00F65BAE420AD04A1C6272DA6946
+:10CCC0004B00D25A228000F01CF860600020F8BDB2
+:10CCD000491CC9B28A42EBD861720520F8BD0EB575
+:10CCE000384B40000ECB0091029301926946085ADE
+:10CCF0000EBD28494978814201D9012070470020A2
+:10CD0000704770B50C460546FFF7E9FF214AA900B8
+:10CD1000891889686043401870BDF8B50C4606460E
+:10CD200000206946134608706A4619462046FFF7F8
+:10CD30009EFE002500282BD0164A6846A1000078E8
+:10CD40008918C96940000E52684601782046FFF7ED
+:10CD5000D8FF0546230009F057FC0504090C0F1401
+:10CD6000170029463046FEF713FA11E0FDF720FAC6
+:10CD70000EE0FFF78FFB0BE029463046F6F7E0FEAA
+:10CD800006E0F8F771FB03E009A1622009F04BFB14
+:10CD90002846F8BD100C0020FFFF00007372635C92
+:10CDA000686F73745F636D2E6300000002300000D3
+:10CDB0007372635C686F73745F636D2E6300000051
+:10CDC000280000206C67010010B5014620220948A8
+:10CDD00009F0ABF907490020C877084610BD06499D
+:10CDE000012048610548064A0168914201D10021AD
+:10CDF00001607047400C00200005004078000020D2
+:10CE0000BEBAFECA8107C90E002808DA0007000F63
+:10CE100008388008C24A80008018C06904E0800891
+:10CE2000C04A800080180068C8400006800F704724
+:10CE3000BD4948788978884201D3401A02E021220E
+:10CE4000511A0818C0B27047B74923314878897819
+:10CE5000884201D3401A02E02122511A0818C0B2B8
+:10CE60007047B149463148788978884201D3401AE1
+:10CE700002E02122511A0818C0B27047A94910B522
+:10CE80000C310868FF22120290430122D2031043A2
+:10CE90000860A54900202331487088702339487004
+:10CEA0008870463148708870A04808F0C8F89F48DC
+:10CEB000401C08F0C4F8F5F741FC00F028F910BD5B
+:10CEC00020207047B4E770B50C4605460026FFF7F2
+:10CED000AFFF9549A04214D30A46203A00232046CA
+:10CEE000641EE4B200280BD08878105C2870887823
+:10CEF0006D1C401CC0B288702128F0D18B70EEE709
+:10CF0000012600F004F9304670BD202070479BE7F1
+:10CF100070B50C4605460026FFF796FF824923317F
+:10CF2000A04214D30A46203A00232046641EE4B2ED
+:10CF300000280BD08878105C287088786D1C401C05
+:10CF4000C0B288702128F0D18B70EEE7012600F086
+:10CF5000DEF8304670BD202101700020704710B50A
+:10CF60000446FFF77EFF2070002010BD70B50C4610
+:10CF70000546FFF776FF6C494631A04215D30A46B5
+:10CF8000203A00232046641EE4B200280BD08878A3
+:10CF9000105C287088786D1C401CC0B288702128F5
+:10CFA000F0D18B70EEE7002400E0614C00F0AFF8A8
+:10CFB000204670BD70B50C460546212904D9FF20D6
+:10CFC0005CA1473009F02FFA55484068103840B24C
+:10CFD000FFF718FFC6B20D20FFF714FFC0B286425C
+:10CFE00007D2FF2053A14D3009F01DFA01E0F5F7FB
+:10CFF000E8FB21462846FFF766FF0028F7D070BD02
+:10D00000F8B507464948484C401E474E007825462B
+:10D0100046362335002806D1A9786878212200F009
+:10D020006BF800280ED0A1786078212200F064F817
+:10D03000002814D0B1787078212200F05DF8002823
+:10D0400028D033E038496878C91C0F546878401CF0
+:10D05000C0B26870212829D10020687026E03249CA
+:10D06000607820390F546078401CC0B2607021286D
+:10D0700001D1002060702D4F7F1E3878002815D018
+:10D08000A1786078212200F037F800280ED0002027
+:10D0900038700BE02449707826310F547078401CAA
+:10D0A000C0B27070212801D100207070A978687812
+:10D0B000212200F021F800281DD0A17860782122DB
+:10D0C00000F01AF8002816D0B1787078212200F00C
+:10D0D00013F800280FD0F5F756FB144807F0B7FFF8
+:10D0E00001214903884203D016A1C12009F09BF910
+:10D0F0000E4807F0C4FFF8BD401C884205D090429E
+:10D1000001D1002901D0002070470120704710B5DF
+:10D11000064807F09CFF002801D1F5F723FB10BD5E
+:10D1200000ED00E000E400E0800C00207D00002025
+:10D13000072000007372635C736F635F72616E64DB
+:10D140002E6300007372635C736F635F72616E6461
+:10D150002E6300000C4908784A78401CC0B2904207
+:10D1600000D008707047094A074820BF40BF20BF61
+:10D170004178037843701368002B02D103788B4207
+:10D18000F3D00020704700007F00002000E200E0A4
+:10D19000FEB5F34C07466068FF213E0181552178BA
+:10D1A000FF2913D00901083141583246491E08327F
+:10D1B00009020192090A805800F0C8F9002802D03B
+:10D1C0002478254615E06168207888552770FEBDD3
+:10D1D000E34842680198115828010090083010581F
+:10D1E00000F0B4F9002806D1DD482C4641680098CB
+:10D1F0000D5CFF2DECD1DA4821014068855547547C
+:10D20000FEBD70B5D64A04460020157A53680AE080
+:10D210000201561C9E5DA64203D10C329A588A42E6
+:10D2200004D0401CC0B28542F2D8FF2070BDF8B5D2
+:10D23000CB4F3E7801F013FE0146FF2E68D034013B
+:10D24000254678680835405900F080F9022802D94F
+:10D25000786840595AE0C2494868025D0A70A11CCA
+:10D26000425C002A0CD0521E425441590122D20580
+:10D2700089180902090A41513046FFF789FF30E059
+:10D28000631CC25C0092221D94468258002A10D072
+:10D2900001239B029A420FD99205920D43595703DD
+:10D2A000DB191B021B0A43516346C3589A1A920AA0
+:10D2B00009E0FF21C1540AE0435952039A181202AF
+:10D2C000120A4251002242543046FFF761FFA4483F
+:10D2D0000C344168C26800980959800012580098BF
+:10D2E00090479F4C2078FF2812D001F0B8FD0146EE
+:10D2F0002078626800010830105800F027F90128F2
+:10D3000096D92078616800010830085801F09AFD2C
+:10D31000F8BDF8B51C4615460E460746FF2B03D34D
+:10D3200090A1D32009F07FF88D48FF21C7604560A8
+:10D3300004720674017000224270104604E002017B
+:10D34000521C401CA954C0B2A042F8D3F8BD70B51D
+:10D35000834C06466578207C854203D381A1E62074
+:10D3600009F061F8E068A90046506078401C6070E0
+:10D37000284670BDFFB581B01D46FF2401F06FFD4A
+:10D38000774F064679780198814203D875A1F42039
+:10D3900009F049F872480021037A406810E00A0158
+:10D3A0009446521C825CFF2A24D0019FBA4205D1C8
+:10D3B00062460C328758029A97421DD0491CC9B266
+:10D3C0008B42ECD8FF2C17D021014B1C019AC25480
+:10D3D0000B33029AC250039B614F0022012B0ED0E7
+:10D3E0000B1DC25001239B029D4216D9AA05920D26
+:10D3F00008D008E00C46E1E7FF2005B0F0BD0B1DAA
+:10D40000C550EFE71A4653039B190E461B02083618
+:10D410001B0AAA1A8351920A09E0002D00D10125A6
+:10D420006B039B191D022D0A0B460833C550891C3E
+:10D4300042543D463E782046FFF7AAFE2878B04287
+:10D4400015D001F00CFD014628786A68000108300B
+:10D45000105800F07BF8012807D928786968000186
+:10D460000830085801F0EEFC01E0FFF7E0FE0198FB
+:10D47000C3E770B50C46054601F0F1FC06462146AF
+:10D480002846FFF7BEFEFF2817D0354D0401204681
+:10D49000696808300858314600F058F8012109033E
+:10D4A00040186968A41C095D400B002901D089025D
+:10D4B0000818002800D1012070BD002070BDF3B510
+:10D4C00081B00F460198FFF79CFEFF282AD0244D1B
+:10D4D0002E7869683246344604E0844205D02646F8
+:10D4E0002301CC5CFF2CF8D11CE0FF2C1AD0A64203
+:10D4F0001FD11001085C2870FF2818D001F0AFFC84
+:10D500002A780146120168680832805800F01EF837
+:10D51000012809D92878696800010830085801F005
+:10D5200091FC06E00020FEBDFFF781FE01E001F066
+:10D5300091FC39460198FFF79CFF22016968FF239F
+:10D54000541C0B558A5C3301CA54FEBD401A0002BC
+:10D550000121000AC905884200D900207047000057
+:10D56000CC0C00207372635C736F635F74696D65CC
+:10D57000722E6300F0B500241C4A01211C4B0803E5
+:10D58000546018601B4B1C601B4C20601B480469D6
+:10D59000E443E406E617046910252C430461184CA3
+:10D5A0006160184D2960761C00E020BF1F68002FC5
+:10D5B000FBD0002E03D107691026B743076190689E
+:10D5C0008005906801D5104A10436960A160002170
+:10D5D00019600121084A09031160F0BD10B5044625
+:10D5E000FFF7C8FF2060002010BD000000C500400C
+:10D5F00080E100E000C1004080E200E000ED00E0DA
+:10D6000000C3004000C0004000FCFFFF70B51F4990
+:10D610000A68002A17D000231D4601244A68521CBC
+:10D620004A60092A00D34D600E792246B2400E6846
+:10D6300016420AD072B60B6893430B6062B6496813
+:10D640000160002070BD052070BD5B1C092BE5D377
+:10D650000FA1362008F0E7FEF5E70120104980050C
+:10D6600008607047EFF31081CA07D20F72B601212C
+:10D6700081400648036819430160002A00D162B660
+:10D68000EBE7024800210160416070478400002000
+:10D690007372635C736F635F6576742E6300000062
+:10D6A00000E200E001208107086070470120810747
+:10D6B000486070471048C068C00700D0012070471C
+:10D6C0000D488068C00700D0012070470A484069B3
+:10D6D000C00700D0012070470748C069704706495D
+:10D6E0008A69D20306D589698907890F814201D1E8
+:10D6F000012070470020704700040040F8B5F84C46
+:10D70000207BE17A88421CD00126F64D0027E07A82
+:10D71000215C14200A4642435019037C052B11D08A
+:10D72000037C062B1CD0037C072B28D0437C012BC9
+:10D7300033D0EDA1EF4808F076FE207BE17A8842F5
+:10D74000E5D1F8BD0674E07A0A2807D0E07A401CDB
+:10D75000E072491CC8B2AA5802210CE00020F7E789
+:10D760000674E07A0A2808D0E07A401CE072491C6E
+:10D77000C8B2AA5803219047DFE70020F6E70674F5
+:10D78000E07A0A2807D0E07A401CE072491CC8B24F
+:10D79000AA580821EFE70020F7E74774E07A0A2843
+:10D7A00007D0E07A401CE072491CC8B2AA58072191
+:10D7B000E1E70020F7E770B50024CF4E0620707235
+:10D7C000CE4825464477047738300473C472CC4879
+:10D7D00007F035FCCB480575F572CB49601E8860B3
+:10D7E0007571B570F57035717570C848643905701C
+:10D7F00045701420604340180574641CE4B2052C85
+:10D80000F7D30120F5F764F80020F5F761F801205F
+:10D81000B071F4F727FDBE48F4F736FDBD4C20701B
+:10D82000BD48F4F731FD6070F4F7F2FF70BD10B53C
+:10D83000F5F719F8B74C2078F4F744FD6078F4F761
+:10D8400041FDAD4C207A002803D0F4F7CAFD00203A
+:10D85000207210BD70B5A84CA079002804D0A2A1F8
+:10D86000AE4808F0E0FD70BDE07A002803D19EA12B
+:10D87000AB4808F0D8FD0126A6710025E572607A54
+:10D88000042114225043974A801801749E488168ED
+:10D89000491C04D0691E81600120F5F719F80020A9
+:10D8A000F5F716F8F4F7FAFF07F00AFDF5F7FBF8BD
+:10D8B0009C480560056001209B49C0030860F5F79E
+:10D8C00071F992480078022804D0032804D1E07846
+:10D8D000002801D0A67000E0A570F5F7D0F870BD63
+:10D8E000034680490520142242435218203A127FF1
+:10D8F000002A04D0401E0006000EF4D17047142206
+:10D90000424351180A46803AD366012220390A77E9
+:10D910007047012805D0032805D1002903D1002034
+:10D9200070470029FBD010B4734C00236370774A12
+:10D93000002890700CD002280AD007291AD20800BB
+:10D9400078440079001887441505070D0F1113005E
+:10D95000D37003E01B2000E03A20D07001206070FB
+:10D9600010BC70475820F8E77720F6E79620F4E7D8
+:10D97000B520F2E710BC0020704710B5634840782E
+:10D98000F5F798F880B210BD411E1422504310B52F
+:10D99000544A8418203C042902D8207F002803D14F
+:10D9A00051A1624808F03FFD207F012804D0B32038
+:10D9B0004DA1800008F037FD0020207710BD70B524
+:10D9C0004E4C607F217F884201D1012500E0002577
+:10D9D000F5F709F8F5F76EF8617F227F914201D1E2
+:10D9E000012100E00021A942EBD170BDF7B5074647
+:10D9F000481E84468EB0C0B2142205905043394A66
+:10DA000085180495287C2D1D07282AD1344C002622
+:10DA1000E07A227B824221D0235C059A934201D195
+:10DA2000012601E0002E04D00A2811D0421CA25C7D
+:10DA300022540A280ED0401C227BC0B28242EBD175
+:10DA4000002E0BD0207B002806D0207B401E04E057
+:10DA50000022ECE70020EFE70A202073049A01205F
+:10DA600010746046244C042813D8142041431D48E8
+:10DA700008182038007F00280BD00498007C01286B
+:10DA80000BD00498007C012803D01098807A0128DC
+:10DA900007D015A1264808F0C6FC1098807A012806
+:10DAA0006FD104980F4B007C022845D00C4C207B92
+:10DAB0000A2872D0207BE17A401C884203D10AA157
+:10DAC0001C4808F0B0FC049901204874217B05989B
+:10DAD0006054207B0A2864D0207B401C20731CE10A
+:10DAE000D80D0020E80D00207372635C72656D2E06
+:10DAF00063000000CF0500006C0E0020A00D002088
+:10DB0000780E0020C00D00204C0E00208E0000205A
+:10DB10002FD200008C000020FDD600007D02000006
+:10DB20005E02000000F5004080E200E0CB02000051
+:10DB30001503000022030000607A059A0146904216
+:10DB400006D0014614267043C018807C9042F8D15C
+:10DB5000627A824208D1617A14225143C918897CC1
+:10DB600061720121A17207E014224243D2181426E7
+:10DB70007143927CC9188A74142206215043C0183C
+:10DB800081741098007A062819D201007944097925
+:10DB900049188F440812100E0C0AE07A00288ED023
+:10DBA00091E700209AE700200FE0B4200DE07320F9
+:10DBB0000BE0322009E00A2007E0062005E0FF2004
+:10DBC000FDA1E03008F02FFC0020029010980168C1
+:10DBD0000298081A28601099097A002912D00221A7
+:10DBE000401A0102090A296010980268406810185A
+:10DBF0000002000A68601098807A0228109803D00A
+:10DC0000007B74E00421EBE7007A002813D00222A5
+:10DC1000029810188446109842686046083016181A
+:10DC2000E848029A4078904202D9E278002A04D06B
+:10DC30003046083005E00422EAE7029A801A80198B
+:10DC40000830627A062A1CD0627A14235A43DE4BCB
+:10DC5000D2185268914214D0DC4B0793617A142297
+:10DC60005143D94A89184A688968D21BC91B1202D4
+:10DC70000902120A090A90423AD89A4238D89942BF
+:10DC800036D83818801B0002000A286010996044BA
+:10DC9000CF4AC9680002000A9446421A01239B0534
+:10DCA00007929A4201D2104614E00A1A09929A4247
+:10DCB00001D207980EE0079A6346624503D9591AC4
+:10DCC0000818401C06E0099A624506D9181A40183F
+:10DCD000401C4042002860DC03E0B7A1BD4808F0CA
+:10DCE000A2FB286880190002000A686000202872E0
+:10DCF0006868082608300002000A68601098407AB8
+:10DD0000A8721098007A687203280ED200280CD0EE
+:10DD1000FFF7D0FC002803D007E0002011B0F0BDD1
+:10DD200002983A210E1A32200290A6480178012961
+:10DD300001D0032909D141780298814205D9E078C0
+:10DD4000002802D10298081A861928689F4AC01B29
+:10DD5000844601026868090AC01B03021B0A029379
+:10DD60008E421AD81346914217D80299994214D874
+:10DD7000617A062915D0667A6146062203920092DE
+:10DD80001422914B7243D2189368DB1B8B4216D836
+:10DD90000396967C062EF3D177E0059801F055F9AD
+:10DDA000BBE70499022205980A74627A062A00D019
+:10DDB000627A8A7460720120A07211B0F0BD062EE2
+:10DDC00063D000223146944614227F4B4A43D21836
+:10DDD0005368DB1B834229D2917BAB7A99421FD8CF
+:10DDE00004980521059C01747B4D287B0A2811D0DD
+:10DDF000287BE97A401C884203D16FA1774808F05C
+:10DE000012FB287B2C54287B0A2807D0287B401C37
+:10DE1000287382E7E87A0028EFD0F2E70020F7E7DE
+:10DE200001218C46917C0629CED102E06046002873
+:10DE30002AD03546009114202A46424362480621E2
+:10DE4000171839741038007B0A28634816D0017BF4
+:10DE5000C07A491C814203D157A1614808F0E3FA16
+:10DE60005D48017B4554017B0A290BD0017B491C8D
+:10DE70000173BD7C0098A842DDD106E0C07A00287D
+:10DE8000EAD0EDE70021F3E70096049902204E4D19
+:10DE90000874607AB04207D1049900988874059894
+:10DEA00060720120A07221E00398062E0FD0062890
+:10DEB00003D141A14B4808F0B6FA0398142250430D
+:10DEC0004019059981740499009888740EE0062819
+:10DED00003D139A1444808F0A6FA0398142250430C
+:10DEE000401905998174049906208874012011B0A5
+:10DEF000F0BD70B50D463D4A441900210B46101A7D
+:10DF00008B4103D22CA13A4808F08DFA394885425A
+:10DF100003DD29A1384808F086FA3848854203DA3B
+:10DF200025A1374808F07FFA3648844205DA002CEC
+:10DF300001DB204670BD334800E03348201870BD37
+:10DF4000401E70B5C0B2142148431F494418607B7D
+:10DF5000062813D201007944097949188F44020C2C
+:10DF60000A080604002068E0B42010E073200EE0E8
+:10DF700032200CE00A200AE0062008E0FF200EA173
+:10DF8000E03008F050FA617B0020002955D00221D2
+:10DF90004018616840180002000AF4F78BFD0C2558
+:10DFA0006557124A441900210B46101A8B412FD293
+:10DFB00001A10F482AE000007372635C72656D2E48
+:10DFC000630000008E000020E80D0020FFFF3F00EE
+:10DFD000FFFFFF000E070000D80D00200702000021
+:10DFE000C5030000DD030000E3030000FF7F841E83
+:10DFF000F50300000020A107F603000000E05EF832
+:10E00000F70300000080841E00807BE108F00BFA1B
+:10E01000FB48854203DDFB49FB4808F004FAFB4856
+:10E02000854203DAF749FA4808F0FDF9F9488442D5
+:10E0300007DA002C03DB204670BD0421A8E7F54871
+:10E0400000E0F548201870BDF0B5064683B0F348EF
+:10E050000190457A029534687068001B0702F04809
+:10E060003F0A001B0090062D2DD014202946414365
+:10E07000EC480122081884464168E9489205864622
+:10E08000081B904210D3631A93420DD30246704688
+:10E09000724503D900984018401C05E073450ED91D
+:10E0A000411A0819401C404200280CDA60460295CB
+:10E0B000857C0198C0790028D5D003B0F0BDD14946
+:10E0C000D94808F0B0F90298854226D01421484377
+:10E0D000D4490123401802908068D1499B058C46A1
+:10E0E000011B8646994210D3221A9A420DD36346E9
+:10E0F000614503D900997144491C06E019466245FF
+:10E100002DD9091A0819401C4142002905DD029841
+:10E11000B17A807B814200D37446062D15D0C14967
+:10E120001420454368184268121B1202120ABA42B0
+:10E130000BD2B37A827B934200D38468857C0198AA
+:10E14000C0790028B9D1062DEAD13068A042B4D0F8
+:10E15000E0190002000A3460706003B0F0BDA94904
+:10E16000B14808F060F9D8E7F0B5B049044648680E
+:10E1700085B0C005C00D1CD0103840B200280CDAA4
+:10E180000207120F083A920892005118C9698007D5
+:10E19000C00EC1400806800F09E08108A44A89002A
+:10E1A000891809688007C00EC1400806800F002842
+:10E1B00008D000272078002806D0012804D00020AD
+:10E1C00005B0F0BD0127F5E72079062813D201003C
+:10E1D0007944097949188F44020C0A080604002082
+:10E1E00018E0B42010E073200EE032200CE00A208A
+:10E1F0000AE0062008E0FF208249E03008F013F929
+:10E2000021790020002905D002214618834D002FD6
+:10E2100002D003E00421F8E70020E871694602AA71
+:10E22000A068F4F751FC694608228A56E06801A903
+:10E2300080180122C01C1F2801DA019209E003AAFC
+:10E24000F4F742FC6846007B002802D00198401C8D
+:10E25000019000990198401808300002000A0190CE
+:10E26000881B0002000A0090607969468872009855
+:10E270000390F4F7B8FB009A019B121A181A6D4923
+:10E2800012020002120A000A8A4216D8884214D8E2
+:10E290006846FFF7D9FE00990398814205D0881996
+:10E2A0000002000AF4F706FCA0600120E9790029C9
+:10E2B00086D0002FB0D005B0F0BD0020F6E7F3B552
+:10E2C0008FB05D480C460B9006F0C1FE5B4A0F997B
+:10E2D000524F56185A4D203E00280BD05948007D09
+:10E2E000002803D058A15B4808F09DF82078012849
+:10E2F0007ED060E1687F0A280CD0687F297F401CAF
+:10E30000884203D150A1544808F08DF820780128A4
+:10E3100004D00CE0287F0028F4D0F7E7F07F002835
+:10E3200003D049A14D4808F07EF80120F077697FBD
+:10E330000F9814224A4E51438919087420780228F4
+:10E3400022D0687F14214843861920793072607981
+:10E35000707232460C323146A068F4F7B5FB0C20DF
+:10E3600030560F2804DD1F3830733068401C306091
+:10E370000C217156301DE26801905018C01C1F28F6
+:10E3800070DA01200199FDE028494868C005C00DF8
+:10E3900021D0103840B200280CDA0207120F083AD8
+:10E3A000920892005118C9698007C00EC140080642
+:10E3B000800F09E081081E4A8900891809688007D2
+:10E3C000C00EC1400806800F002804D105201EA100
+:10E3D000000208F028F8687F1421484386190021BC
+:10E3E000E0686A460691117006A9F4F76DFB00E03B
+:10E3F000D7E06A46002010560F2834DD012033E0B4
+:10E400000020A107B8DF0000F603000000E05EF87E
+:10E41000F70300000080841E00807BE16C0E00206A
+:10E42000FFFFFF00E80D00200E07000000ED00E0F8
+:10E4300000E400E0FFFF3F00780E00209200002083
+:10E44000A00D0020C00D00207372635C72656D2EFC
+:10E450006300000011050000EF040000F404000058
+:10E46000E00C002082E0002006994018079002206E
+:10E47000B0722079307260797072A068311DC01C52
+:10E4800006911F2801DA012009E0F4F71DFB684618
+:10E490000078002804D0069806990068401C08609F
+:10E4A000307A062813D201007944097949188F443B
+:10E4B000020C0A08060400200FE0B4200DE07320CF
+:10E4C0000BE0322009E00A2007E0062005E0FF20EB
+:10E4D000FD49E03007F0A7FF00202179002943D053
+:10E4E00002214018069071680830081807990890B2
+:10E4F00009180698081A0C900020F871F4F773FABE
+:10E5000004463060079820180002000AF060787A0C
+:10E51000062825D0797A14204143EC480818406831
+:10E520000899029040180002000A0390707A694628
+:10E53000887402A8FFF788FD0299039A091B121B31
+:10E5400009021202E24B090A120A0C98994207D8F2
+:10E55000824205D80299069808180002000A306025
+:10E56000F8790028C8D110E00421BAE704AA01997B
+:10E57000F4F7AAFA6846007C002804D001980199B3
+:10E580000068401C08602078B072687F0A2806D0B6
+:10E59000687F401C68770B9806F071FD47E000200B
+:10E5A000F8E7F07F002804D0A320CAA1C00007F03C
+:10E5B0003AFF0120F077CA490F98087420780228A2
+:10E5C00003D1C4A1C74807F02EFFC54E2079307291
+:10E5D0006079707232460C323146A068F4F774FAF2
+:10E5E0000C2030560F2804DD1F3830733068401C73
+:10E5F00030600C22B256301DE16801908818C01CB2
+:10E600001F2802DA012001990BE003AA0199F4F70F
+:10E610005BFA6846007B002804D0019801990068E5
+:10E62000401C08602078B072AD4901200875687FF1
+:10E63000297F884224D07C7A062C23D0F4F7D3F9A2
+:10E6400014214C43A14961180A7C042A18D00A7C81
+:10E65000032A15D04B6889681B1A081A1B0200028E
+:10E660009B4A1B0A000A082B0AD31146934207D87B
+:10E67000884205D8687F297F884201D0F4F7FFF9E6
+:10E6800011B0F0BD687F297F8842F7D111B0F0BD8D
+:10E6900010B50020F4F709F910BD10B50120F4F70A
+:10E6A00004F910BDF1B5009802281ED08E4C607A96
+:10E6B000062803D187A18D4807F0B5FE0026A67174
+:10E6C0000125E572607A03211422804F5043C0195E
+:10E6D0000174F4F7D9F9009800280BD0012829D04B
+:10E6E000032879D07BA1824844E082480078F3F780
+:10E6F000EFFDF8BD8048007F002803D075A17F485A
+:10E7000007F091FE65717C4D00202E60F4F7E0F873
+:10E71000A968481C04D0012300221846F4F70EF91A
+:10E72000607A617A401CC0B2142251437A580121A8
+:10E730009047F8BD0120F4F7CBF8607900280DD0A0
+:10E740006D488068401C09D0607A617A401CC0B274
+:10E75000142251437A5806219047F8BD6648007F3D
+:10E7600001280AD0022812D0032822D0042834D04D
+:10E7700058A1634807F057FEF8BD2079002803D060
+:10E780002671F4F786F9E5705B480677F8BD207AC4
+:10E79000002802D1F3F7FCFD2572607A617A401CF3
+:10E7A000C0B2142251437A5800219047524806774C
+:10E7B000F8BD514F0123397B78680022411A184671
+:10E7C000F4F7BCF82079002803D02671F4F761F93A
+:10E7D000E57002203877F8BD19E0474E217870685F
+:10E7E0000123411A00221846F4F7A8F8207A0028DD
+:10E7F00002D1F3F7CDFD2572607A617A401CC0B278
+:10E80000142251437A58002190473577F8BD607A39
+:10E81000617A401CC0B2142251437A5805219047B6
+:10E82000F8BD10B5304C607A062803D129A13548CF
+:10E8300007F0F9FD607A617A401CC0B2142251439E
+:10E84000224A52580421904710BDF0B583B00620EB
+:10E850000290F4F7C8F8244C0090617A2A4801909D
+:10E86000062920D0617A1420414318480918097CF0
+:10E87000042918D0617A142251430818007C032817
+:10E880007BD0019900980B6849681B1A081A1B0273
+:10E8900000020F4A1B0A000A082B6ED3114693424E
+:10E8A0006BD8884269D814488068401C03D009A1FD
+:10E8B000164807F0B8FD00206071607A06282CD158
+:10E8C0006078002829D023E0B8DF0000E80D0020A0
+:10E8D000FFFF3F007372635C72656D2E6300000082
+:10E8E000C00D00201E0500006C0E00204F0500002A
+:10E8F000A20500008C0000204C0E00205B050000EB
+:10E9000096050000A90500005C0E0020E50500004A
+:10E91000FE48C178417081780170607A062815D070
+:10E92000607A1421FA4A48438018007C04280DD1EB
+:10E93000607A0290607A0121142358438018017490
+:10E94000607A58438018807C6072A172F14D687FB4
+:10E95000297FF14F884233D0F04E287F142148435D
+:10E960008019007CC05D0128287F07D048438019AA
+:10E97000007CC05D02282FD044E0FDE11421484313
+:10E980008019807A01280AD0287F0221142250435E
+:10E990008019007CC155287F0A2808D009E0287F0B
+:10E9A0000021142250438019007CC1552AE0002028
+:10E9B00001E0287F401C2877687F297F8842CCD1DE
+:10E9C000D74D287D00284CD0287CC15D012928D056
+:10E9D000C05D022830D03AE0287F142148438019D6
+:10E9E000807A012803D0CFA1D14807F01CFD297FF0
+:10E9F00000201422514389198872297F51438919B3
+:10EA0000097CC855287F142148438219287F484330
+:10EA10008019017C0098FEF7E9FF287F0A28C8D1F9
+:10EA2000C5E7A97A012904D00221C1550020287523
+:10EA30000DE00021C1550AE0A87A012803D0B9A150
+:10EA4000BC4807F0F0FC0020A872297CC855287D3E
+:10EA5000002806D0297CB24A0098FEF7C7FF0020A4
+:10EA60002875029806281ED014214843A84940184A
+:10EA7000017C012917D107210174AF4D287B0A2899
+:10EA80003CD0287BE97A401C884203D1A5A1AB4841
+:10EA900007F0C9FC297B02986854287B0A2831D0EA
+:10EAA000287B401C2873607A06287DD0A07A002835
+:10EAB0007BD00020A072617A1420414394480E1844
+:10EAC0009F49B56873680A46F6687C32CB679660E2
+:10EAD00055609C4D697E002916D00226617A142269
+:10EAE0008B4851430818407B06281BD2010079440B
+:10EAF000097949188F440A1412100E0CE87A00287C
+:10EB0000C4D0C7E70020CDE70426E7E700210FE0E7
+:10EB1000B4210DE073210BE0322109E00A2107E066
+:10EB2000062105E0FF208849E03007F07CFC002149
+:10EB30002973687E022801D0012810D12869009A23
+:10EB40004018821A1202120A3A2A08D932380321CE
+:10EB500000026976000A28613220287308E0322911
+:10EB600006D2207A00280AD1F3F712FC012005E032
+:10EB7000207A002803D0F3F734FC00202072634988
+:10EB80000822487820700978012901D0032906D18C
+:10EB900001212171297B884201D9421A0832A378C8
+:10EBA000002B00D0921C01E08DE09BE02179002930
+:10EBB00001D1002B5DD09446644A00990092019ADD
+:10EBC000176852687F1A511A3F0209023F0A090A60
+:10EBD000BC451BD85D4A974218D8009A914215D877
+:10EBE000297B884223D92B69421A9A1A1202120AE7
+:10EBF000101880190002000A2A616860002914D0E8
+:10EC0000032028770006000E3ED14CE00020207142
+:10EC1000A070297B002925D028694018801900029E
+:10EC2000000A6860022028772EE00120E9E781428F
+:10EC30000BD92A69511889190902090A6960002843
+:10EC400001D00420DDE70220DBE7002B03D135A152
+:10EC50003F4807F0E8FB286980190002000A686055
+:10EC6000002004E0296989190902090A69602877E6
+:10EC700019E0287B00280FD02969081880190002A4
+:10EC8000000A686002202877286901238119002280
+:10EC90001846F3F753FE09E0286980190002000ABC
+:10ECA0006860002028770120F3F712FE607A1421B3
+:10ECB000484317490C2240188256012300206968F6
+:10ECC000F3F73CFE0EE00120F3F702FE0020F3F71D
+:10ECD000FFFDF3F7E3FD207A002803D0F3F781FB73
+:10ECE00000202072A078002804D0F3F7D2FE002084
+:10ECF000E070A0706078002804D00448C1784170AA
+:10ED000081780170207900282BD023E08E0000202C
+:10ED1000E80D0020A00D002091000020E00C002054
+:10ED2000C00D00207372635C72656D2E630000007D
+:10ED30000706000023060000D80D0020350600005D
+:10ED4000E00D00204C0E0020B8DF0000FFFF3F0068
+:10ED5000870600000020CF49E0700978002900D123
+:10ED60002071CD48017BC07A814203D0CB484078E6
+:10ED7000F3F7AEFA0120E07103B0F0BDF0B5C84C76
+:10ED80000746607A83B0062803D1C6A1C84807F0B9
+:10ED90004AFB607A1421C74E48438019007C03283F
+:10EDA00003D0C0A1C44807F03EFBC44DA868401C76
+:10EDB00003D0BCA1C24807F036FB607A1421484357
+:10EDC00081190C20085600216A4600911171C01962
+:10EDD00001AA6946F3F778FE6A46042010560F2808
+:10EDE00001DD012000E0002000994018696840180A
+:10EDF0000102090AA9606079002804D001230022D9
+:10EE00001846F3F79BFD03B0F0BD70B5AE4CAD4AAC
+:10EE10000B1AA34214D3451AA54211D3934203D926
+:10EE2000101A43185B1C0BE0954204D9511A0818BC
+:10EE3000401C434204E0A549A54807F0F4FA00232A
+:10EE4000184670BD10B50146012300220220F3F7D9
+:10EE500075FD10BD10B50220F3F73AFD10BD10B5D9
+:10EE6000F3F7C1FD10BDF0B58D4D0446E87A83B0CF
+:10EE7000002803D18BA1974807F0D5FA642C4DD315
+:10EE8000954900200246091B824147D39348417FA0
+:10EE9000007F814242D19248007D00283ED1687AAD
+:10EEA0001421844F4843854EC519306801AA0019C2
+:10EEB0006946F3F709FE694604200856002802DD7A
+:10EEC0000098401C0090A96800986B680A18D21A34
+:10EED0001202844B120A9A4220D8AA7C062A08D031
+:10EEE00014235A43D2195268511A0902090A81425D
+:10EEF00014D3B068401C05D00120F3F7E9FC0020D2
+:10EF0000C043B060306800193060A86800994018AC
+:10EF10000002000A7061012003B0F0BD002003B0C0
+:10EF2000F0BDF8B50646401EC5B2142061496843DD
+:10EF30004418207C002803D15AA16B4807F073FACB
+:10EF40006648017F407F81420CD0684A14234B43BE
+:10EF50009B181B7CB3420CD00A290CD0491CC9B2A7
+:10EF60008142F3D15E48017D002964D0007CB0422B
+:10EF700061D10020F8BD0021F1E7217C052905D0F1
+:10EF8000217C062902D0217C072928D10121217466
+:10EF9000C17A0023027B8A4221D00246565CAE42EF
+:10EFA00001D1012301E0002B04D00A2911D04E1C0D
+:10EFB000965D56540A290ED0491C167BC9B28E4262
+:10EFC000ECD1002B0BD0117B002906D0117B491E00
+:10EFD00004E00026ECE70021EFE70A211173617CD1
+:10EFE00000292AD06774C17A0023027B8A4224D088
+:10EFF000425CAA4201D1012301E0002B04D00A297E
+:10F0000012D04A1C825C42540A290FD0491C027B50
+:10F01000C9B28A42ECD1002B0FD0027B0146002AF4
+:10F0200006D00A7B521E04E00022EBE70021EEE747
+:10F030000A220A7301E018480027217C01299CD18B
+:10F04000617C002999D10120F8BD70B505461420D6
+:10F05000184A05216843801801740F4C207B0A2848
+:10F0600011D0207BE17A401C884203D11749204807
+:10F0700007F0D9F9207B2554207B0A2807D0207B74
+:10F08000401C207370BDE07A0028EFD0F2E700202A
+:10F09000F7E700008E000020D80D00208C00002033
+:10F0A0006C0E00207372635C72656D2E630000004D
+:10F0B000EA060000E80D0020EB0600004C0E0020E0
+:10F0C000EC060000FF7F841E0020A107B8DF0000CF
+:10F0D0000E0700002D070000FF1FA107A00D002054
+:10F0E000C00D0020FFFF3F006A070000E00C002079
+:10F0F0000702000070B5FF4D00246C702C70AC61ED
+:10F1000000F0CEFC284620304470C473AC6214304A
+:10F110002C6305F094FF002804D0FF20F6A14E30A8
+:10F1200007F081F92C7770BD0B23DB4310B5C21AB1
+:10F13000F54998421FD008DC1C3222D00A2A20D080
+:10F14000142A1CD0182A08D117E0083011D004283E
+:10F150000DD0082809D00C2805D0FF20E6A1753075
+:10F1600007F061F910BD04200CE000200AE0FC204B
+:10F1700008E0F82006E0F42004E0F02002E0EC20B3
+:10F1800000E0D820C86010BD70B50125DF49022617
+:10F190000E60DF490022CA63CD63DE49C96A0907F0
+:10F1A0000ED4DC494031CB6ADB4A53620B6B93626D
+:10F1B0004B6BD3628B6B1363C96BD30519435163DC
+:10F1C000D14C002826D0012828D0FF20CAA1A13088
+:10F1D00007F029F9D148A063FF200430606325635C
+:10F1E00003202061C849962040314860C1491C2055
+:10F1F0000856FFF799FFCB49C9488860C948CA49F2
+:10F2000080304160C9490160C9480660C949102081
+:10F21000486070BDC8486061C84803E0C848606184
+:10F22000C648801FA061D5E770B50C46B14D0146B8
+:10F230000622A81C06F079FF2C7270BDAD48203064
+:10F2400040787047AB4A517010707047F8B504466B
+:10F250000D465079117900020843690009190884A4
+:10F260001F461646501C06F0C1FF317800020843C5
+:10F27000A90060502846083001268640002F0ED095
+:10F28000012F04D0FF209CA1E83007F0CCF8206BC0
+:10F29000304301460120A84001432163F8BD206BA3
+:10F2A000B043F6E770B50D460446082904D9FF209F
+:10F2B00091A1F93007F0B7F80022A24809E09100C7
+:10F2C000635809180B6053001B191B8C0B62521CEE
+:10F2D000D2B2AA42F3D3206B9A494031086070BD84
+:10F2E00010B50446FFF720FF8248047710BD81481F
+:10F2F0002030007B704710B5834CC178616206F006
+:10F3000075FF0002E06110BD252808D0262808D02E
+:10F31000272808D041000A2807D8091D06E0022145
+:10F3200005E01A2103E0502101E0891DC9B2764AA7
+:10F33000916075494031486170476E4988617047F6
+:10F3400070B5002818D002226A4C784B0320A272B4
+:10F35000F0331860734D72486860002001262075F4
+:10F3600000290BD0012910D002291BD0952062A1C1
+:10F37000800007F058F870BD0122E5E77248012AC5
+:10F3800001D0466070BD066070BD5A48012A006B0E
+:10F3900005D00121490508432063696070BD012142
+:10F3A0000905F8E7A069002803D153A1674807F0D1
+:10F3B0003AF8A169A06A40186549886059486549CA
+:10F3C0008030816060491031C1600120216BC00331
+:10F3D00001432163686047482030C67370BD08B59B
+:10F3E0000C20694608705148002110380161564AC6
+:10F3F000012111610BE000BF00BF00BF00BF00BFD3
+:10F4000000BF00BF00BF6A461178491E11706946EF
+:10F410000978002902D001690029ECD068460078FB
+:10F42000002804D1494834A1203006F0FCFF08BD73
+:10F43000F8B53E4CF034206886083E48B600416876
+:10F44000C906CD0F10218160002727603549344857
+:10F450008860FFF7C4FF35481038076100F020FBD3
+:10F460002660002D02D0334910204860F8BD10B549
+:10F4700006F0BCFE00022449000AC86310BD2349FF
+:10F48000022008602A49086070472049022080391C
+:10F4900008607047304908707047164810B534301E
+:10F4A00005F0D5FD002804D0284813A15A3006F0F5
+:10F4B000BAFF10BD0F4810B5343005F0E0FD10BDA7
+:10F4C00011494860704770B50A4D0446A86AA042C9
+:10F4D00004D31E4808A16B3006F0A5FF0120287355
+:10F4E0001C49002008392C6148601948446000F02C
+:10F4F000DEFA70BD7C0E00207372635C68616C5F25
+:10F500007263732E630000000015004080E100E08C
+:10F51000C01F004080000010001700405B06000084
+:10F520000040000400F50140408000401011004000
+:10F5300080E200E000130040060102002500030203
+:10F5400005010300001600400010004047020000C3
+:10F5500040850040488100409700002010B5FF48DA
+:10F5600002210173C6210161FD4A00215160806AB8
+:10F57000FC49C630486000F09AFA10BD0121FA48F3
+:10F5800089058160F548026B8A430021026301739B
+:10F590007047F64801214160C160F1490020486090
+:10F5A000F0494860ED4988627047F149402008629F
+:10F5B000F0490A6802430A607047EE480168402239
+:10F5C00091430160EA49002008627047E9480168F8
+:10F5D000102291430160E849012088617047E749A2
+:10F5E0000020C861E34801681022114301607047A0
+:10F5F000E249CA69012A01D000207047DC4A9268BA
+:10F600005206520E524202700020C861012070471B
+:10F6100070B5D248D24D017B002902D0696801291A
+:10F6200009D00024D5490A69012A06D00023807A2E
+:10F63000012804D006E00124F4E74023F7E7CA6874
+:10F64000012A04D000221A43012802D004E020221B
+:10F65000F9E74B68012B05D000231343C84A022861
+:10F6600002D007E01023F8E71668012E02D1CE6819
+:10F67000012E04D000261E43022802D007E00826EF
+:10F68000F9E71268002A02D1CA68012A04D00022D0
+:10F690003243022802D005E00422F9E7002C01D011
+:10F6A000022300E000231343022807D14868012801
+:10F6B00004D16868012801D0012600E00026B14885
+:10F6C0001E4302681206120E02D04A69012A00D0B7
+:10F6D0000022A24C2034227300680006000E02D0E3
+:10F6E0008869012800D000206073A148006A0028C2
+:10F6F00003D000F0A8FA012800D00020A07300F089
+:10F70000C7F9002068603046F3E670B50C00054686
+:10F7100003D19D499D4806F086FEE00706D0012CE6
+:10F7200004D06D209849C00006F07DFE002D0ED05B
+:10F7300002218A4801294172C4728E4809D00229E7
+:10F740000AD0924890491A3006F06DFED1E60121A8
+:10F75000EFE70168042201E001680822114301601B
+:10F76000C7E670B57D4C0022E37A990701D54107C1
+:10F7700014D47A49DD062031002D05DA4D7B002DA9
+:10F7800002D08D7B002D09D01D0702D50D78002DEC
+:10F7900004D15B0703D54978002900D10122637A9F
+:10F7A0007449002B06D00225284010430CD0FFF7E7
+:10F7B0003FFE9EE66C4A76489060086880088000AC
+:10F7C000086000F06DF994E6012B07D0022B0ED0F3
+:10F7D0006E486D496B3006F026FE8AE60868042202
+:10F7E0009043086000F05CF90120A07281E608688F
+:10F7F00008229043086000F053F9A57279E6574952
+:10F8000008757047F8B5554F544D2037FA7B564C64
+:10F810000021286B002A31D00122D203A26090433C
+:10F820002A46544D10632E685A4A102090600020DA
+:10F8300028601014A060FFF7D2FD00F029F92E60B7
+:10F84000281460605349102048604448817A4A482F
+:10F8500001290DD002290ED04C484FA1801F06F07F
+:10F86000E2FD0020F8733D48007D022874D0F8BD09
+:10F8700001210160F5E701214160F2E73A4A906019
+:10F880000E462963FFF7C4FE044636482E754168CC
+:10F8900069620068A862AA7A022A0AD16A78002AF4
+:10F8A00007D0334B403B5B681B7813402A789A4360
+:10F8B00008D03E70E20708D0084603F04AFD012157
+:10F8C000A86A09E001223A70F4E7A10601D50221F5
+:10F8D00002E0A10702D5002103F04BFD2448403887
+:10F8E00041680622A81C093106F0F2FB002809D164
+:10F8F0001F48297A403840680078C009814201D108
+:10F90000012000E0002078702046FFF72AFF2648FB
+:10F91000007800280DD001284AD002285BD00328A7
+:10F9200078D01DA1214806F07EFDA87A022870D06B
+:10F93000A3E0A00701D502F0EDFB200702D50120CE
+:10F9400002F020FC600702D5002002F01BFCA0069C
+:10F95000EBD502F07CFBE8E793E000007C0E002092
+:10F96000408100404085004000F50140008000409B
+:10F9700040150040001200400010004000110040FF
+:10F980000014004040160040F8F40000630300003B
+:10F9900000400004001300407372635C68616C5F98
+:10F9A0007263732E6300000097000020E6040000DD
+:10F9B000A00701D504F0BBFF200702D5012004F009
+:10F9C00021FF600702D5002004F01CFFA006ACD583
+:10F9D00004F0A4FEA9E7A007BF27002802DA3C40F4
+:10F9E000F3F702FB200703D53C400120F3F7FBFAB5
+:10F9F000600703D53C400020F3F7F5FAA00602D5D6
+:10FA00003C40F3F7EFFA60068FD5F3F7EEFA8CE798
+:10FA100000E012E0A00701D5F3F7EAFA200702D5CB
+:10FA20000120F3F7E4FA600702D50020F3F7DFFACC
+:10FA3000A00690D5F3F7DAFA77E7287B00281CD0E8
+:10FA40001F494E6002281FD0012803D01D491E48BF
+:10FA500006F0E9FCA96A2869884204D81A481949BD
+:10FA6000401C06F0E0FC2969184841600120296B20
+:10FA700080050143296316494860287D012800D08C
+:10FA8000F5E6F3F7C5FAF8BD2969A86A4118EBE76E
+:10FA900010480021C160016141604161816170478E
+:10FAA0000D480021417281720121C17270470A48DC
+:10FAB0000121026B89050A430263054841607047D2
+:10FAC0004081004098F90000FB04000040850040A0
+:10FAD00000F50140001100407C0E00202E4800215E
+:10FAE00001704170704770B5064614460D460120FE
+:10FAF000F1F758FC28490120284B08709E60DC6013
+:10FB00001D6170BDF8B504460120F1F74BFC224998
+:10FB10000120087021494C60214900264E600321D4
+:10FB2000204D0906A960204F002C0AD0012C03D0DB
+:10FB30001EA1412006F077FC3E60032000066860AD
+:10FB4000F8BD386001200006F9E710B512480178C9
+:10FB500000290ED00321134A0906916010494A6812
+:10FB60000021002A03D0154A1268427000E041705B
+:10FB700001700020F1F716FC10BD0748017800293C
+:10FB800007D007484068002802D00C480068C0B27F
+:10FB900070474078704700009800002000F5004052
+:10FBA00000F1004000F5014000F200407372635C18
+:10FBB00068616C5F63636D2E6300000000F40040B9
+:10FBC0003A4800210170417010218170704770B572
+:10FBD000064614460D460220F1F7E4FB01203349A6
+:10FBE000334A0870E41E14619660556070BD10B50C
+:10FBF0000220F1F7D7FB2D49012008702D48002184
+:10FC000001604160816001202B49C005486010BD42
+:10FC100010B5264C2078002811D001202649C005B7
+:10FC2000886000F034F80021002804D001206070C2
+:10FC30002248006801E061701020A070217000204F
+:10FC4000F1F7B0FB10BD10B51848017800290BD0B2
+:10FC500018480068002805D000F019F8002800D0E6
+:10FC6000012010BD022010BD407810BD10B50F4816
+:10FC70000178002909D000F00AF8002803D00F48C5
+:10FC80000068C0B210BD102010BD807810BD0948BA
+:10FC90000168002905D04168002902D08068002849
+:10FCA00001D0002070470120704700009A0000201A
+:10FCB00000F5004000F1004000F5014000F4004074
+:10FCC000FFB593B0044600201D9E049015981C9D1E
+:10FCD0001027082806D0E06901F014F8002809D0A0
+:10FCE0003770CCE028880921384328801F980227E4
+:10FCF000017016E0E169012088710521E269C902FD
+:10FD00009180E1698872E169F9480881E169002020
+:10FD10008873288820210843288011211F980427F0
+:10FD200001701F980225801C0390307810900A20E3
+:10FD30003070204618301190F6F76BFC00206FE011
+:10FD40001598102809D1022D07D06846828A049997
+:10FD50000398401A8270110AC1706846C08A1699C9
+:10FD6000884203D9E349097A149106E0884204D114
+:10FD70001099002901D0317021E003990870000A20
+:10FD800048701E980088401BC01B83B2FF20C01B18
+:10FD9000984200D203460398149AC0190CA9009205
+:10FDA000019002912020015D6846C08A0022F6F78A
+:10FDB000A5FC3070002806D0C0B2832862D0684607
+:10FDC000C08A208345E00F98002805D0C948006804
+:10FDD00000790A2830D33CE06846008EC119C9B2C8
+:10FDE0000491022D0FD01F99049A4978914203D1B2
+:10FDF0006A46128C824209D0BE480491006801789C
+:10FE0000032909D027E008461F994870B9480068BF
+:10FE10000178042906D008E000790A281BD20120C5
+:10FE20000F9009E06946C98A8180039904980818EF
+:10FE300003900498281885B205AA14991198F6F72A
+:10FE4000EBFB002805D11E980088401BB84200DB60
+:10FE500076E7022D0ED01598102807D1049A039941
+:10FE60006846808A891A8870000AC8701E980580C2
+:10FE7000002030709F4800680078032802D00020DE
+:10FE800017B0F0BD0220FBE7F8B50446406B002632
+:10FE9000134600282BD0491F8DB2618F2A460832A5
+:10FEA000278F8A18BA4221D89A7840185F781102B1
+:10FEB00039430170090A41701A79DF781102394318
+:10FEC0008170090AC1700571290A41712A46591DBC
+:10FED000801D06F02AF9608FAD1D401980B2608741
+:10FEE000626B002110180170417000E00926304655
+:10FEF000F8BD30B50B88048F9C4212D9446BE018D2
+:10FF00004478057824022C430BD0447905792402E7
+:10FF10002C436404640CA41D1B190B80106000208A
+:10FF200030BD822030BDF7B588B000256846058217
+:10FF300005275DE00398417802780E021643417967
+:10FF4000027908021043000452D40A980123068063
+:10FF500005A802905B02002200970195304609999E
+:10FF6000F6F7CCFB04004AD16846018A0183039866
+:10FF70004179027909021143437802781C02144343
+:10FF8000B4421ED10A041CD44B0401215B0C89032A
+:10FF900000950B4301970295C17880780A020243CD
+:10FFA00020460999F6F7C6F9040011D1039948795A
+:10FFB0000A79000210430122D20310430871000A9B
+:10FFC000487103AA06A90898FFF793FF0400CED052
+:10FFD0000399009501970295487809780002084333
+:10FFE00069468B8A00220999F6F7A4F9822C06D17A
+:10FFF00003AA04A90898FFF77CFF04009AD068467A
+:020000040001F9
+:10000000058209E003984179027909021143490404
+:10001000490C0171090A417103AA04A90898FFF764
+:1000200068FF0028EED0822C02D020460BB0F0BD35
+:100030000020FBE730B50446406B002597B0002850
+:100040000DD00B2268460270228F0281606B0391F3
+:10005000019000216846F3F7E2FA6846057065638F
+:100060006587258717B030BDF8B50F460546696B23
+:100070000020069E144600290FD0012B0DD13246D8
+:1000800039462846FFF74FFF002806D1002C04D040
+:1000900032463946284600F044FEF8BD0022028070
+:1000A000C262831D0263C3614263428702872030BC
+:1000B0000170704710B50022D24302800420FDF782
+:1000C000FEF910BD10B596B00446FFF7B3FF208EC1
+:1000D000002808D0012069460870E06A01900021DC
+:1000E0006846F3F79CFA0020E062206316B010BD6A
+:1000F00001280000B40E00200146098800200A07EC
+:1001000000D501200A06120F01D002221043CA05B1
+:1001100001D5042210438A0501D510221043490558
+:1001200001D5202108437047FFB5A9B00600329DD4
+:10013000359C2B981F46229016D0007841060FD48C
+:100140008106890E1E2909D021884A05520E0BD13D
+:100150003A88172A08D3FE4A914205D0C10906D031
+:100160008006800E122802D003202DB0F0BD20465C
+:100170002C302690F7492A980872002018AA03907C
+:1001800010726A46107404AA0A60339A4A6020AA60
+:10019000908090812298007801908106681C1C90C4
+:1001A000701F1D902B98890EC21C2492224620326B
+:1001B0001B92083A401C02920B0006F025FA1FFD24
+:1001C000FD11FD1FFD8EFDFCFDFBFDFAFDF9FDFCA3
+:1001D000FDF8FDFDFDF7FDF6FDFDFDFDFDF5FD0066
+:1001E000032E76D102E018A9087219E303202870C3
+:1001F0001C9917220A7000224A70CFE2052EF0D116
+:100200004178027808021043208320A98880249A2C
+:100210005178127809021143618300287ED0884208
+:100220007CD800202072E080401E60840298F6F79F
+:10023000F0F905202870A81C0190022000901BAA4C
+:100240002A990298F6F7E8F9002868D118A8807C66
+:10025000012803D002206870102002E0012068709D
+:1002600002202490002225A91CA8F2F746FD0028B0
+:100270002BD120A8007D2499814226D13A8800996B
+:10028000801C511A814220DB10A8C18D0198017099
+:10029000090A417001991CA8891C01910099019AD1
+:1002A000891C009125A9F2F728FD20A8007D01995D
+:1002B0001BAA091801910099081880B200902A9988
+:1002C0000298F6F7A9F90028CCD00098022826D089
+:1002D00064E272E018A9087261E2072E6DD34178DA
+:1002E0000346027808021043208320A98880249ABC
+:1002F0005178127809021143618300280ED0884298
+:100300000CD8012020725879197900020843E08046
+:1003100000202073E06900F0F5FC01E098E0A9E01E
+:1003200000280ED1E169012088710521E269C90226
+:100330009180E1698872E16987480881E16900205C
+:100340008873F01F60842298C01D60620298F6F7DF
+:1003500060F907202870681C00900120019000209F
+:1003600010A9C8852FE00198012814D0E069807990
+:10037000012830D000981E38417F007F09020143D8
+:1003800000980170090A41700098801C0090019843
+:10039000801C80B2019010A8C18D00980170090ADC
+:1003A00041700098801C09E00AE296E13BE1DFE041
+:1003B00004E29BE077E036E016E2AFE000900198BF
+:1003C000801C80B201901BAA2A990298F6F724F9A2
+:1003D000002803D007E010A8818DD1E73988019863
+:1003E000081A0428BFDA0198012843D0E06980790F
+:1003F000012804D010A8818D5548814206D110A84B
+:10040000818D00980170090A417009E000981E383A
+:10041000417F027F0802009910430870000A48706B
+:100420000198801CBAE1072E01D0152E76D14178B3
+:10043000027808021043208320A98880249A5178EA
+:100440001278090211436183002801D0884201D942
+:1004500001203FE7012020720020E0802073052E5C
+:100460000AD01D982299E269C0B2491DF2F71FFC1B
+:10047000002801D00A202DE70020C04360841AA87C
+:10048000019023A9229802970395009100780023F8
+:100490008206920E20462A99FFF712FC0390208BC9
+:1004A00020A988807BE1032EC0D1402220A98A8127
+:1004B0004178027808021043208320A988802A9975
+:1004C0001EAB1C9A02930192009139880022491EAA
+:1004D0008BB21B990978F6F711F918A90872002850
+:1004E00033D10B20287010A8008F3FE0052E9DD13E
+:1004F000802220A98A814178027808021043208353
+:10050000249984464A78097812020A43628420A911
+:1005100088801248824202D30720DBE6AFE03F200A
+:100520008002024362842A981FAB1C9902930191B6
+:1005300000903888401E83B21B9801786046F6F719
+:10054000DDF818A9087200280CD08328AAD107E08A
+:10055000FFFF0000B40E002001280000010200008F
+:100560000220B8E00D20287010A8808F401C15E1F3
+:1005700001990C22C9095143C91CB14204D90198FF
+:1005800040067CD5002009E1427803781002184328
+:1005900020AA9080844622980078400609D505203C
+:1005A0006A46107422980078C00905D000201074A3
+:1005B0001DE106206A46107424981F902A9A009024
+:1005C0000023701A029383B21E9001921B9800229E
+:1005D00001786046F5F7AEFE18A908720022694658
+:1005E0000A74832801D102200390229800784006E3
+:1005F0000DD52088C00506D520A9208B8988884282
+:1006000001D100206062002018A90872C6E0FF2115
+:10061000013120A88181808820831E9860841F98E2
+:1006200060621320B8E0052E29D3417802780802D1
+:10063000104320A98880218F002902D0FE4A9142D0
+:1006400006D10A216A4611740121C943218702E0BB
+:1006500007216A46117422992A9A491D0192009134
+:1006600001221D990023D203029311438BB22499D6
+:100670004A78097812020A431B99097800E0C9E018
+:10068000F5F758FE18A90872002269460A7401227B
+:10069000520220A98A81832808D0002809D0218FFE
+:1006A000E54881427ED10020208778E08888208339
+:1006B0004DE7606B002808D031462046229AFFF7AC
+:1006C000E3FB18A90872002869D12B463A46304648
+:1006D000229900F056FB039061E02298022E4078A8
+:1006E00001907DD1002801D0012879D108206946E8
+:1006F00008740198087521A800901B9800220178C1
+:100700002046019BFFF7B0FC6946002248758A75B8
+:10071000002802D10198012809D0208F002806D096
+:10072000002008740120800220A988810EE004A81E
+:100730003399F2F774FF0390002069460874012092
+:10074000800220A988810398022807D0BB4800684E
+:100750008079002805D018A908722BE00198208321
+:100760001DE00398002803D0812018A9087240E0FA
+:1007700021A800901B98012201782046019BFFF7D9
+:1007800073FC18A9087220463499FFF753FC18A986
+:10079000087A002803D11920287001203880684683
+:1007A000007C00E03CE0002804D004A83399F2F774
+:1007B00036FF0390039800282ED01AE0062012E599
+:1007C0002078000713D5012E11D109216846017444
+:1007D000A188818204203499FCF771FE082100E091
+:1007E00005E020A88181CDE60198400612D50320BE
+:1007F000039020A9208889890843208020A988891E
+:100800004005400E04D026992B98086026988680D3
+:100810000398AAE40420E6E418A8007A00280ED081
+:100820000120287022980078687020A88088A8701D
+:10083000000AE87018A8007A28710520388020A9DD
+:100840002088898988432080E2E7FFB50746A1B068
+:1008500000201C903A7801209040794A7C68104032
+:1008600010AA1087744B22885B1C9A4203D0002880
+:1008700004D0100702D5012025B0F0BD249E002031
+:10088000307023980025028810A8028518A80575E5
+:100890006A4B68461972057404A8186020462C300B
+:1008A0001B902A985860249E94463878721C052123
+:1008B000039201282DD0022808D003287DD130785A
+:1008C000800980011D303070B889A08038780228F6
+:1008D00004D13078800980011B303070F01C1FAAD1
+:1008E00001900292009110A8008D0022C01E83B2D8
+:1008F0002020015DB889F5F701FF0028DED10398BB
+:10090000B9890170090A417010A9888FC01C088537
+:1009100028E1787B18AA10753A7B012A02D0022AB6
+:10092000CCD1FCE022887F231B011A4010AB1A8730
+:10093000802A4AD006DC102A10D0202A0ED0402A65
+:100940000AD124E0FF3A013A65D0FF3A013A79D062
+:10095000FF3AFF3A022A76D00525A2E02078C006A9
+:1009600001D5082000E010201C9004206A46107475
+:10097000002090821AA81DAA1EAB03960192029035
+:1009800000933B8A20461C9AFFF79AF984E0228B59
+:100990003B8A9646934268D10A221C92002839D19C
+:1009A000039801906046401E1FAA83B20292202045
+:1009B0000091015D0022704600E0BAE0F5F79EFE6E
+:1009C000014618A801750B201AE0228B3B8A964637
+:1009D00093424AD10C221C92002862D103980190C4
+:1009E00060461FAA401E0292009183B22020015D42
+:1009F000628C7046F5F782FE014618A801750D203D
+:100A0000307010A8818F491C01850421684601744B
+:100A1000218B818245E0238B3A8A9C469A4224D1DD
+:100A200012221C9200283CD1606A002813D00022B8
+:100A30006B4607C3638C07E0FEFF0000B40E002086
+:100A400009F800000DE04BE02020015D6046F5F75D
+:100A500071FC18A9087513203070012010A90885B1
+:100A60001FE0398A228B914201D00425B6E016217D
+:100A70001C91002815D11B98818802682046FFF739
+:100A800003FA18A9087500280BD11B983346016892
+:100A900080881AAA00F075F9054602281BD0042D9B
+:100AA00019D01B988088002811D06846007C002847
+:100AB00004D004A82A99F2F7B2FD05460120694640
+:100AC00008741B981B990068059000208880002DF1
+:100AD00048D0052D2ED06846007C032878D07DE0D4
+:100AE00018211C91002806D0388A20832046B96836
+:100AF000FFF7A0FAD5E72046183000902020015DCE
+:100B0000237E01222046FFF7AFFA18A908750028B6
+:100B1000ECD119203070012010A90885E6E7208863
+:100B200001214902084010A90887FF38FF38022830
+:100B300006D0052510A92088098F884320804DE024
+:100B4000208F9849884290D116201C90386900283F
+:100B500005D06063B88A20870020608702E000200B
+:100B6000C043208710A8008F7F21090102468A43D5
+:100B70000DD0782300220420B968FCF7FBFB3878FD
+:100B8000A07010A92088098F0843208002E02188E6
+:100B9000814321806846007C002805D08248416856
+:100BA00004A8F2F73CFD054618A8007D002815D0E2
+:100BB0001C98707001203070208BB070000AF070AB
+:100BC00018A8007D3071052110A8018506E0FFE717
+:100BD0007548416804A8F2F722FD05467248017A7B
+:100BE00020884005400E22D11B98808800281ED006
+:100BF000239A0026138810AA1385249A2A9B6F46ED
+:100C00004CC71B9A039412681AABFFF78DFA05467E
+:100C100002280CD00120694608741B982A990068A4
+:100C2000059004A8F2F7FBFC05461B98868010A8E7
+:100C3000018D2398018028461EE600B597B0042850
+:100C400007D102206A461070019100216846F2F730
+:100C5000E6FC17B000BD10B5534C037800222168A4
+:100C6000012B02D0022B42D126E00B78002B01D0C1
+:100C7000042B03D10A712268032111702168838833
+:100C80000A79D200921D8B5221680A79D20008326B
+:100C90008918C2880A80216803890A79D2000A3239
+:100CA0008B52428920680179C9000C314252216877
+:100CB0000879401C08711EE00A7482888A802168C5
+:100CC000C288CA80226801891181226841895181C4
+:100CD000C1682068C1606168F2F7A1FC0146022882
+:100CE00007D02068007C002802D1002903D0812091
+:100CF00010BD832010BD002010BD406B002800D027
+:100D0000012070478178012909D100880521C90295
+:100D1000884202D0491C884201D10020704705203A
+:100D20007047F7B586B00024684615460F468481A3
+:100D300005261AE0049841780278090211432980B7
+:100D4000811D019602940091417902790B021343AF
+:100D5000C178827809020A43417800780902084381
+:100D60003946F5F7E7FA002806D104AA03A9069840
+:100D7000FFF7BFF80028DDD0822800D1002009B09D
+:100D8000F0BD10B51488844201D2052010BD17248F
+:100D90001C701080421E581C491C05F0C6F900202A
+:100DA00010BD0000FEFF0000B40E002010B540484A
+:100DB00004F04DF9002801D00C2010BDFF211131A5
+:100DC0003C4805F011FA3B4901200870002048809A
+:100DD000E03188718874887520310871344804F0D6
+:100DE0004EF9002010BD10B5314804F028F9002854
+:100DF00003D031A1312005F016FBFFF7D7FF002803
+:100E000003D02DA1382005F00EFB10BD10B504460F
+:100E1000274804F01CF9002801D00C2010BD2549FA
+:100E20000878002807D0002008702148216004F0CD
+:100E300026F9002010BD1E4804F021F91F2010BD26
+:100E400070B505460C461A4804F001F9002801D097
+:100E50000C2070BD174A5088A84202D11078002893
+:100E600004D0134804F00BF9122070BD1048226022
+:100E700004F005F9002070BD10B504460C4804F0DC
+:100E8000E6F8002801D00C2010BD0A48017800299E
+:100E900007D00020C0432080054804F0F0F812205D
+:100EA00010BD40882080024804F0E9F8002010BD01
+:100EB0009D000020C00E00207372635C6C6C5F6448
+:100EC000622E630010B5282105F08CF910BD70B5B5
+:100ED000054600780A0700090001120F1043287028
+:100EE0000B0005F091FB07050705070509050B0039
+:100EF000062408E00C2406E0222404E00024F2A1E9
+:100F0000572005F090FA68788009800120436870C6
+:100F100070BD00780007000F704710B50622C01C96
+:100F200005F003F910BD10B50622093005F0FDF8F3
+:100F300010BD0278BF23C9071A40490E0A43027048
+:100F4000704702785206520EC9010A430270704778
+:100F500070B515460E4604461F2A03D9DAA1A8200B
+:100F600005F061FA20462A463146093005F0DDF8E1
+:100F70006078AD1D80098001A906890E0843607064
+:100F800070BD70B515460E4604461F2A03D9CEA182
+:100F9000CC2005F048FA20462A463146093005F0B3
+:100FA000C4F86078AD1D80098001A906890E084348
+:100FB000607070BD70B501780907090F03292ED044
+:100FC000052931D1411C827E0C46437E1102194312
+:100FD000037FC27D1D02037EC67E1B021343827DFA
+:100FE000407835438006800E22281DD106291BD368
+:100FF0001920C001814217D8FF26F436B54213D814
+:10100000002A11D0082A0FD88A420DD28B420BD861
+:10101000617F227F09021143814207D904E04078B1
+:101020008006800E0C2801D0002070BD012070BD0C
+:1010300000210A464254491C2229FBDB704710B5A7
+:1010400002788B07920892009B0F1A430270427835
+:10105000520952014270012908D0022906D0032901
+:1010600005D0FF2098A1EE3005F0DDF910BD01217B
+:101070000A43427010BD10B502788B0792089200A7
+:101080009B0F1A43027042785209520142700129A3
+:1010900007D0022905D0032904D08BA18E4805F082
+:1010A000C2F910BD01210A43427010BD00788007CB
+:1010B000800F70470278EF23C9071A40C90E0A4310
+:1010C0000270704770B50546C1700B0005F09CFAC0
+:1010D0000E080A0C0E1012120C14141212160C1810
+:1010E0000C2413E0082411E002240FE017240DE083
+:1010F0000D240BE0012409E0092407E0062405E0A3
+:101100007548002470A1A03005F08DF96878400979
+:1011100040012043687070BDC0787047017AC27981
+:10112000080210437047817A427A080210437047E0
+:10113000017BC27A08021043704781794279080224
+:101140001043704700797047817B427B080210434F
+:10115000704770B5017AC37909021943431C857A37
+:101160001C46467A2B023343657926792C02344398
+:10117000C21C5A4E00798D1FB54214D8FF25F43594
+:10118000AB4210D800280ED008280CD888420AD2CA
+:101190008C4208D8507A117A00020843B11D884267
+:1011A00001D8012070BD002070BD0B4610B5011D97
+:1011B0000522184604F0B9FF10BD817A427A080270
+:1011C0001043704701717047007970470B4610B5A6
+:1011D000011D0822184604F0A8FF10BD027B0A700A
+:1011E000407B487070470B46014610B508220E310F
+:1011F000184604F09AFF10BD0B46014610B50422B4
+:101200001631184604F091FF10BD10B50822001DDC
+:1012100004F08BFF10BD10B504220C3004F085FFE4
+:1012200010BD017170474171090A81717047C17128
+:10123000090A017270470079704781794279080282
+:1012400010437047017AC279080210437047017158
+:101250007047017170470B4610B5011D08221846F2
+:1012600004F063FF10BD10B50822001D04F05DFFFF
+:1012700010BD70B515460E4604461B2A03D912A1AF
+:10128000174805F0D0F82A463146E01C04F04DFF1F
+:101290006078E90640094001C90E0843607070BDDE
+:1012A00070B5054640780E46C406E40E1B2C04D9E2
+:1012B0000B4805A10C3005F0B6F82246E91C304673
+:1012C00004F033FF204670BD7372635C756C5F7011
+:1012D00064752E6300000000070200007A0C000015
+:1012E000F7030000C1074008C207C90FD20F511809
+:1012F0004008C207D20F51184008C207D20F511838
+:101300004008C207D20F51184208D007C00F40183A
+:101310005208D107C90F0918500840187047002219
+:1013200002808271C271C2720273427382738270D0
+:10133000C270027142714276828303464284203336
+:101340009A7102859A72C2750276C2730274DA7259
+:101350001A739A7319750284FF21603081709A752F
+:10136000704770B504460020A083208C1E46484379
+:101370001546114604F061FF2084F000294604F070
+:101380004EFF401C80B20146192269439202E0835D
+:10139000914201DD401EE0837D202946000204F0D9
+:1013A0003EFF401CA08470BD70B50546087B0E460C
+:1013B000C006C00E08730020A87504463019007AD4
+:1013C000FFF790FF29194874A97D641C0818E4B23E
+:1013D000A875052CF2D3C0B2252803D979A18A209B
+:1013E00005F021F870BDF8B5044630302646274692
+:1013F0002546C036A03780350090032909D0002942
+:101400001AD0012924D0022902D1A11CFFF7CCFF58
+:10141000F8BD1146FFF783FF002028836883A88367
+:10142000E883288468847871E88538732621085514
+:10143000A08430703071F8BD0020E885B871A188B3
+:1014400023890A460098FFF78CFFA11C0098DDE76E
+:101450000020E885B38A328AA1880098FFF781FFCF
+:10146000F8BD70B5867D0D460446002E01D0252EB0
+:1014700001D9122070BD002A18D0287EE17D50438A
+:101480000818252104F0CBFE0846E1754207520FEB
+:10149000C908504B69189A5C097A8A4368D031466A
+:1014A00004F0BDFE491CCAB2002007E0002070BD58
+:1014B000002803D02118097C511ACAB22118497C8E
+:1014C00091423AD32918097AC943CB07DB17D21ABC
+:1014D000521E1206120E35D08B07DB17D21A521E7F
+:1014E0001206120E30D04B07DB17D21A521E12060C
+:1014F000120E2CD00B07DB17D21A521E1206120E38
+:1015000028D0CB06DB17D21A521E1206120E24D098
+:101510008B06DB17D21A521E1206120E20D04B0673
+:10152000DB17D21A521E1206120E1CD00906C9175A
+:10153000511A491E0A06120E18D0401C0528B7DBA6
+:101540001F2070BDC00013E0C000401C10E0C000B0
+:10155000801C0DE0C000C01C0AE0C000001D07E0B8
+:10156000C000401D04E0C000801D01E0C000C01D9F
+:1015700020769BE738B505460C466846FEF738F8F6
+:1015800000281ED0694600200856207209216156A5
+:101590000022411A00D5494220356B798B420FDC7D
+:1015A000FF2B0DD0A17A491CC9B2A172AB79994227
+:1015B00002D8617A7F2903D160720020A0720122D3
+:1015C000104638BD7372635C6C6C5F7574696C2E09
+:1015D000630000007667010010B5040004D0FF200E
+:1015E000FAA1AB3004F01FFFFB4821464143FB4802
+:1015F000FF230918FF330022581C5A544254C81DB7
+:10160000FF30FA3002704270F448001FC378A342E2
+:1016100002D18270FF23C370EF48EF4BC01E081841
+:101620009B1EC91802700A7010BD70B5EB480026E9
+:10163000001F8670FF24C47035462846FFF7CCFF94
+:101640006D1C2D062D0EF8D00020E4490B229201CE
+:10165000E14B43435B189B181E74401C0006000EB0
+:10166000F6D0DF48FFF7E4FC0021DD48FFF722FD5C
+:101670000121DB48FFF7E3FCDA4804704470847012
+:10168000C4700471447170BDCFE71B20704730B542
+:101690000021D24A0B239B01CF4C4C43A418E418E1
+:1016A000247C002C05D0491C0906090EF4D000202A
+:1016B00030BDC94C01254C43A218D21815740170D5
+:1016C000284630BD10B5044600F0D0F900280CD0F3
+:1016D0002046FFF781FFC0490B224C43BF49002041
+:1016E0006118920189180874012010BD10B50446D4
+:1016F00000F0BCF9002802D0BA484471012010BDA6
+:10170000034610B5B748B44940794843B349421835
+:101710001046FF30E130C17F807F04F0D5FF10BD5F
+:1017200010B5B048AC4940790F224843AB49401846
+:10173000A949D239095CFF30FF3004F09FFF10BD8A
+:1017400010B5044600F092F9002802D0A5480471B3
+:10175000012010BD034610B5A2489F4900794843B7
+:101760009E4942181046FF30E130C17F807F04F06F
+:1017700098FF10BD70B59B4C97492079974D484311
+:101780004019C11DFF31F931FF30E130807F0F2258
+:1017900004F064FF002813D020798F494843401992
+:1017A000FF30FF3002300178491C01700178407829
+:1017B000814204D1884885A1773804F034FE0120A5
+:1017C00070BD884884490079484384494018FF30F7
+:1017D000E130C17F807F814201D10120704700202C
+:1017E000704770B57F487C49007948437B49401871
+:1017F000FF30E130867FC57F0F242946304604F054
+:1018000026FF002801D0204670BD70066906400EF4
+:10181000490E884201D3401A01E0081A201AC0B2CA
+:1018200070BD0F20704770B50C46054600F01EF9DC
+:1018300000280ED0002020706748454367482818CC
+:10184000FF30FF300230017842788A1A22704170EE
+:10185000012070BD70B50C46054600F007F9002860
+:101860000BD05D4845435D482818FF30FF300230FB
+:1018700001784078081A2070012070BD5849016035
+:10188000704710B5044600F0F1F8002802D0554822
+:101890000470012010BD5149091FCA78FF2A02D0E7
+:1018A0000021016007E08A784C492439012A02D0DE
+:1018B000016001207047002070474848801E017871
+:1018C000012908D001210170464801784348001FD2
+:1018D000C170012070470020704710B5044600F029
+:1018E000C5F8002802D03F484470012010BD3B4994
+:1018F0003C4B091FCA785B789A4206D18A78203916
+:10190000002A02D001600120704700207047334850
+:10191000344A001FC1785278914209D1FF21C17029
+:10192000801C0178002903D000210170012070473C
+:101930000020704729482B4A001FC17852789142F5
+:1019400004D18078002801D0002070470120704722
+:1019500010B5044600F08AF8002802D02148C4706F
+:10196000012010BD034610B51E481B49C0784843EE
+:101970001A494018C21DFF320B21FC328901401860
+:10198000C17B807B04F0A0FE10BD10B51548124944
+:10199000C0784843114940180B2189014118C97B7F
+:1019A0000D4AD21E8018062204F068FE10BD0D48B4
+:1019B0000949C0784843094941180B20800108189B
+:1019C000C17B807B81420FD1012070477372635CC1
+:1019D000646D5F712E630000D1020000F40F0020DF
+:1019E000C51200209E0000200020EEE710B504463E
+:1019F00000F03CF8002802D021488470012010BD7E
+:101A0000034610B51E481F49807848431E494018B8
+:101A1000C21DFF320B21FC3289014018C17B807B43
+:101A200004F03FFE10BD10B51548164980780B2212
+:101A300048431549920140181249891E41188018DF
+:101A4000807B062204F00AFE10BD0D480D49807807
+:101A500048430D4941180B2080010818C17B807B49
+:101A6000814201D10120B0E70020AEE7002805D176
+:101A70000648007C002801D00120A6E70020A4E74A
+:101A80009E000020D1020000F40F0020B4120020BC
+:101A9000F8B5FF4E0446B079002500280AD0002989
+:101AA0002DD1657010202070F079A070307AE07030
+:101AB000B57124E0F64F203F387A012804D0707ABF
+:101AC000012810D00020F8BD002918D1657013201E
+:101AD000EF4920701C221639A01C04F026FB0120BF
+:101AE000A0713D720BE0002909D165701420E8490E
+:101AF000207008220A31A01C04F017FB7572012027
+:101B0000F8BDF8B5E3480178002902D00C2630462C
+:101B1000F8BD0026DE4D3446403D2E756E75EE75DF
+:101B20002E76AE75294620396E730F464E734037B8
+:101B30007E717F218170687E002804D0FDF73DFD15
+:101B4000FEF766F86C763C72D14884711430FFF76A
+:101B5000B9F9CF483C30FFF7B5F9D8E710B5CD4B10
+:101B600000221A70CA4B203B1A711A46603A11665D
+:101B7000D065FFF7C6FF002804D0FF20C6A187303C
+:101B800004F051FC10BDC2484038007D7047C04988
+:101B900010B54039C87B897B42078307D20FDB0F22
+:101BA000D218C007C00F101840000B0004F02CFD25
+:101BB000050B060B04080F00BB4906E0BB4810BD2F
+:101BC000B949083101E0B8490839085A10BDFF2069
+:101BD000B1A1A73004F027FC002010BDAC48B449E7
+:101BE0004038008A48437047F8B5A94C0646407B08
+:101BF000403CE07337791346A773012F26D0308815
+:101C00002082A348B27B203882710546603D29704E
+:101C100006221946681C04F088FAB0796873062217
+:101C2000F11DE81D04F081FA607B0126002800D038
+:101C3000667597486038407B002800D0A6753B0049
+:101C400004F0E2FC0506082549084B000020D7E710
+:101C500000211DE08E4801211430FFF738F98C482F
+:101C6000E91D1430FFF75FF9687B002807D00128D1
+:101C700007D0FF2088A1EE3004F0D5FB0CE0002156
+:101C800000E0012182481430FFF75BF904E00621EF
+:101C90007F481430FFF71BF90020E07520767C4860
+:101CA000691C1430FFF739F9794829781430FFF7A7
+:101CB00040F9774804213C30FFF709F97448691C62
+:101CC0003C30FFF72AF9724829783C30FFF731F9A8
+:101CD00026750020F8BD0221DAE7FF206EA1F8305A
+:101CE000CAE770B56A4C0125403C0346257620467C
+:101CF0002030007A002801D03A2070BD64480022CC
+:101D0000803806789E4206D1E2750622401C04F017
+:101D10000CFAE57500E02276002070BD70B504462F
+:101D20005B4D0020403DA87528462246323804F01D
+:101D3000FCF92846203844730120A87570BD544929
+:101D400020390871704710B5514C0022403C627533
+:101D5000607302462046123804F0E7F901206075EE
+:101D600010BD4B49203948717047F8B500F0A4FB0D
+:101D7000474C0025403C607E002804D0FDF71DFC48
+:101D8000FDF746FF6576434F3D70FDF793FBA07B63
+:101D9000012804D00021084601F0A6FAF8BD002170
+:101DA000022001F0A1FA3A4C203C207A002809D008
+:101DB000374881790029F1D11321C17105720121C0
+:101DC0008171F8BD78780028FBD0314E0622803E24
+:101DD000707BE0733078A0753046F11D703004F0F0
+:101DE000A4F930460622711C773004F09EF93C209D
+:101DF000A072012020727D70F8BD10B5244C403CCB
+:101E0000E17BA07CCA0701D0C2070BD08A070FD59F
+:101E100082070DD42620FDF777FAA07C0221084323
+:101E2000A07410BD2520FDF76FFAA07C0121F6E714
+:101E30004907F6D54007F4D42720FDF765FAA07CC2
+:101E40000421ECE770B5134E3078002872D1104CA5
+:101E5000403C207D00286DD0FDF71FFB0025A574B8
+:101E6000E57475702846FDF715FB0020FDF78CF929
+:101E70000D480D38FDF73FFA0B481038FDF7F7FA1B
+:101E8000FDF76CFBFFF7B9FFFDF7FFFA012111E049
+:101E900068130020A40000207372635C6C6C5F61A7
+:101EA00064762E63000000008E6701009A8913009B
+:101EB000710200000020FDF743FA0F210520FDF715
+:101EC000C1F92646403E3178701CFDF7ADF9A07B84
+:101ED00001280CD004280AD0607D002807D02146B4
+:101EE00012390846627B6630FFF732F86575A07DCF
+:101EF000002807D0FE480146427B12399C30FFF78C
+:101F000040F8A575306E0178002903D00178001DD6
+:101F1000FDF7C8F9F06D0178002906D0F44A401C9D
+:101F2000C732FDF754FE01206076FDF7C3FA0020AA
+:101F300070BDFFE70C20FBE7EE494860704770B5C5
+:101F4000050001D0FFF759FFE94C2034E07C002860
+:101F50000AD0A07B012804D19920E749C00004F0F1
+:101F600062FAFFF702FFE3E7002D0DD00221002007
+:101F7000FDF7E6F9DE4840300079032801D001285A
+:101F800002D10220FDF73BFCE07D002600280DD0A9
+:101F9000D74D203D2846691C9430FEF7BEFF2846E9
+:101FA000691CBC30FEF7B9FFE6752676D048743060
+:101FB000FDF786FAA07B030004F026FB0504040469
+:101FC0000D04090001210846FDF79FFB03E0CA4903
+:101FD000CA4804F028FAE17BA07C81430120002953
+:101FE00003D1A17B012903D0E074C24908709FE7A7
+:101FF000A674FAE710B5FDF750FABE48007800283D
+:1020000018D1BB482030007D002813D00020FFF7F6
+:1020100096FFB74840300079002809D001280FD03A
+:10202000022805D003280BD0B349B54804F0FBF9CA
+:10203000002010BD00F040FAFDF73CFA0C2010BD66
+:10204000F0F7E6FFF4E7AB49012048707047F8B5B8
+:10205000002400F0E0FF002824D0FF202D30FDF701
+:102060006CF9A44D2878A24F403701281DD00228D2
+:1020700001D0032834D0A2489F496B3004F0D3F933
+:10208000287800280DD0387900280AD0012808D0F7
+:10209000022838D0032836D099489749803004F078
+:1020A000C2F9F8BDFFF761FEF8BD914E2036B07B56
+:1020B000032815D0707E002803D0FDF798FDFDF7AA
+:1020C00074FA8B48C430FDF7FBF9B07B012812D0BD
+:1020D000042810D0B879012806D0032804D004E0E1
+:1020E0000120FFF72CFFCBE7102421460E200143EF
+:1020F0000020FDF70AFB7879012801D1FDF76FFA7E
+:1021000002202870BCE728780228CDD10120FDF7F5
+:1021100076FBF8BD70B5764840304079012801D192
+:1021200000F0D4F9724C2034607E002803D0FDF713
+:1021300044FAFDF76DFD00F06EFF00280CD06D4DE8
+:102140002878022804D06E486B49A33004F06BF95C
+:10215000A07B012803D006E0FFF707FEE8E6992000
+:102160008000FDF7EAF80120FFF7E9FE2878002853
+:10217000F4D028780128F1D039205F49000104F01B
+:1021800052F9D5E6F0B5074689B000200690FDF774
+:10219000AEF800900020019056480078022804D044
+:1021A00057485549F03004F03EF9514D40356879B3
+:1021B000012801D100F08AF94D48C430FEF7A9FE8C
+:1021C0004B4E04462036002F70D03046A430FEF728
+:1021D000F1FE0028F8D0FDF731F80028F4D0707E29
+:1021E00000280AD005277F1EFFB2FDF72CFD02282C
+:1021F0000FD0012800D0002001903D492046C43175
+:102200000C46643C030004F0FFF906A4A4A40CA44B
+:1022100056A4002FE7D177203AA1C00004F003F9BB
+:10222000E9E7B07B012841D004283FD0019A00980B
+:10223000104304D1A879002801D0022836D168794A
+:1022400001281DD1607A00281AD101206072087817
+:1022500006224006C00FA0722548C91C6B3003F04F
+:1022600064FF244C224FA07871377F2804D1A92025
+:1022700024A1C00004F0D7F8A07838707F20A070A7
+:102280001B489C30FDF71CF91A480321017028797E
+:10229000002860D001280AD002285CD0032806D08C
+:1022A000164818A1E03804F0BEF854E051E00120CF
+:1022B000FDF7A5FA4FE00E480F462038C978C079DF
+:1022C000814230D10A4839792038027A91422AD1A4
+:1022D0007979427A914226D1B979827A914222D192
+:1022E000F979C27A91421ED1397A027B914211E08A
+:1022F00008130020A4000020981E0100F60400002E
+:10230000DE0200007372635C6C6C5F6164762E6346
+:102310000000000007D13978407B4906C90F81428F
+:1023200001D1012100E00021B07B012801D0042867
+:1023300001D100290AD100280BD101990098084346
+:1023400004D1A879002801D0012802D1307E0028CC
+:102350001FD001200690707E002803D0FDF72DF9D4
+:10236000FDF756FC0698002802D00120FFF7E7FD94
+:102370005D48017800290AD00178012907D000784A
+:10238000032804D095205949C00004F04CF809B046
+:10239000F0BD55480422406855490F3003F0C5FE92
+:1023A000387806224006C10F4F4840680177F91C73
+:1023B0001D3003F0BAFE4C484D4940680322091D08
+:1023C000133003F0B2FE4848494A4068B97D817530
+:1023D0000F3A117ED37D09021943018311468B7E8A
+:1023E0004F7E1B023B438380137FD77E1A023A4302
+:1023F000C2808A7F4B7F1102194301813C4905222B
+:1024000010310A3003F091FE3948374A1130017912
+:102410005768C906C90EB97600794009F876287A56
+:10242000002809D0A07900283AD11320E0710020BB
+:1024300020720120A07133E00020A8727888B08556
+:10244000387FE8732A48394606221D31833803F065
+:102450006CFE27490622F3390878A87508467730BC
+:10246000491C03F062FEB888F087F888208038891C
+:102470006080F87E20710198002860790BD00121DE
+:1024800008436071FDF7F2FB61794000C907C90F8D
+:102490000143617102E04008400060710120287230
+:1024A000114C0020207000F007F8FDF703F8012020
+:1024B000616800F019FF4EE710B5FDF76AF8FDF707
+:1024C0005DF8FCF7B5FFFCF7DAFF10BD064810B564
+:1024D000801CFDF78DF8002802D103497F20887009
+:1024E000FDF774F810BD0000A400002004230100D3
+:1024F000DB1300208107C90E002808DA0007000F4F
+:1025000008388008F74A80008018C06904E0800815
+:10251000F54A800080180068C8400006800F7047A8
+:1025200010B500F03BFF10BD70B5F04C0546626879
+:10253000002908D0002A04D0FF20EDA10C3003F0C0
+:1025400072FF656070BD002A04D1FF20E8A112303F
+:1025500003F069FF0020606070BDE948C07E7047ED
+:10256000E7482830C07E704738B5E04C20680168E5
+:102570004978012925D001216846FAF7C9FC684647
+:102580000078E049000203F04AFE2068426AC06811
+:1025900012685118FBF7ADFC2168C860D84A206862
+:1025A00028320321904218D0028B002A15D0012234
+:1025B0004272017200210171021D017F00F0FBFED9
+:1025C00038BD7D21C068C900FBF793FC2168C86055
+:1025D000FFF7DDFA21680861E0E7028B521C0283F5
+:1025E0004172E6E7FFB5C64E85B0706A346805688B
+:1025F00060680190306A0390298E0798401A80B273
+:1026000002900898002804D02746383720464830E2
+:1026100002E0371D2846A830009003203871059845
+:10262000002820D001287DD002285ED003287AD04F
+:10263000AFA1B54803F0F7FE0898002807D0387915
+:10264000032804D0B048AAA1093003F0ECFEA16A27
+:102650007069FBF74EFCB860616A206A88427DD9D8
+:10266000009801601FE1306A002804D1A648A0A1AB
+:102670007A3803F0D8FEA449288B373948434018EC
+:10268000069900F0A6FEA0619F49A8883739484303
+:10269000069900F09EFEE061316A9B48891CA162A8
+:1026A0002A8B37384243A069974B121AE63BD2185F
+:1026B0005118A162944BAA7D373B5A4340008018C1
+:1026C000FF30193020626062306A081AED21FF384D
+:1026D000C90015388842AFD28C49884204D28A4852
+:1026E00083A15D3803F09FFEB6E0874A288B373A16
+:1026F000E16850430818069900F06BFEA06182491A
+:10270000A88837394843069900F063FEE061306AD3
+:10271000002804D17C4876A1553803F084FEAE2011
+:10272000405B01E02CE05AE00028288B784AE16801
+:102730001DD050430818A169401AA0622169A06801
+:10274000734A4843A1694018A97D4000514340188D
+:10275000FF3017302062A888504300E0A1E0E16913
+:10276000411A6F20C000081A6062A06A34E050432A
+:102770000818A169401A3168D63849684018DCE762
+:10278000284680300190C08D002802D0306A002891
+:1027900004D15F4856A1401F03F045FEA8885C495C
+:1027A000E3694843C01AA06201999C46CA8D216919
+:1027B000A368521A4B43A169591863465343C91879
+:1027C000AA7D534B49005A438918FF3117312162C2
+:1027D0006F21C900411A6162316A401A35E00898D8
+:1027E000002803D03420005D002878D1A88848490B
+:1027F0004843E169401A02994843A0622846803064
+:102800000490C08D0028019829D0002804D03E48AB
+:1028100037A1163803F007FE04983D4AC18D02988F
+:102820000818E16948434000FF3017302062A8884B
+:102830005043411A6F20C000081A606200F0AEFDDC
+:1028400000281CD0A16A0398081AED21FF38C9009E
+:102850005538884200D3EFE601203871ECE60028B5
+:1028600002D00398002804D1294821A11A3003F08E
+:10287000DAFD0198A16AD6380818A062CCE7FBF708
+:102880009EF8726901461046FCF7BFFAA16A081A61
+:10289000ED21FF38C90050388842DCD2012009B050
+:1028A000F0BD0099086000981A4900688035081842
+:1028B000F860298B0798081A00B2002804DD0598F3
+:1028C000022801D0032000E00120787108983870B8
+:1028D0000898002820D03420005D00281CD0022059
+:1028E000DDE7000000ED00E000E400E0B4000020BF
+:1028F0007372635C6C6C5F6C6D2E73302E630000C2
+:10290000F413002010270000190500002902000020
+:10291000E20400004B1700000898012148402034D1
+:102920006075317F3A46304600F045FD0020B6E73D
+:1029300010B5FE4900280A68516A096807D0126874
+:102940008988FB4BD2695943891A03F068FC10BD92
+:10295000F8B5F64F38680468416A26460D68203697
+:10296000717D00290AD0618E2A8E914206D1407A6B
+:10297000012803D1EF49F04803F055FDFBF71FF89C
+:10298000014638684069FCF740FAFFF7D1FF2A8E0C
+:10299000618E1318994202DB491C618602E0401CDB
+:1029A00010186086B07D002806D19C21608E495B9E
+:1029B000884201D1401C6086DC480168088B0328EE
+:1029C00002D2401C088302E0618E982041532846C1
+:1029D00040300646C1898089081A298E401E401859
+:1029E00087B218E0D148EB7E00685B00406A00794E
+:1029F0004100D248415AC05A401881B2207D00237C
+:102A0000FFF7F0FD00280FD001280ED0CA48C949B1
+:102A10003A3003F008FD628EB81A00B20028E1DAFD
+:102A20000820B07200F010FEF8BD608E401C608679
+:102A3000F1E770B5BD4D002168680162C27E1300E8
+:102A400003F0E2FD045656034A56426A14680268CF
+:102A500011700268516000682030407D002808D164
+:102A6000FAF7ADFF69680968096CFCF7CEF9002830
+:102A700018DC6868228E0168498E914206D1214691
+:102A800080318B8B9A1ACA83238605E0891A9E228D
+:102A900011530168498E21860268C1681164C168BA
+:102AA000416111E068680168098E228E8B1A224606
+:102AB0008032D3830168098E218601680B6CC36064
+:102AC0000B6C4361886C9062204601F0D8FC0028B2
+:102AD0000DD098499A4808E0C1684161FFF7B2F902
+:102AE000002804D096489349801D03F09CFC70BDDB
+:102AF000934890490D30F8E710B58C4A0B001268E6
+:102B000003F082FD0906090F1F0C2E2E082B2E0044
+:102B1000FFF78FFF10BD00F068FC10BDFCF772FEE0
+:102B200010BDD07E022806D0D07E032806D0FF201C
+:102B30008049A3300EE0FFF70BFF10BDFFF714FD37
+:102B400010BDD07E0228F6D0D07E0328F6D0FF201C
+:102B50007849AE3003F067FCF0E7FAF715FF10BDD7
+:102B6000FF207449BC3003F05EFC10BDF3B581B0AA
+:102B70000E4601276D4D734C0B0003F045FD090611
+:102B80002F39392F40403939400001216D48FFF776
+:102B9000CBFC31460198FFF7AFFFE07E022826D13B
+:102BA00068680568406A0668FAF7E7FEB188604A17
+:102BB0005143EA69891AD639E962B72802D26248D4
+:102BC000081803E0081A6049B7314018E8625F4806
+:102BD000E96A814200D80846E86205E00198FFF7FB
+:102BE0008BFFE07E022802D1206820300775FEBDF1
+:102BF0002C600198FFF780FF00202860FEBDFF20B9
+:102C00004C495C3003F00FFCFEBD70B50C46064627
+:102C10000B0003F0F9FC09060D10100D1A1A101024
+:102C20001A00484801212830FFF77EFC2146304633
+:102C3000FFF762FF70BD43483C4D283028603046A6
+:102C4000FFF75AFF0020286070BDFF20394982300D
+:102C500003F0E9FB70BDF0B5344C0020216885B06D
+:102C600003258D76CA7E0746032A03D0C97E002934
+:102C700029D029E0087F002803D12E49344803F0E9
+:102C8000D2FB2068067F684605714571FAF797FE0A
+:102C90000290FF20F53003900121684601706946DB
+:102CA0003046FBF70CFB00E020BF2068007FFCF7FC
+:102CB00038F90028F8D02068007FFAF765FE206810
+:102CC000077700F072FB012021688F7605B0F0BD18
+:102CD00016490A68907600E020BF0A68D07E002876
+:102CE00003D0D07E937E9842F6D0D07E002803D0C9
+:102CF00000200021917670470120FAE770B5114954
+:102D00000024CA7E094D032A03D02831CA7E032A33
+:102D10002ED12960002827D0012821D00C48054950
+:102D2000973003F080FB0020296813E0B4000020F6
+:102D3000E2040000F0280100F70500009E67010092
+:102D4000A1030000F4130020C4F8FFFF38120000B4
+:102D500072020000086048622860002C08D070BD34
+:102D60000320FFF7B5FF01E0FFF775FF0446DAE740
+:102D70000C2070BDF8B5F94F04461F25E67E3300E0
+:102D800003F042FC042920031B20F548844204D0B0
+:102D9000FF20F449FC3003F046FB02203C60FFF7C3
+:102DA00097FF002805D03968002008604862386025
+:102DB00011E00C25002038600AE00120FFF79EFF9B
+:102DC000054603E0E749E84803F02DFB002D02D05B
+:102DD000E07EB042D2D1E07E002804D0E248E14952
+:102DE000801D03F020FBF8BD10B5DD48FFF7C2FFE2
+:102DF000DB482830FFF7BEFFD94900205031087565
+:102E0000D649C91F4870D64948610A4628325061E0
+:102E100088769076D1494860086010BD70B5044648
+:102E20000120FFF767FBC5B20B20FFF763FBC0B2C1
+:102E3000854204D0FF20CB49C63003F0F4FA0120CC
+:102E4000FFF758FBC5B21820FFF754FBC0B285420C
+:102E500004D0FF20C349C73003F0E5FA0420C04383
+:102E6000FFF748FBC5B21920FFF744FBC0B285420B
+:102E700004D0FF20BB49C83003F0D5FAB748B849A1
+:102E8000083804700020C87688760A462832D07642
+:102E90009076B24B012408331C711860486250626E
+:102EA00008601060FFF7A0FF70BDAC4908310871E1
+:102EB0007047FEB5AA49CA7E08462830A74C002AAA
+:102EC00002D1C27E002A03D0C97E022903D005E0C8
+:102ED000A648216006E0C17E002901D00C20FEBD7D
+:102EE0002060A348FAF7FCFC216808779B4920681A
+:102EF000C91F0160C91C4162007F002804D1AD20B8
+:102F00009849800003F08FFAFAF737FD9949884213
+:102F100000D20846FF30C83086B220680325C57647
+:102F2000FEF735FE21680861FEF758FE00270028ED
+:102F300027D0FEF753FE21684A6A10600968012015
+:102F4000087001466846F9F7E3FF684600788A4949
+:102F5000000203F064F90191FAF731FD019971184B
+:102F6000FAF7C7FF2168C8602068057245720771CB
+:102F7000021D017F00F01FFA2068078300202760F0
+:102F8000FEBDFAF71CFD3146FAF7B3FF2168C860B1
+:102F900008680770096801204870E5E77047F8B5D0
+:102FA0006F4EF17E002904D131462831C97E0029B7
+:102FB00001D00C20F8BD0221F176694C674F5034E6
+:102FC0000837776234600025386025753979C07E0E
+:102FD0004A006A4940008A5A085A2B46101881B2A2
+:102FE0002A462846FFF7FEFA002804D0CF205D4984
+:102FF000800003F018FA25610120A5602075658620
+:1030000025865748703085753968088E401E0886B9
+:1030100035830020F8BD10B5504801244068817EFA
+:1030200003290CD001684978002906D0006A544968
+:10303000884202D90024FFF706F8204610BD00247C
+:10304000FBE74648406802681178491C1170016A24
+:103050000068C26A914204D8007D012801D0012095
+:1030600070470020704700207047F8B53B4C3C4843
+:103070002060416A00680D68002634210E54A621A4
+:10308000495D00294BD1007D032848D1FAF797FC10
+:10309000014620684069FBF7B8FE00283FDDFFF7D6
+:1030A00047FC298E401C4118206802681186006880
+:1030B000018E9C22525B511A09B200292FDD012199
+:1030C0002030817528464030C1898089081A298EB0
+:1030D000401E401887B21BE0496A09794A00274917
+:1030E0008B5A028E007D9446EA7E5200895AC91896
+:1030F00089B201236246FFF775FA00280FD0012834
+:103100000FD002280BD01B481649193803F08BF951
+:1031100021680868028EBA1A12B2002ADCDA266028
+:10312000F8BD20680068018E491C0186F0E7F8B5FB
+:103130000A4D00266A680128516A0C6853D1087943
+:103140000E4940000B5A1068077D032F1AD0027DEC
+:10315000022A24D0007D012834D044E0B4000020AD
+:10316000F4130020F0280100070200006D2B01007D
+:103170000B2C0100F6050000102700009E670100DF
+:10318000D98213000661106886609C20025BE07E95
+:103190004000085AC01881B2002303201BE02246D9
+:1031A0008032D78D0761E07E928B4000085AC018AC
+:1031B00081B200230220FFF715FA6A680121126824
+:1031C00011750AE09C20025BE07E4000085AC0189E
+:1031D00081B200230120FFF705FA002803D09C49A3
+:1031E0009C4803F020F9FAF735FB9B480078EFF78D
+:1031F0006FF8686806830268218E51860068203067
+:103200008675F8BD38B5944C0021083460680D46C9
+:1032100000684278002A01D045701FE0007800283D
+:1032200009D001216846F9F773FE684600788B499A
+:10323000000202F0F4FF6068426AC0681268511828
+:10324000FAF757FE01466068C160057103214172BB
+:10325000021D017F00F0AFF860680583FAF7FAFA03
+:103260007D480078EFF734F838BD7B4A10B5014649
+:10327000083250680B0003F0C7F9060D1504081753
+:103280000C31012100F0D1F807E00021106800F0B6
+:10329000CCF810BD0120FFF74AFF00210846FFF7D8
+:1032A00043F910BD032116E0416A02680968D36939
+:1032B00093608A886A4B5A430368DA600A46C032D0
+:1032C000D3890B83137B8B75138A8B80538ACB80B6
+:1032D000928A0A8102210068017510BD5D485C492F
+:1032E000913003F0A0F810BD70B500280BD05A4CF7
+:1032F000083401280ED002281ED056485449B43054
+:1033000003F091F870BDFFF77DFF00210846FFF73D
+:103310000BF970BD6068002501684D7000F045F83C
+:103320000320F5F7B8FEFAF795FA4B486560007888
+:10333000EEF7CEFF656070BDFFF764FF606800F0D8
+:1033400034F800210846FFF7EFF80420F5F7A3FE54
+:1033500070BD414908314968CA7E022A08D10A680D
+:103360001378002B04D150600968CA6A1018C8622B
+:103370007047394A10B50832526800290CD001292B
+:1033800007D0022907D033483149D93003F04BF830
+:1033900010BD801E00E0401F106210BD2E48083096
+:1033A0004068002800D0012070470021C176817656
+:1033B00001604162704710B50B46C17E847EA14218
+:1033C00004D011461846FAF77AFF10BDFFF7EDFF5B
+:1033D00010BD024610B50020002905D00846504314
+:1033E000204902F01CFF401C10BD1B4810B50830DE
+:1033F0004068C07E030003F007F9041515030B15A0
+:1034000001F05EF900280CD00F2017A1800106E022
+:10341000FEF7F0FD002804D0F12013A1800003F096
+:1034200002F810BD10A11448F9E710B504460029B0
+:1034300003D00020FFF77BFE03E007480078EEF79B
+:1034400047FF2046FFF7B1FF0020F5F724FE10BD2F
+:10345000F028010092060000AC00002010270000B8
+:10346000E204000040420F007372635C6C6C5F6C9E
+:103470006D2E73302E630000CB030000F8B5FEF70D
+:10348000B0F90446FEF756FAF84E0546706920304A
+:10349000407D002809D0012827D002282AD00328FF
+:1034A00032D0FF20F2A19A3037E0F0481830FEF712
+:1034B0001EFA002801D003200FE0EC481830FEF778
+:1034C00049F9002804D070695B21095C002908D003
+:1034D000E6481830FEF7D2F90120716920314875AD
+:1034E0001DE002212030417519E0E0481830FEF758
+:1034F000C5F914E0DD481830FEF72CF900280ED18C
+:10350000FF20DBA18C3008E0D8481830FEF7EFF937
+:10351000002804D1FF20D6A1943002F084FFB069C6
+:10352000F72201781140017072692032937DDB0728
+:103530001B0F1943FB2319400170D37DDB075B0F81
+:1035400019430170577DEF23022F04D0012F07D0BC
+:10355000032F07D00CE0012C06D8002D04D007E083
+:103560006D1E2C43002C03D019401023194300E09A
+:1035700019400170D17F002916D0517D012913D047
+:10358000BF48FBF79DFFBE480021283001767269D5
+:10359000916ED26E42610161B949B269FCF7A3FA3A
+:1035A0000020FCF7AFFA03E0FBF78AFFFCF7CDFA47
+:1035B000B0690078C00606D4F0690078C00602D46D
+:1035C000F079002806D0B079002803D101210846FF
+:1035D000FCF79BF8032030703079002803D1FBF70B
+:1035E000BDFF01203071F8BD70B5A0481C30FEF75A
+:1035F000B9F901259D4C002802D00020607002E03E
+:1036000065709F48E061606940300078002802D012
+:103610006078002805D0E069FBF752FFFCF795FAC7
+:1036200070BD9748FBF74CFF9548283005766269D6
+:10363000116F526F42610161914AE169FCF753FADF
+:103640000120FCF75FFA70BD10B588490023486976
+:1036500002462030C3768377012049239854A03254
+:103660009279002A03D008700021022001E0002195
+:103670000320FFF7FAFD10BD70B57C4C6079C206DF
+:103680002046406901468031002A01DA002202E02A
+:10369000CA8DCB8BD218CA850246C0321379002B53
+:1036A00005D0034640331D8AC98B69181982617A97
+:1036B000002903D03D2001F051F94AE003462033B0
+:1036C000D97E042945D0217A002913D0480701D496
+:1036D000C80601D51E2030E0080701D53D202CE0AA
+:1036E000C80705D1880703D461A1664802F09BFE94
+:1036F0002A2022E04030817D002905D0418A4D1CDE
+:103700004582858AA9420FD2517A062902D0117AC0
+:10371000062905D1018B4A1C0283828A914203D279
+:10372000028AC1898A4201D3222006E09A7F8089D9
+:10373000002A0AD088420FD3082001F00FF96069EF
+:103740002030C07E042804D006E0062804D33E20A2
+:10375000F3E7FFF779FF70BD0120207000210846D4
+:10376000FFF783FD70BD10B5404840690146203128
+:103770008A7F002A29D0012A27D0022A06D0032ACC
+:1037800004D03BA1404802F04EFE10BDC97E032983
+:103790000FD0082919D001464031CA898989511AA8
+:1037A000891E89B2032900D303218030828B5118EE
+:1037B00009E0014640318A89032A06D3028EC9896D
+:1037C00080305118491C018310BD8030818BFAE78D
+:1037D00000B5030002F018FF0604070B0F121217C2
+:1037E00000290ED00FE0891E02290AD90BE0891F9B
+:1037F000012906D907E0082903D004E00B390C2978
+:1038000001D8012000BD002000BDFEB505461748C7
+:103810001830FEF740F8002804D11B4814A1D13815
+:1038200002F001FE114CA069FDF702FC0321A06922
+:10383000FDF721FCA069EF220178114001702946B3
+:10384000FDF740FC002601272B0002F0DDFE0E5C98
+:103850005C085C2C6060255C4C5C603C375C60699B
+:103860006521095C002911D0062111E0C400002067
+:103870007372635C6C6C5F736C6176652E630000C1
+:1038800090140020430200005C080000C030417921
+:10389000A069FDF797FC3AE060698030417CA0693F
+:1038A000FDF7D7FC33E06169A069B831FDF7ADFCE5
+:1038B0006169A0698C31FDF7AEFC28E00621A069A2
+:1038C000FDF7C5FC23E020690178A069FDF7A9FC9C
+:1038D00020698188A069FDF7A6FC20694188A0695C
+:1038E000FDF7A5FC13E00096019660696030007951
+:1038F000002803D069460878384308706946A069F3
+:10390000FDF7B1FC03E0F949F94802F08CFDFDF741
+:10391000D4FF002804D1F648F449801D02F083FD4D
+:103920000C2D06D0072D03D0606940304682877584
+:10393000FEBD606940300683FEBDF0B5ED4CC82089
+:1039400061698DB0405C04280AD0052835D15C201F
+:10395000405C00282AD0012060314871022026E016
+:1039600010226846D63101F030F86169102204A8AF
+:10397000B03101F02AF8684601F0DFFB08AE8DCEC9
+:10398000616984250E4678360DC66F5000250D6797
+:103990004D67012540267554D74D88318DC5284681
+:1039A0000822093002F0C1FB052000E00D20FFF7DE
+:1039B0002CFF61690020C03108720DB0F0BDF8B570
+:1039C000CC481830FDF767FF002848D0C94C207A52
+:1039D000002844D16069C421095C002500290ED06B
+:1039E0002030C17E0120FFF7F3FE002807D1606977
+:1039F0002030C17E0420FFF7EBFE002806D060696E
+:103A0000C921095C0126062907D00DE06069502113
+:103A10000D526030457102204EE02030C17E0420FE
+:103A2000FFF7D6FE002813D0616908462030C27E19
+:103A3000921E130002F0E8FD166262621D6262626D
+:103A400060621F6262622843626262626262466210
+:103A500060695E21095CC90702D0C0304572F8BDBB
+:103A60000C20FFF7D2FE60694030817F31438177BF
+:103A7000F8BD072020E0FDF79AFF0028F8D0606924
+:103A8000403005700B2017E0F9F741FA0C28EFD30E
+:103A900060690821B830F9F73BFA002806D0606960
+:103AA00004218C30F9F734FA002804D1C72093A1FF
+:103AB000C00002F0B8FC0420FFF7A7FEF8BDFFF736
+:103AC0003CFFF8BD00228A66CA66C6770A4678318E
+:103AD000C8C9894878322838D26842632830C8C0BB
+:103AE00008220D30091D02F020FB0620FFF78DFE95
+:103AF000606940308575F8BD0920DDE700F036FFCC
+:103B0000F8BD70B57B4C3B216069095C08292FD159
+:103B10000146028EC0314B89521C9A4228D1227A2A
+:103B2000002A25D10A8A83889A4207D14B8AC58800
+:103B3000AB4203D18B8A0589AB4209D043884B85C0
+:103B40008A854A8ACA858A8A0A860122E6210A5417
+:103B500001221146FDF747FC00210420FFF785FBF9
+:103B600060690021C92211542030C1760321817778
+:103B700070BD70B55F4C60692030C07E172803D0DF
+:103B80005EA1624802F04FFC616900220B4640339F
+:103B9000DA7608469A75E030867D0B240125002EE2
+:103BA00006D0837C002B14D1C4740275857410E098
+:103BB0001E7F002E07D01A774C88FA235C520276BB
+:103BC0000C23837505E04E88FA235E520276057752
+:103BD00084752031CA7670BD70B5464CA0798007D7
+:103BE00036D5207A002833D160692030C17E01208B
+:103BF000FFF7EEFD00282BD1A0690126C078002533
+:103C0000030002F001FD0E8585088537465F0A85B1
+:103C1000168526625285032152E060692030C07EFD
+:103C2000052804D0394835A1333802F0FCFB60691F
+:103C30000CE060692030C07E092804D033482FA1F1
+:103C40002D3802F0F0FB606956210D542030C57606
+:103C500070BD60692030C07E0B2804D02B4827A19E
+:103C6000263802F0E0FB60695B210E540C21203005
+:103C7000C17670BD60692030C07E0F2804D0234813
+:103C80001EA11F3802F0CFFB60695B210E5410218A
+:103C9000EDE760692030C07E102804D01B4817A1D2
+:103CA000183802F0C0FB12210AE060692030C07EA3
+:103CB000102804D0154811A1123802F0B4FB1421C9
+:103CC0006069D4E7FFF755FF70BD60690146C030F9
+:103CD000027A062A04D14031897F890700D505720E
+:103CE000417A0629F0D1457270BD0000703801009C
+:103CF000CD070000C4000020B81400207372635C7C
+:103D00006C6C5F736C6176652E6300004C0500007F
+:103D1000FD49FE4802F087FBE6E710B5FC4C606900
+:103D20002030C17E0020FFF753FD002803D1207A08
+:103D3000012108432072207A002808D1E069FDF7AC
+:103D4000EBF961699122505405202031C87610BDED
+:103D500010B5EF4C60690146C0314A7A002A06D09E
+:103D6000097A062903D0217A012211432172217A8E
+:103D7000002928D14030807F800715D4E069FDF705
+:103D80005AFA61694031C877E069FDF756FA61690E
+:103D900040310884E069FDF755FA6169022240313B
+:103DA0004884887F10438877606900220146C031CB
+:103DB0000B7A062B00D10A724030837FDB0702D1D9
+:103DC00006234B72028310BDF8B5D14C60692030D8
+:103DD000C17E0020FFF7FCFC0125002807D16069A7
+:103DE0004030007F002802D1207A28432072207AB8
+:103DF000002830D160690026014640304682857532
+:103E0000B031E069FDF7EFF96169E0698831FDF7EC
+:103E1000F3F960690146E030827D0827002A06D068
+:103E2000817C002913D1C774067585740FE04A8818
+:103E3000F8204252FA31E069FDF7C8F96169E0699A
+:103E4000FF310331FDF7CAF96069E03087756069B9
+:103E50000F212030C176F8BD10B5AD4C606920301F
+:103E6000C17E0020FFF7B4FC002803D1207A012195
+:103E700008432072207A002812D1E069FDF769F921
+:103E800000280ED0E069FDF75FF96169CA2250523F
+:103E9000098E00F0D6FD002806D0282000F05EFD37
+:103EA00010BDFFF73AFF10BDE069FDF74BF96169FE
+:103EB000C0310873E069FDF740F96169C031C8811C
+:103EC000E069FDF72BF96169C0310882E069FDF70F
+:103ED0002AF96169C0314882E069FDF729F9616911
+:103EE000D422505208202031C87610BDF8B5884C35
+:103EF000A079C00776D0207A002873D1606920307D
+:103F0000C17E0120FFF764FC002863D1E069002531
+:103F1000C178022701260B0002F076FB0D1613086C
+:103F2000415A5A445C575A192F545A00FDF74CF91C
+:103F30006169C62250543B20475440314D828E75F2
+:103F400048E000F093FD45E0FFF786FF42E060693E
+:103F50002030C17E0020FFF73BFC002802D1207AF0
+:103F600030432072207A002834D160690146403104
+:103F70004D828E750B2120300FE0606901462030A4
+:103F8000C27E0C2A02D0227A3A432272227A002A76
+:103F900020D1C57740310E770D21C1761AE0FFF7A9
+:103FA00013FF17E0606901462030C27E122A02D05A
+:103FB000227A3A432272227A002A0BD140318D753F
+:103FC0001721EAE7FFF7C4FE04E000F00DFD01E071
+:103FD000FFF7A3FE62690023106F516F401C594127
+:103FE00051671067F8BDF8B5494C05466069203047
+:103FF0008079012801D1FBF7E9FA012D14D160691C
+:104000004021095C002903D12030C07F002801D065
+:10401000FBF79BFDFBF7BDFAFBF7B0FAFBF708FADD
+:10402000FBF72DFAFBF746FA60790225C107012656
+:10403000002901D180070ED560692030817F0029D9
+:1040400002D0032902D006E0867700E085770021C0
+:104050000120FFF70AF960692030817F012903D12F
+:104060006179090700D58577607A002803D100F0CF
+:1040700027FDFFF7A4FC207900250028606902D005
+:104080008030058403E08030018C491C0184607914
+:10409000C00705D06069AC210D544030858104E033
+:1040A000616940318889401C8881E079002806D008
+:1040B0006169A031087B022806D8401C087360693A
+:1040C000A030007B022806D9606901468030058453
+:1040D0004584A0310D7360692030C17E0020FFF758
+:1040E00077FB002804D160692030C07E072855D1B5
+:1040F00060690146C0310A7A062A4FD0497A0629FA
+:104100004CD03E21095C05E0FC3C0100BA050000F2
+:10411000C4000020022941D1A030007B00283DD1FD
+:10412000FDF74FFB002839D0FDF704FC002835D0FF
+:1041300061690A468032508B01282FD90846A03089
+:10414000844646716038C7898389B81E834201DB83
+:10415000012002E0F81A401E80B2138CA789BB42EE
+:1041600001D3012302E0FB1A5B1C9BB2984200D9E9
+:104170001846012801D163465D71C0310B78002BD0
+:1041800010D0528C49888A4201D3012102E0891A59
+:10419000491C89B2884205D9084603E061690120BB
+:1041A000A0314D7161690A8E803110188883FFF744
+:1041B000DAFAFFF761FAFEF756FF002809D06069C6
+:1041C0000146FF3001300279002A02D14988C180BE
+:1041D00006716069A0308571F8BD70B5F84C6069F2
+:1041E0002030407D00283ED0022810D1FDF7C2FAD1
+:1041F000002804D17120F349000102F014F962692A
+:104200000023916ED06E491C58419166D06660695A
+:10421000002520304575017D012904D10575A1795E
+:1042200010221143A171C17C012915D1C574A07957
+:1042300008210843A071FDF76AFB002804D1E5209E
+:10424000E049C00002F0EFF860690023816EC26EA1
+:10425000491C5A41C266816660692030817D01290E
+:1042600002D0012181753FE585753DE570B5D44CDF
+:104270000026E169012508788207920F0420012AAF
+:1042800015D0022A13D0032A03D0217A01432172C8
+:104290002AE560780028FBD1606920308574A17917
+:1042A0002943A17122E0C6751EE5C5751CE5497854
+:1042B000CA0624D06278002AEAD1C906C90E1B2991
+:1042C00018D8617901436171FDF75FFB002804D1C3
+:1042D0003B20BC49400102F0A6F860690023016F51
+:1042E000426F491C5A41426701672030C17D012954
+:1042F000DBD1D8E7207A102108432072F4E460690A
+:10430000F3E77CB504460020C0436946888001A8D5
+:10431000FCF7B2FD00287AD169468888FCF790FD49
+:10432000002803D0A749A84802F07DF8009801466C
+:10433000E030827C0025002A08D0657010212170B1
+:10434000C17CA170017DE170857472E082799C4E20
+:10435000002A13D065700720207008E07169E620FC
+:104360008D8445540A22A01CE83101F0DEFE00983D
+:10437000E03080790028F1D1A5705AE0827D002AD2
+:1043800038D0827D130002F03FF90D2F2F2F2F2FF1
+:104390002F2F2F112F2F24082F0065700C21217033
+:1043A000017EA17071694988A18010E065700820C4
+:1043B00020707069082240886080201DFA3101F069
+:1043C000B4FEFF2100980331095AA181E0308575C0
+:1043D0002FE065700B212170017EA1707169498801
+:1043E000A180017FA171F2E7774876495D3002F044
+:1043F0001AF81EE0C81DF9300279002A08D01122EF
+:1044000065702270811C89886180057111E012E05D
+:10441000027A002A0FD012226570FF312270033118
+:1044200004E005720A8962804A89A280027A002A21
+:10443000F7D101207CBD00207CBD614800780128B7
+:1044400001D00C2070470020704770B55C4C0546C9
+:104450002078002804D05C485A49933001F0E3FFEB
+:1044600000202561A07201202070FFF7E6FF0028E0
+:1044700004D0554853499E3001F0D5FF34E4F8B5D7
+:104480004F4F3978012901D00C20F8BD0126A62113
+:1044900078610E548030807CFDF752F900282FD0CF
+:1044A00078698030807CFDF753FA002828D078693D
+:1044B0008030807CFDF7E5F9002821D078698030D4
+:1044C000807CFDF70AFA00281AD0FAF7E6FF78692F
+:1044D00000258030408B002827D039481830FDF760
+:1044E000DAF9002821D07869C421095C00291CD0A0
+:1044F0002030C17E0120FFF76BF9002802D014E0C4
+:104500001220F8BD78692030C17E0420FFF760F9E1
+:1045100000280AD1786950210D526030457102207F
+:10452000FFF773F97869A03045717869E621095C75
+:10453000002903D1818CC288914200D8C188B981F9
+:1045400001468031CA8B521E93B20A8CD21892B2A5
+:104550000A8494460246A0321479002C02D04D847D
+:10456000157102E04C8CE4184C8404464034A78951
+:10457000FF18A7814C8B012C01D8641C4C83002BA5
+:1045800000D015732030C07E0D4C04281ED0507909
+:1045900000281DD0A1898C451AD2FDF712F90028F8
+:1045A00016D060690146C0310A78002A10D08030E8
+:1045B000408C498888420BD3A570E6700AE0000061
+:1045C000C4000020FC3C010081080000A67001E04E
+:1045D000A570E5706069A5210D543B21095C062991
+:1045E00001D0072918D1CA21028E095A511A09B2DD
+:1045F000002911DB01460522CC310A3001F095FD7E
+:10460000012202216069FCF7EEFE6069C9210D54A8
+:104610003B210D546030867160699E210A5A811CCD
+:104620003030FCF71EFFA07800283DD16069C02122
+:10463000095C002901D0803045840120FAF7A4FDEF
+:1046400060691330FAF713FF60690F30FAF753FE11
+:104650000120FAF71FFF61694020405C002803D168
+:104660003F20405C00280DD00A467831C8C9F9487F
+:104670007832D26842632830C8C008220D30091D44
+:1046800001F053FDFAF701FF01210846FAF758FE41
+:1046900060698030806AFAF716FFFEF7A5FF60694F
+:1046A0004030007AFAF730FE6571E571A571257228
+:1046B0006572257102202070FAF7FCFE0020F8BD1B
+:1046C00010B5E54C2078022801D00C2010BDA07850
+:1046D000002803D00020FFF786FC17E0FAF7DDFE84
+:1046E00000F033F9606920308079012801D1FAF7B0
+:1046F00076FFA07A002809D0012807D0022807D029
+:10470000032805D0D549D64801F08DFE002010BD04
+:10471000EEF77EFCFAE7D0498872704710B5CE4CB0
+:104720002078032804D0CE48CC49293001F07BFE04
+:10473000606901212030827C002A06D00022827428
+:104740000175A27904231A43A271A2691378DB438D
+:104750009B0707D1C37C002B04D1C174A07902212F
+:104760000843A0711078C00606D4E0690078C0063E
+:1047700002D4E07900280CD06078002809D1A07913
+:10478000002806D1FEF75DFC002802D0207A002820
+:1047900003D00120FFF727FC03E0FEF725FF00F020
+:1047A000D4F8207801280DD0A07A00280AD001285A
+:1047B00008D0022807D0032805D0A948A7496830A7
+:1047C00001F031FE10BD0120FBF719F810BD10B546
+:1047D000A14C606920308079012812D1FAF7F6FEE9
+:1047E0006169881C3031FCF7C5FE002809D060697A
+:1047F000C21D4388F93253812030007E107301209E
+:10480000107210BD70B5944C05462078042804D071
+:1048100093489249803001F006FE617910200143EF
+:104820006171002D50D0FBF7A8F96178012508438C
+:10483000002811D160694021095C00290CD0E16990
+:104840004A78D20608D0097820300907C07DC90F00
+:10485000814201D165724EE0E078002809D0E0691C
+:104860004178C90605D10078C00602D4FFF7AFFF32
+:1048700041E0FFF7ACFFE06900784007C10F6069D5
+:104880002030807D814205D0FFF7A7FC60790821A8
+:1048900008436071E06900780007C10F606920304B
+:1048A000C07D814201D1FFF7E1FC6079284360714E
+:1048B0000020E071A079000704D560692030C07E37
+:1048C000032818D0207A14E0022001436171E079B6
+:1048D000401CC0B2E07101280DD8606940300078FA
+:1048E00000280CD05B484078C106C90E052906D2C5
+:1048F000C006002803D00120FFF775FB01E0FEF79A
+:10490000BDFD207801280DD0A07A00280AD001280A
+:1049100009D0022806D0032805D051484F49E2307B
+:1049200001F081FD9FE40120FAF769FF9BE410B5D7
+:1049300049480078042804D049484849EA3001F041
+:1049400072FD0120FFF74FFB10BD10B501210020C3
+:10495000FAF7DBFE40490420087010BD3E494A22A8
+:104960004969505404202031C876704710B53A4C3C
+:10497000C8206169405C00281CD0062806D0203180
+:10498000C97E0020FEF724FF002813D0606901468D
+:10499000C0310A7A130001F037FE070D0D0D0D0D21
+:1049A0000D050D004030807FC20704D0C043800752
+:1049B00000D1087210BD0C20FEF727FF60690122AC
+:1049C0004030817F1143817710BD10B5002A0AD095
+:1049D000002306E0D41A6418203CE47FC4545B1C16
+:1049E000DBB29342F6D310BD7CB51B4C606920301E
+:1049F000C17E0020FEF7ECFE0125002802D1207ABE
+:104A000028432072207A00281AD16946E069FCF711
+:104A100022FC684600780022C107C90F6846017071
+:104A20006069002902D06030057101E060300271D8
+:104A30006069014640304282857509202031C87680
+:104A40007CBD401A074900B2884201DC00280BDC1B
+:104A50000120704790140020C4000020FC3C01009D
+:104A6000F4090000FE7F00000020F2E710B5534C6F
+:104A700060692030C17E0020FEF7AAFE0028207A5F
+:104A800010D000280DD1E069FCF797FB6169CA22BC
+:104A90005052098EFFF7D5FF002807D02820FFF7D6
+:104AA0005DFF10BD01210843207210BD6169E069FE
+:104AB000CC31FCF77AFB606906212030C17610BD4D
+:104AC00010B500F04EF83D4C607940070BD5606999
+:104AD0002030C17E0520FEF77BFE002803D0207A1F
+:104AE000082108432072FFF701FA00F018F8FFF7D9
+:104AF00073F8A079C0060FD5207A00280CD1606920
+:104B00002030C17E0B0001F07FFD07070707070774
+:104B1000070507000721C176FEF7F3FF10BD10B5AA
+:104B200026488179490715D5017A002912D14069B3
+:104B30003B21095C891E0B0001F066FD07050C0C8A
+:104B40000C0D0C0F0C00002256210A54C030807945
+:104B5000FFF704FF10BD012100E00221C0304172C7
+:104B600010BD10B515488179090720D5017A0029B3
+:104B70001DD1406902462032D47EA41E230001F0DC
+:104B800043FD13160B1616161616161616161616BF
+:104B90001616161616171600562211546030407954
+:104BA000002801D0062000E01620FFF7D7FE10BD38
+:104BB0004030C1768175D17610BD0000C400002060
+:104BC00030B50346002002460DE09C5C2546303D92
+:104BD0000A2D02D30020C04330BD0A256843303877
+:104BE0002018521CD2B28A42EFD330BD70B50D46A8
+:104BF000144608E00A2101F012FB2A193031203A4C
+:104C0000641ED177E4B2002CF4D170BD10B500233E
+:104C100010E0040A00020443A0B2CC5C4440200629
+:104C2000000F60400407240C44402006C00C604084
+:104C30005B1C9BB29342ECD310BD000010B572B662
+:104C400000F0DCF800280BD0ECF72AFBF8F7EFFDBA
+:104C500000F0A5FD6E490020C86288626D490860B9
+:104C600062B6002010BDF3B5002501200007C06A20
+:104C700081B0C0430006000E04D167480068401CA4
+:104C800000D1012572B600F0B9F8002802D062B652
+:104C90000820FEBDECF75AFAECF706FB5F4B604EBE
+:104CA00000211A68CA40D2071FD00246CA40D20764
+:104CB00018D14AB2002A07DA1407240F083CA408C6
+:104CC000A400A419E46904E09408564FA400E41970
+:104CD00024689207D20ED4402206920F012A04D0F3
+:104CE000032A02D062B65048FEBD491C2029D8D301
+:104CF0000198030001F088FC14212323232323239C
+:104D000023230B0D0F11131F1517191B1D2E002424
+:104D100016E0012414E0022412E0032410E004242D
+:104D20000EE008240CE009240AE00A2408E00B2421
+:104D300006E00C2404E0052402E0072400E0062439
+:104D4000F06901210002000AC9070843F061002D43
+:104D500004D009E062B601200003FEBD2C4D3348AB
+:104D6000E862ECF7A1FAA8622A49314808603149A3
+:104D700002980860ECF798FA214600F0F7FCF8F783
+:104D80001AFD00F0FDFE00F073FD0198ECF756FAF5
+:104D9000040062B603D0FFF751FF2046FEBD00209D
+:104DA000FEBD10B5044600F029F8002800D001200F
+:104DB0002070002010BD204908600020704710B509
+:104DC0000C46102808D011280BD012280CD013281C
+:104DD0000ED00120086010BD03CC083CFFF743FF54
+:104DE0000AE0FFF72BFF07E02068FFF7DAFF03E098
+:104DF0001149206808600020206010BD05480C495A
+:104E00000068884201D101207047002070470000EF
+:104E100000050040780000200010001000E100E0D4
+:104E200000ED00E000E400E00110000000190000C7
+:104E3000BEBAFECAE40000200400002010B52038ED
+:104E40000C46030001F0E0FB33A6AAAEB2B8BCC02A
+:104E5000C5E0DBE41B1F23272C31373C41474D5075
+:104E600054585C606D71656974787C8084888C901E
+:104E700094989C9FA2CACFE9F0F3D3D7F80020689A
+:104E800000F0DDF8D6E0206800F0E1F8D2E020681C
+:104E900000F0F5F8CEE0207840B200F0D7FAC9E093
+:104EA000207840B200F0F5FAC4E02078616840B2A2
+:104EB00000F008FBBEE0207840B200F018FBB9E03B
+:104EC000207840B200F023FBB4E02078217940B292
+:104ED00000F02EFBAEE02078616840B200F058FB95
+:104EE000A8E000F064FBA5E0206800F068FBA1E00A
+:104EF000207800F07DFB9DE02068F8F72CF899E021
+:104F00002068F8F72CF895E021792068F8F72EF85A
+:104F100090E0206800F0E6F98CE0206800F0E7F906
+:104F200088E0207800F0E7F984E000F0F1F981E012
+:104F3000207800F0F3F97DE0207800F005FA79E0C0
+:104F4000206800F01EFA75E0206800F020FA71E099
+:104F5000206800F022FA6DE0206800F023FA69E092
+:104F6000206800F025FA65E0206800F027FA61E08B
+:104F7000206800F028FA5DE00846ECF7FFF859E0F9
+:104F8000EDF719FA56E0EDF746FA53E02068EDF731
+:104F90004EFA4FE0206800F0E1F84BE0206800F0A6
+:104FA000E9F847E0206800F0F0F843E02078A268D4
+:104FB000616800F0F5F83DE0207800F006F939E08E
+:104FC000207800F017F935E02078616800F027F9C3
+:104FD00030E02078616800F03AF92BE02179207800
+:104FE00000F016FC26E0206800F06BF822E0206854
+:104FF000F8F70CFB1EE02068F8F7F0FA1AE007CC8F
+:105000000C3C00F0FFFC15E0206800F052FD11E0C0
+:1050100003CC083C00F07DFD0CE0206800F06EFF42
+:1050200008E009E003E0FFE700F080FF02E020680D
+:1050300000F0B8FF206010BD0120086010BD002105
+:105040000170084670470146002008707047EFF372
+:105050001081C907C90F72B60278012A01D0012256
+:1050600000E0002201230370002900D162B6002A6B
+:1050700001D000207047012040037047E7E7EFF3BD
+:105080001081C907C90F72B600220270002900D131
+:1050900062B600207047F2E710B52848FFF7CFFF4F
+:1050A000002803D026A11D2001F0BDF92348401C93
+:1050B000FFF7C5FF002803D021A1212001F0B3F99B
+:1050C00010BDF1B5224D6F6801261C48FFF7BFFFE8
+:1050D0001A4C002803D10026601CFFF7D0FF1D4AA0
+:1050E0001D490120506000BF00BF00BF00BF00BFCE
+:1050F00000230B604B60009B6B60106000BF00BF23
+:1051000000BF00BF00BF0868002802D1486800281F
+:10511000F9D048680028E4D1002E04D06F60601CEC
+:10512000FFF795FF07E0601CFFF791FF0028D3D140
+:105130000248FFF7A4FF0020F8BDC2E7E800002006
+:105140007372635C736F635F6563622E630000005C
+:1051500000E5004000E0004000E100405A495B4BA0
+:105160000A685B499A42096801D18904890C016087
+:10517000002070475449554B0A6855499A4201D15D
+:105180008004800C4860002070474F494F4B0A68EC
+:105190004F499A4201D18004800C886000207047FA
+:1051A00030B5494B494D1C684A4BAC4202D01028DF
+:1051B00002D203E00E2801D3184630BDC300444894
+:1051C000181801614261002030BD3F493F4B0A6819
+:1051D0004049491C9A4202D0042802D203E0022826
+:1051E00001D3084670473C4A0121C0008018016085
+:1051F000002070473449354B0A683649491C9A42A9
+:1052000002D0042802D203E0022801D308467047E6
+:10521000314A0121C000801841600020704770B5FC
+:10522000294A2C4B14682D4E284D82005B1C921984
+:10523000AC4203D0042803D2116006E0022801D357
+:10524000184670BD8804800C1060002070BD70B5D9
+:105250001D4A204B1468214E1C4D82005B1C921984
+:10526000AC4203D0042803D2106806E0022801D320
+:10527000184670BD10688004800C0860002070BD66
+:1052800010B5134A164890600E200021C3009B18E9
+:1052900019615961401C1028F8D300200F4A05E01D
+:1052A000022803D383009B18196005E083009B1834
+:1052B0001C68A404A40C1C60401C0428F0D310BD7E
+:1052C000034907488860704778000020BEBAFECACC
+:1052D00000F501400820000000F0014000F8014006
+:1052E00000C0FFFF47490968016000207047454939
+:1052F0000860002070470121434A002803D001289C
+:1053000003D042487047916300E0D16300207047AA
+:105310003F49012008603D48801C704704223D4BF6
+:105320003B49002805D05A600869012210430861F2
+:1053300008E008694008400008619A60324900208E
+:10534000C03188600020704731490622002808D00B
+:10535000012809D002280DD003280FD02B48401C6B
+:1053600070470869904302E008699043801C086117
+:105370000020704708699043001DF8E70869104352
+:10538000F5E723494A6A02434A62002070472049F0
+:105390004A6A82434A62002070471D49496A016097
+:1053A000002070471A49CA690243CA610020704749
+:1053B0001749CA698243CA61002070471449C96904
+:1053C0000160002070471249024600204031002A47
+:1053D00003D0012A01D0072070478A6370470D4926
+:1053E0000420886008490020C03188600A480168AC
+:1053F0008022090A0902114301600849012008605E
+:1054000070470000000400404000004004200000FD
+:10541000000500400003004000E400E000E100E07F
+:105420008107C90E002808DA0007000F0838800835
+:10543000814A80008018C06904E080087F4A8000AB
+:1054400080180068C8400006800F704710B50446F9
+:1054500000F0DBF8002813D02046FFF7E1FFC0B2D0
+:1054600000F0E1F800280DD07549E2060B78D20E65
+:1054700001209040002B08D04A681043486006E0A5
+:10548000704810BD6F48401C10BD6F490860002077
+:1054900010BD10B5044600F0B8F800280BD06849DC
+:1054A000E2060B78D20E01209040002B05D04A680E
+:1054B00082434A6004E0634810BD6349803108605C
+:1054C000002010BD70B50D46044600F09EF800287F
+:1054D0000BD05E480068E206D20E012191400840E0
+:1054E00000D001202860002070BD564870BD10B566
+:1054F000044600F08AF8002807D0E106C90E012012
+:10550000884052490860002010BD4E4810BD10B5BB
+:10551000044600F07AF8002808D0E106C90E012000
+:1055200088404A4980310860002010BD454810BDC0
+:1055300070B50D46044600F068F8002819D02846DA
+:1055400000F071F8002816D0A007C10EFF228A4093
+:10555000A807000E8840002C10DA2107090F08392F
+:105560008B0835499B005B18D96991430143D96188
+:105570000CE0344870BD3348401C70BDA3082F496F
+:105580009B005B181968914301431960002070BDAE
+:1055900070B50C46054600F038F8002805D02846BE
+:1055A000FFF73EFF2070002070BD264870BDBFF39E
+:1055B0004F8F21492648C860BFF34F8FFEE770B573
+:1055C0001F4C05462178012000290ED1207072B6AB
+:1055D00000F0F4F81C4E803631688143616000F0C1
+:1055E000EDF8C043306062B600202870002070BD26
+:1055F00013490A78002A06D0002804D1124A4868C4
+:105600001060002008700020704710B50446202864
+:1056100007DA00F0D3F80121A140084201D10120AE
+:1056200010BD002010BD012803D0032801D00020A8
+:10563000704701207047000000ED00E000E400E04A
+:10564000EC0000200120000000E100E000E200E0AA
+:105650000400FA05F8B50446800700250126002855
+:1056600004DA5848C563C66302208443E00404D5C5
+:105670005548C563C66380148443600003D553480E
+:10568000456080058443E00504D55148C563C66381
+:1056900080158443A00404D54E48C563C6634014F6
+:1056A000844360042704C00FF90F884203D04AA145
+:1056B000612000F0B8FEB80F0AD04C49CD634C48C9
+:1056C000C563C563CE63C663C6630320800384439A
+:1056D00020050AD5474FFD632F20EBF765FDFE63DC
+:1056E0002F20EBF761FDF8148443FFF7C9FD424812
+:1056F000044203D038A18D2000F095FEF8BDF0B52E
+:1057000000210A46FF230446CC40E4072AD04CB2CD
+:10571000E606F60E0125B540384E3560384E356048
+:10572000002C11DA25072D0F083DAE08354DB600C7
+:105730007719FD69A407E60E1C46B440A54314463C
+:10574000B4402543FD610DE0A6082F4DB600761943
+:105750003568A407E70E1C46BC40A5431446BC4070
+:1057600025433560491C2029CDD3F0BD70B5274CA9
+:105770000D462060FFF76EFF2068FFF7C0FF284648
+:10578000ECF7EAFEFFF788FCF7F778FBFFF778FD08
+:10579000FFF725FEECF766FD00F06AF870BD10B566
+:1057A0001A4C2068FFF756FF2068FFF7A8FFFFF7A5
+:1057B00067FDECF74BFF0020206010BD1348006828
+:1057C00070470000C01F0040C0CF004000E501400E
+:1057D000C08F0040C0DF00407372635C736F635F13
+:1057E000636F6E6669672E6300000000C0EF0040C3
+:1057F000C0FF0040C0BF0040FEFF0FFC80E100E0A2
+:1058000080E200E000ED00E000E400E0F4000020B1
+:1058100070B5002402460D4620462146002A1ED0BF
+:10582000012A04D0022A04D0032A1ED103E0012059
+:1058300002E0022013E003202B0000F0E5FE071633
+:105840000507090B0D0F1600012108E0022106E0F3
+:10585000032104E0042102E0052100E00621F8F71D
+:1058600058F8002801D0204670BD0724FBE700004F
+:10587000B348002101708170704770B5B14D0123AC
+:105880006B60B14B1C68002CFCD0002407E00E6854
+:1058900006601E68002EFCD0001D091D641C944289
+:1058A000F5D30020686018680028FCD070BD70B582
+:1058B000A34C0E466178884203D0A4A16F2000F06B
+:1058C000B2FD0325330000F09FFE09520624245246
+:1058D0005252524952002078022803D09BA17320D3
+:1058E00000F0A1FD2570A078022802D0012804D084
+:1058F00008E0A06800F0D2FB04E02046083007C8AA
+:10590000FFF7BBFF0020A070F7F7A4FF0420207072
+:1059100070BDF8F754F801466068F9F776FA064664
+:105920002078022803D089A1872000F07CFD8B4AD3
+:105930008B498C48964205D86269032A02D2521CD0
+:10594000626102E0864207D84D71801BC8608449BD
+:105950006078F8F7B4FC70BD032003E0A07800285D
+:10596000FAD10220F7F77EFE00F0E1F870BD77A1D2
+:10597000B12000F058FD70BD70B50546F8F71FF86E
+:105980006F4C60602078012803D070A1B82000F02F
+:105990004AFD73490220087000220A718D600422BA
+:1059A0004A71704ACA6020706078F8F788FC70BD50
+:1059B00010B5634CA078002802D12078002801D0CF
+:1059C000112010BD6848F7F78BFF607060780028E1
+:1059D00004D0012020700020606110BD032010BDA4
+:1059E00010B50124020B64040121604BA04202D2D5
+:1059F0009140186802E0203A58689140084000D071
+:105A0000012010BDF8B50E46910005464F19144609
+:105A10003F1F009100F053FB009980028919091F74
+:105A2000B14201D2012200E00022002C03D0FF216C
+:105A300001318C4201D90920F8BD4D498D4219D35D
+:105A4000AF4217D3854205D2874203D2284630435E
+:105A5000800701D01020F8BD8E420BD3002A09D157
+:105A60002846FFF7BDFF002804D13846FFF7B8FFEE
+:105A7000002801D00F20F8BD3E483F490068884209
+:105A800005D0224631462846FFF7F7FE0FE0FFF724
+:105A90008FFF0028EFD12A480121C660856004618C
+:105AA00081702046302148431830FFF765FF002001
+:105AB000F8BD10B504462E48800A84420BD300F08E
+:105AC000FEFAA04201D8102010BDA0020446FFF744
+:105AD00087FF002801D00F2010BD26482649006806
+:105AE000884203D0204600F0D9FA0AE0FFF760FFB1
+:105AF0000028F1D112480221846081701F48FFF70D
+:105B00003BFF002010BD1A48010B01208840401EB9
+:105B1000704700B50B460246FFF7F5FF104201D073
+:105B20000F2000BD114802604360002000BD10B589
+:105B3000034C6078F7F728FF00202070A07010BD9C
+:105B4000F800002000E5014000E401407372635C4E
+:105B5000736F635F666C6173682E6300307500005D
+:105B6000E0140020D0FB0100AF5801000006004007
+:105B70000080010078000020BEBAFECA3A5600003C
+:105B8000F74805218170002101704170C17081606A
+:105B9000704710B5F3490A78022A07D0CA6810186E
+:105BA000C860C8689638F9F7E9F810BD8A68101817
+:105BB00088608868F6E70378EB49EC4A002B02D04E
+:105BC000012B10D014E00379002B01D0012B0FD151
+:105BD0004379002B01D0012B0AD18368643B8B42AF
+:105BE00006D2C06810E00379002B03D0012B01D04E
+:105BF000002070474379002B01D0012BF8D1C368F6
+:105C0000643B8B42F4D280689042F1D80120704707
+:105C1000F8B504460226F8F740FD0068002803D0D6
+:105C2000D3A1BD2000F0FFFB0127CD4D002C08D0F3
+:105C30002078002817D0012805D0022811D0032889
+:105C400013D02F710DE06068C82808D3F9F70BF95D
+:105C5000002804D06068FFF79CFF012603E00026BF
+:105C600001E000F0F9F93046F8BD28780028F8D1B5
+:105C70006068FFF7A0FF0028E3D060680078002884
+:105C800026D0A878042803D0B9A1F72000F0CBFBD8
+:105C9000B44F0020387060680079012800D00020DF
+:105CA000387160684079002837D0042078716068C6
+:105CB0008168E868F8F71DF9B8606068C0689630D8
+:105CC000F8600320A870A749E878F8F7F8FAC8E761
+:105CD000A4480221017061680979012919D00021C5
+:105CE000017161684979002915D004214171616809
+:105CF0008968963181606168C968C160C068984CE4
+:105D000014346060F7F75BFE20606F700220A870AB
+:105D1000A7E70321E4E70321E8E70320C6E7F8B596
+:105D20008F4C0D46E178884204D0FF2090A11930B5
+:105D300000F079FB28468A4F00250126143703001E
+:105D400000F062FC090612375A7C8D97C4A0C4008B
+:105D5000A078032807D0A078022804D0FF2084A1CF
+:105D60001D3000F060FBF8BDA078032807D0A078B4
+:105D7000022804D0FF207EA1213000F054FB042033
+:105D8000A07025712078002810D1FFF702FFE0787D
+:105D9000F8F7D6F8E0607D49886A7D4A02402261C2
+:105DA0007B4AD24310408862002050E000F054F952
+:105DB000F8BDA078032807D0A078022804D0FF20DF
+:105DC0006BA1423000F02FFB2078002802D000F0B9
+:105DD0004FF9F8BDA07803281FD104202AE0091A42
+:105DE0006048C1600146E078F8F769FAF8BD042020
+:105DF000F7F738FCA570F8BDA078032807D0A07885
+:105E0000022804D0FF205AA1633000F00CFB207858
+:105E10000028DCD1A07803280BD0F7F7D0FD01468D
+:105E20003868F8F7F2FF0028E1DB79688142DEDBB1
+:105E3000D5E70520F7F716FCA670F8BDA078042872
+:105E400004D0FF204AA1843000F0EDFA0220A168BE
+:105E50008847FFF7DDFEFF260546BD3642E0A07805
+:105E6000042804D0FF2042A1893000F0DCFA012090
+:105E7000EDE7A078042899D0FF203DA18E3000F0F6
+:105E8000D2FA93E7A07804280AD06078002802D0DC
+:105E9000A078022804D0FF2035A1933000F0C3FA87
+:105EA0002078002893D12079002804D00620F7F725
+:105EB000D9FB2571C0E76078002805D02949E07832
+:105EC000F8F7FDF96570F8BD0720B3E7FF2028A1BA
+:105ED000AE3046E7002D0AD0012D06D024A1304671
+:105EE00000F0A1FA022DF5D1F8BD042000E0032056
+:105EF000A1688847FFF78CFE0546F3E770B50500FB
+:105F000005D0174CA078052803D0112070BD1020B3
+:105F100070BD2048F7F7E4FCE070E078002803D07B
+:105F2000A5600020A07070BD032070BD10B50C48A6
+:105F30000178002901D0112010BD817805292BD0CE
+:105F4000817801292AD08178002927D00121017088
+:105F50008178012922D0807800281FD020E000001D
+:105F600010010020F01400203D860100FF1FA10752
+:105F70007372635C736F635F726164696F5F74698E
+:105F80006D65736C6F742E630000000000050040A7
+:105F9000028100001F5D01000F2010BD00F068F8B5
+:105FA000002010BDF8B5394E0446B078002801D065
+:105FB00001280DD1002C0DD02046FFF7FCFD002854
+:105FC0000AD02078324D002808D0B078012823D09C
+:105FD0000F20F8BD1020F8BD0720F8BD02272F7054
+:105FE0002079012814D0002028716079002811D070
+:105FF00004206871A0689630A860E068E860E868EE
+:10600000224C14346060F7F7DAFC2060B77019E0B6
+:106010000320E9E70320ECE700202870207901281D
+:1060200016D0002028716079002813D004206871F0
+:10603000A168F068F7F75DFFA860E0689630E86057
+:106040000320B0701249F078F8F739F90020F8BD54
+:106050000320E7E70320EAE710B50E48816A0E4AFD
+:1060600011400A4A126911438162F7F7F3FB10BD30
+:1060700010B5064CE078F7F787FC0820F7F7F2FA3E
+:106080000520A07000202070607010BD100100205D
+:10609000F014002000050040FD7EFFFF0A4A0221A7
+:1060A00051600A490B68002BFCD0906008680028FA
+:1060B000FCD00020506008680028FCD07047012008
+:1060C000000740697047000000E5014000E401401E
+:1060D000034610B50B439B070FD1042A0DD308C804
+:1060E00010C9121FA342F8D018BA21BA884201D9A8
+:1060F000012010BD0020C04310BD002A03D0D307EB
+:1061000003D0521C07E0002010BD03780C78401C1F
+:10611000491C1B1B07D103780C78401C491C1B1B16
+:1061200001D1921EF1D1184610BDF8B5042A2CD326
+:10613000830712D00B78491C0370401C521E830742
+:106140000BD00B78491C0370401C521E830704D0EF
+:106150000B78491C0370401C521E8B079B0F05D007
+:10616000C91ADF002023DE1B08C90AE0EBF72CF870
+:10617000F8BD1D4608C9FD401C46B4402C4310C064
+:10618000121F042AF5D2F308C91A521EF0D40B7854
+:10619000491C0370401C521EEAD40B78491C037042
+:1061A000401C012AE4D409780170F8BD01E004C064
+:1061B000091F0429FBD28B0701D50280801CC90767
+:1061C00000D00270704700290BD0C30702D00270C4
+:1061D000401C491E022904D3830702D50280801C7B
+:1061E000891EE3E70022EEE70022DFE70378C278AA
+:1061F0001946437812061B0219438378C0781B04A2
+:10620000194311430902090A000608437047020AAC
+:1062100008704A70020C8A70020ECA707047002221
+:1062200003098B4273D3030A8B4258D3030B8B426F
+:106230003CD3030C8B4221D312E003460B437FD4A3
+:10624000002243088B4274D303098B425FD3030AB5
+:106250008B4244D3030B8B4228D3030C8B420DD3C8
+:10626000FF22090212BA030C8B4202D31212090256
+:1062700065D0030B8B4219D300E0090AC30B8B4294
+:1062800001D3CB03C01A5241830B8B4201D38B0342
+:10629000C01A5241430B8B4201D34B03C01A5241E7
+:1062A000030B8B4201D30B03C01A5241C30A8B422A
+:1062B00001D3CB02C01A5241830A8B4201D38B0215
+:1062C000C01A5241430A8B4201D34B02C01A5241B9
+:1062D000030A8B4201D30B02C01A5241CDD2C3092B
+:1062E0008B4201D3CB01C01A524183098B4201D3A7
+:1062F0008B01C01A524143098B4201D34B01C01A92
+:10630000524103098B4201D30B01C01A5241C30809
+:106310008B4201D3CB00C01A524183088B4201D378
+:106320008B00C01A524143088B4201D34B00C01A64
+:106330005241411A00D201465241104670475DE079
+:10634000CA0F00D04942031000D3404253400022FC
+:106350009C4603098B422DD3030A8B4212D3FC22A5
+:10636000890112BA030A8B420CD3890192118B4224
+:1063700008D3890192118B4204D389013AD092113A
+:1063800000E08909C3098B4201D3CB01C01A5241F5
+:1063900083098B4201D38B01C01A524143098B42BE
+:1063A00001D34B01C01A524103098B4201D30B01A7
+:1063B000C01A5241C3088B4201D3CB00C01A5241CC
+:1063C00083088B4201D38B00C01A5241D9D24308B3
+:1063D0008B4201D34B00C01A5241411A00D20146F0
+:1063E000634652415B10104601D34042002B00D55A
+:1063F0004942704763465B1000D3404201B500201C
+:10640000C046C04602BD70477047704710B500F0E7
+:106410003BF810BD012308CB134B1860134B1960D8
+:10642000134B1A607047134A134B13607246053AB8
+:10643000F0E7114A0F4B1B689A420ED10D4B00201A
+:10644000186001980D4B04B598470CBC9E46024657
+:10645000029800990A4B1B68184706980599094B42
+:106460001B68DB6818470000340100203801002059
+:106470003C0100202C010020EFBEADDEC9CD0000A4
+:10648000E4000020040000201D481E497047FFF76B
+:10649000FBFFEAF753FE00BD01200007C06AC0B24F
+:1064A000FF2804D1184819490968884202D01848C1
+:1064B00018490160184819490968884203D1184AE7
+:1064C00013605B68184700BD20BFFDE71248134901
+:1064D000096888420ED1134B18680B498842F3D0E3
+:1064E00080F308881049884204DD104802680221C0
+:1064F0000A4302600E4880470E4880470E48004716
+:106500000015002000150020FFFFFFFF0010001005
+:106510002C050040080000000010000000000020D2
+:10652000040000200080010000200020240500401D
+:10653000DFCD000099640100156401001348704527
+:1065400002D1EFF3098101E0EFF308818869023895
+:106550000078102814DB202810DB2B280BDB0C4ADA
+:1065600012680C4B9A4203D1602804DB0A4A104798
+:10657000022008607047094A10470000084A104787
+:10658000084A12682C32126810470000FDFFFFFF16
+:1065900078000020BEBAFECAAD1200003D4E0100D8
+:1065A000BF4D0100040000200D4B0E4908470E4B63
+:1065B0000C4908470D4B0B4908470D4B0949084743
+:1065C0000C4B084908470C4B064908470B4B05493B
+:1065D00008470B4B034908470A4B0249084700008C
+:1065E00079250000192200009D2B00003F2A0000A1
+:1065F000ED2900009F270000B912000013140000CD
+:10660000012B00000F23000030B47446641E25786F
+:10661000641CAB4200D21D46635D5B00E31830BCD6
+:10662000184703B5684600784006400E401C884273
+:1066300005D269460878401CC0B208700CBD684697
+:106640000078000601D500200CBD80200CBD414023
+:10665000802901D0002070470120704737B50878A5
+:106660000C4669460978884206D020781146FFF723
+:10667000D8FF207001203EBD00203EBD37B5044646
+:106680000078154669460979FFF7E1FF002801D037
+:1066900000203EBD20782946FFF7C3FF207001206F
+:1066A0003EBD0FB568460179007881420AD0684640
+:1066B000007922214006400E4843801818600120CE
+:1066C00004B000BD0020FBE77FB5684601791C4699
+:1066D00015460078FFF7BBFF002802D0002004B069
+:1066E00070BD6846007822214006400E484340199C
+:1066F00020600120F3E70000FFFFFFFF0000FFFF25
+:106700000100030000000100000000000000000084
+:1067100000000000000000008700000000000000F2
+:10672000000000000000000000000001020304005F
+:106730000D0E0F100000000033690000516B0000C7
+:10674000196C0000736C0000C76C00002F6D000016
+:106750008D690000456A0000D16D0000DF790000FE
+:10676000100110013A0200001A02000004013C006E
+:10677000230044000E0001020408102040805555FB
+:1067800055D6BE898E0000007006120DB4130000AD
+:1067900014035A06A00900006004F208840DF401F5
+:1067A000FA00960064004B0032001E001400000046
+:1067B000E067010008000020100000000411000044
+:1067C000F0670100180000202801000004110000FB
+:1067D0001869010040010020C013000020110000D2
+:1067E0000249022208681042FCD0704700E200E033
+:1067F0000000000000000000000000000000000099
+:106800000000000000000000000000000000000088
+:106810000000000000000000000000000000000078
+:10682000000000000100010054000020FB349B5FC9
+:106830008000008000100000000000000000000048
+:106840000000000000000000000000000000000048
+:106850000000000001000000000000000000000037
+:106860000000000000000000000000000000000028
+:106870000000000000000000000000000000000018
+:106880000000000000000000000000000000000008
+:1068900000000000000000000000000000000000F8
+:1068A00000000000000000000000000000000000E8
+:1068B00000000000000000000000000000000000D8
+:1068C00000000000000000000000000000000000C8
+:1068D00000000000000000000000000000000000B8
+:1068E00000000000000000000000000000000000A8
+:1068F0000000000000000000000000000000000098
+:106900000000000000000000196401000000000009
+:0869100000000000000000007F
+:00000001FF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/Lib/s130_nrf51822_1_0_0/s130_nrf51_1.0.0_softdevice.hex	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,6861 @@
+:020000040000FA
+:10000000C0070000D1060000D1000000B1060000CA
+:1000100000000000000000000000000000000000E0
+:100020000000000000000000000000005107000078
+:100030000000000000000000DB000000E500000000
+:10004000EF000000F9000000030100000D010000B6
+:1000500017010000210100002B0100003501000004
+:100060003F01000049010000530100005D01000054
+:1000700067010000710100007B01000085010000A4
+:100080008F01000099010000A3010000AD010000F4
+:10009000B7010000C1010000CB010000D501000044
+:1000A000DF010000E9010000F3010000FD01000094
+:1000B00007020000110200001B02000025020000E0
+:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24
+:1000D00008205A49096809580847382057490968CB
+:1000E000095808473C2055490968095808474020E5
+:1000F0005249096809580847442050490968095875
+:10010000084748204D490968095808474C204B4981
+:10011000096809580847502048490968095808479C
+:100120005420464909680958084758204349096836
+:10013000095808475C204149096809580847602068
+:100140003E4909680958084764203C49096809582C
+:100150000847682039490968095808476C20374919
+:100160000968095808477020344909680958084740
+:100170007420324909680958084778202F490968CE
+:10018000095808477C202D490968095808478020EC
+:100190002A490968095808478420284909680958E4
+:1001A0000847882025490968095808478C202349B1
+:1001B00009680958084790202049096809580847E4
+:1001C00094201E4909680958084798201B49096866
+:1001D000095808479C201949096809580847A02070
+:1001E0001649096809580847A4201449096809589C
+:1001F0000847A8201149096809580847AC200F4949
+:10020000096809580847B0200C4909680958084787
+:10021000B4200A49096809580847B82007490968FD
+:1002200009580847BC2005490968095808470000D3
+:1002300003480449024A034B7047000000000020B5
+:10024000C0070000C00700000122D84B5A6000BF61
+:10025000D74A1268002AFBD0016000BFD44A126856
+:10026000002AFBD00022D14B5A6000BFD04A12684E
+:10027000002AFBD07047F0B505460E46174600240D
+:1002800006E0A200B158A2005019FFF7DDFF641C80
+:10029000BC42F6D30020F0BD0120C043C549086030
+:1002A000401048607047014601229204086890425D
+:1002B00001D9102070470020FCE7F0B505460C4638
+:1002C0001646002706E028462168FFF7BDFF2D1DD2
+:1002D000241D7F1CB742F6D3F0BD70B505460C4611
+:1002E0002E460BE0304600F075F9FF2C01D80024B3
+:1002F00001E0FF3C013C012080023618002CF1D1C6
+:1003000070BD0146012212044868904201D90920BB
+:100310007047A9484069401C01D10F20F8E7002030
+:10032000F6E7FEB504462068030000F037FA05043E
+:100330002B4249598B00201DFFF7E3FF0546002D96
+:1003400001D02846FEBDFFF7A7FF0120C00200F044
+:1003500041F9042221469948FFF78DFF002801D07A
+:100360000320EFE708222146944800F06DF90028A9
+:1003700006D1002192480068FFF766FF00F00CF9F3
+:100380000320DFE7A768E6686068019031463846D9
+:10039000FFF7A3FF324638460199FFF78EFFB20000
+:1003A0003846019900F050F9002800D1CAE703202F
+:1003B000C8E700F0E3F9834800688349086041E03A
+:1003C00060680190E668A0680090B200009901980A
+:1003D00000F03AF90746002F00D1B3E70E20B1E74D
+:1003E000201DFFF760FF0546002D01D02846A9E734
+:1003F0006068002807D1FFF74FFF0320800200F05C
+:10040000E9F800F0C9F8FFF747FF0120C00200F04B
+:10041000E1F8042221466948FFF72DFF002801D0AA
+:1004200003208FE708222146644800F00DF90028D8
+:1004300006D1002162480068FFF706FF00F0ACF823
+:1004400003207FE700BF00207CE770B505460C461F
+:10045000182D04D12068FFF764FF206002E001201E
+:10046000206000BF00BF70BDF0B589B05248406940
+:1004700003905248806881000398081802900398FE
+:10048000000B01900121090302984018401E000B47
+:1004900000900124002520462946019A00F0C4F866
+:1004A0000022401E91410791069001260027304608
+:1004B0003946009A00F0B8F80022401E914105919B
+:1004C0000490049BDB43059AD2430698184307998E
+:1004D00011430791069037490698086007984860CD
+:1004E00009B0F0BD70B53448446934488568466841
+:1004F000AA003146204600F0A7F8002801D00020CD
+:1005000070BD0120FCE72D484068002801D0012083
+:1005100000E000200546FFF7E5FF002807D0FFF7C1
+:10052000BBFE0320800200F055F800F035F8FFF71D
+:100530009BFF002D0ED020484669204884684768FC
+:1005400021463046FFF7C9FE224639463046FFF7BE
+:10055000B4FE00BF00F020F810B5184844681A48EF
+:100560000460204600F0DCF810BD15480068006803
+:10057000401C01D100BFFEE710480068002802D0EF
+:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B
+:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB
+:1005A000C860BFF34F8F00BFFEE7000000E50140C9
+:1005B00000E40140000600400010001000080000A8
+:1005C000B8070000BC070000000000200400FA0586
+:1005D00000ED00E010B50146104B1A6808460223F2
+:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC
+:1005F00004D0904202D20A4B186101E0084B986087
+:1006000000BF084B1B68002BFBD00023044C636029
+:1006100000BF044B1B68002BFBD010BD0010001066
+:1006200000E5014000E4014010B5202A04DB01464A
+:10063000203A9140002010BD914020239C1A03468F
+:10064000E3401943904010BD034610B50B439B0790
+:100650000FD1042A0DD308C810C9121FA342F8D025
+:1006600018BA21BA884201D9012010BD0020C04328
+:1006700010BD002A03D0D30703D0521C07E000208E
+:1006800010BD03780C78401C491C1B1B07D1037854
+:100690000C78401C491C1B1B01D1921EF1D118463D
+:1006A00010BD70477047704710B500F007F810BDD7
+:1006B000014B1B68DB6818470000002019481A49E5
+:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716
+:1006D0001649174C24688C420BD1164B1B68994263
+:1006E0000CD1154B154A1360186810498842EDD09B
+:1006F0000AE0134880F30888124B18470F4A13602A
+:1007000018680A498842E1D080F308880E49884277
+:1007100004DD0E48026802210A4302605B68184744
+:100720000346DFE7C0070000C0070000FFFFFFFF30
+:10073000000C000014100010001000000000002049
+:10074000000400206B05000000200020240500406C
+:100750000D48704502D1EFF3098101E0EFF3088104
+:10076000886902380078182802D1C046074A104725
+:10077000074A12682C3212681047000000B5054B7A
+:10078000054A9B58984700BDFDFFFFFF4B04000042
+:1007900000000020001000000400000030B4744687
+:1007A000641E2578641CAB4204D3635D5B00E318D0
+:1007B00030BC18471D46F8E7000C00000010000090
+:10100000F0210020FDB101005D22000063B101006C
+:1010100000000000000000000000000000000000D0
+:101020000000000000000000000000006DB20100A0
+:1010300000000000000000005D2200005D220000B2
+:10104000D9B20100DFB201005D2200005D22000084
+:101050005D2200005D2200005D2200005D22000094
+:10106000E5B201005D2200005D220000EBB201004C
+:101070005D220000F1B20100F7B20100FDB20100F3
+:101080005D2200005D2200005D2200005D22000064
+:101090005D2200005D2200005D2200005D22000054
+:1010A00003B3010009B301005D2200005D220000CE
+:1010B0005D2200005D2200005D2200005D22000034
+:1010C00000F002F81AF07BF80CA030C80838241899
+:1010D0002D18A246671EAB4654465D46AC4201D170
+:1010E0001AF06DF87E460F3E0FCCB646012633420D
+:1010F00000D0FB1AA246AB46334318477CA301003D
+:10110000ACA30100103A02D378C878C1FAD85207CC
+:1011100001D330C830C101D504680C6070470000AD
+:101120000023002400250026103A01D378C1FBD803
+:10113000520700D330C100D50B6070471FB5C046C1
+:10114000C04619F0DEFF04B00FB41FBDF0B4404636
+:10115000494652465B460FB402A0013001B506482D
+:10116000004700BF01BC86460FBC804689469246B8
+:101170009B46F0BC70470000C11000008269024924
+:101180008161024810447047911100000100000085
+:1011900001B41EB400B501F000FF01B40198864609
+:1011A00001BC01B01EBD0000401E00BF00BF00BF5B
+:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37
+:1011C00000BFF1D17047000070B505460C461646C9
+:1011D00002E00FCC0FC5103E102EFAD2082E02D31B
+:1011E00003CC03C5083E042E07D301CC01C5361F2E
+:1011F00003E021782970641C6D1C761EF9D270BD45
+:101200008307FF22DB0E9A408907090E99400028C8
+:101210000BDA0007000F0838830828489B001818CD
+:10122000C36993430B43C3617047830824489B0001
+:101230001B181868904308431860704710B504469F
+:1012400000210120FFF7DCFF00211820FFF7D8FF65
+:1012500000210B20FFF7D4FF02211920FFF7D0FF58
+:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F
+:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4
+:1012800003211620FFF7BCFF03211520FFF7B8FF4D
+:10129000204600F019F8002010BD6721018070473A
+:1012A00010B500F020F810BD0648704710B500F0EA
+:1012B00022F810BD704770477047000000ED00E055
+:1012C00000E400E003F9004370B505462D4C08200A
+:1012D0002070A01CFFF7E1FF5920A080294620467E
+:1012E00000F0B3FB70BD10B500F0B8FB254900203D
+:1012F000891E087010BDF8B5224E0446B61E30781F
+:1013000001270D46002807D0204660380B2808D852
+:10131000204600F059FF2BE0602CF9D01A480860F5
+:10132000F8BD20466C38032803D8204600F08DFF16
+:101330001EE0204670381F2803D8204600F047F9E9
+:1013400016E0204690380F2803D8204600F0EAF82F
+:101350000EE02046A0380F2803D8204600F076F88B
+:1013600006E02046B0380F2804D8204600F0E2F905
+:10137000286000E02F60602CD2D128680028CFD1EF
+:101380003770F8BD1A000020013000000120254907
+:10139000C003086024490020087007202349C005C5
+:1013A0008860704770B5204D04462878A04207D069
+:1013B000002C05D0002803D01DA14D2019F0CBFE34
+:1013C0002878A0420ED000211E4A18482C70002C0C
+:1013D0001BD01D4B012C06D0022C0DD014A168206F
+:1013E00019F0B9FE70BD1160022111605361032133
+:1013F00009068160416070BD116003211160536175
+:101400000121C9058160416070BD11601160072133
+:10141000C905816070BD10B505A1712019F09BFE52
+:1014200010BD000080E100E02000002000F5014038
+:101430007372635C68616C5F63636D5F6161722E80
+:101440006300000000F500408401002010B5A038C2
+:10145000030019F0A1FF0B070E172028313A414B6A
+:10146000525C65004B6808788A68194603F0D9F920
+:1014700010BD88888A6883B20888194680B203F054
+:10148000DFF910BD08884C68CB688A6880B22146B5
+:1014900003F0DAF910BD08884B688A6880B21946F3
+:1014A00003F0EEF910BD88888A6883B2088819466F
+:1014B00080B203F0FAF910BD88888A6883B2088880
+:1014C000194680B203F034FA10BD08884A6880B229
+:1014D000114603F073FA10BD088982B2888883B27E
+:1014E0000888194680B203F074FA10BD08884A686B
+:1014F00080B2114603F091FA10BD08894C6882B29F
+:101500000888CB6880B2214603F00AFB10BD08882A
+:101510004C68CB688A6880B2214603F01BFC10BD82
+:10152000012010BD10B59038030019F035FF0906F1
+:101530000F161D242C363F464E0088888A6883B2D9
+:101540000888194680B204F01DF910BD08884A6861
+:1015500080B2114604F051F910BD08884A6880B283
+:10156000114604F056F910BD08884A6880B2114649
+:1015700004F05CF910BD08884B688A6880B219468F
+:1015800004F067F910BD088982B2888883B20888A0
+:10159000194680B204F066F910BD08894B6882B222
+:1015A0000888194680B204F07CF910BD08884A68A2
+:1015B00080B2114604F087F910BD888882B208888D
+:1015C000114680B204F0DBF910BD012010BD10B54A
+:1015D0007038030019F0E0FE1B0F15192125282F84
+:1015E000363B4044484C53585F68707881889095EA
+:1015F000999CA2A5AC004A680878114607F019FC2E
+:1016000010BD086807F066FC10BD0C790B7B8A687A
+:101610000868214607F06FFC10BD086807F000FD60
+:1016200010BD07F08CF910BD08884A6880B21146D9
+:1016300007F034FE10BD0A790888114680B207F021
+:10164000C4FE10BD087840B207F0CDFE10BD08887A
+:1016500080B207F0E1FE10BD086807F0EFFE10BD94
+:10166000086801F0ECFB10BD086801F016FC10BD25
+:10167000088982B209C9194607F0F8FE10BD05C9EC
+:10168000114607F042FF10BD08884A6880B2114633
+:1016900009F0FAF910BD0C790888CB688A6880B225
+:1016A000214609F0CDFA10BD0B7908888A6880B20E
+:1016B000194609F07DFC10BD08884B688A6880B225
+:1016C000194609F0EEFC10BD08884C68CB688A68A2
+:1016D00080B2214609F053FD10BD08884A6880B2E7
+:1016E000114609F08CFD10BD0B7908880A7A80B28A
+:1016F000194607F02DFF10BD088880B207F02DFFB6
+:1017000010BD086807F030FF10BD07F0FCF810BDF1
+:101710008A6809C9194607F08CFF10BD07F0DCF88C
+:1017200010BD08884A6880B2114608F05BF810BD09
+:10173000012010BD10B5B02805D0B12808D0B228BE
+:101740000BD0012010BD088880B20AF056F910BDF8
+:10175000088880B20AF070F910BD08884B688A6862
+:1017600080B219460AF079F910BD000010B50300E7
+:1017700019F012FE0A0609060C0C0F0F06060612D7
+:1017800007F005F910BD09F027FF10BD01F042FA7E
+:1017900010BD06F075FA10BDFAA1FE4819F0DBFC89
+:1017A00010BD7FB5FC49054603C901900291132085
+:1017B000800169468881F94A0F2310460A2128389A
+:1017C0000AF043FE0024F6480AF05DFE641CE4B211
+:1017D0000A2CF8D304200090F04801231A4603A9EC
+:1017E000F0300AF05DFA002804D0FF20E5A1533064
+:1017F00019F0B1FC686800F024FC00211E220846A4
+:1018000004F040F907F0C6FA02222421E54801F06D
+:101810007FFBE44801222C214C3001F079FBE149A7
+:101820000B20B03901F000FA002804D0FF20D5A128
+:10183000673019F090FC09F09FFE02F075F901ABDA
+:1018400000220821D8A007F085F9002804D0FF2045
+:10185000CCA16D3019F07FFC284602F0C2FC0028B4
+:1018600004D0FF20C7A16F3019F075FCDB2189007F
+:10187000D04819F045FBCF48012141710221817107
+:101880000621C1717FBD10B5CA4CA078092804D3C8
+:10189000FF20BCA1A73019F05EFC207860214843EE
+:1018A000001900210173417BF722C908C900C91C36
+:1018B0001140EF22114041730121E1700C3010BD45
+:1018C00070B50E4600211C4619801546030019F01C
+:1018D00063FD0723050B1711231D2300224629460C
+:1018E000304609F096FE70BD22462946304606F085
+:1018F00098FE70BD22462946304601F0C2FF70BDF9
+:1019000022462946304603F0C0FD70BD22462946D6
+:10191000304600F010FC70BD9E489AA1D53819F0F1
+:101920001AFC032070BD70B5A24CE078002818D0D6
+:101930002078602148430019407B00254007400F74
+:1019400001190879401E08712078401CC0B220702F
+:10195000092800D12570A078401CA0700AF01DFF56
+:10196000E57070BD9348C079002800D08BE77047C0
+:1019700070B5904DA86800280CD0FFF7F3FF002841
+:1019800062D06022A968FFF71FFCFFF7CCFF0020A0
+:10199000A860EFE76879002856D0FFF774FF044687
+:1019A00080484C3001F0C4FA6060002804D1C9209E
+:1019B00074A1800019F0CFFB60680AF0EAF80028F3
+:1019C0000DD0204606F011FD6078010703D5C00850
+:1019D000C000401C2BE0734861684C302DE071481A
+:1019E00061684C3001F0ADFA00F05AFB00282BD1B1
+:1019F000FFF749FF04466B4801F09AFA606000283F
+:101A000004D164485FA16D3019F0A5FB60680AF04D
+:101A1000C4F8002814D0606800886080204609F06F
+:101A20002BFE6078010706D5C008C000801C6070DE
+:101A3000FFF779FF9EE75B48616801F082FA99E75A
+:101A40005848616801F07DFA70BD10B55A4CE160EC
+:101A5000A0605A4800F034FC607010BD5649002068
+:101A60000870704770B5564E0546706A94B00C46C3
+:101A7000401C04D1B06AC0430004000C0BD0306A93
+:101A8000C007C00F2870706A19F03CFAB06A207164
+:101A9000000A607114E02B206946087009A96846A5
+:101AA0000AF04BF8002804D0972036A1800019F0E6
+:101AB00052FB0120287006220AA9204619F0C1F91C
+:101AC0002878002803D06079C0210843607114B0E1
+:101AD00070BDF0B53A4C0646206895B00D463746C5
+:101AE0000837401C08D16068401C05D1A068401C24
+:101AF00002D1E068401C11D02068314619F002FA8A
+:101B00006068311D19F0FEF9A068394619F0FAF93C
+:101B1000E06831460C3119F0F5F925E02B206946D3
+:101B2000087009A968460AF008F8002804D0194886
+:101B300014A1553819F00FFB08220AA9304619F0F4
+:101B400080F92B206946087009A9684609F0F5FF5D
+:101B5000002804D0A3200BA1800019F0FCFA082271
+:101B60000AA9384619F06DF920692E460836401C3E
+:101B700029D16069401C26D1A069401C23D1E069AD
+:101B8000401C1FE07372635C686F73745F636F72F5
+:101B9000652E6300DA020000B4B30100D801002012
+:101BA0006D170000A40B00206E52463531383232DA
+:101BB00000000000880700202400002071190000A8
+:101BC0008000001012D02069294619F09BF9606945
+:101BD000291D19F097F9A069314619F093F9E069C8
+:101BE00029460C3119F08EF915B0F0BD2B2468464A
+:101BF000047009A909F0A1FF002803D0F649F748AD
+:101C000019F0A9FA082209AF28460AA919F019F90A
+:101C10006846047009A909F090FF002804D0EF4835
+:101C2000ED49C01D19F097FA0822391D304619F008
+:101C300008F9D9E770B5EA4C0546A068002804D039
+:101C40000320E549000219F086FAA56070BD10B5C1
+:101C50000146E44801F075F9E1498879401CC0B2B9
+:101C60008871012803D1E048407800F04DFB10BD99
+:101C700070B50446DD4816460D46814204D1D7486A
+:101C8000D549CB3019F067FA012E05D0E120D249B1
+:101C9000800019F060FA70BD66202070002020726C
+:101CA000A5810120A07370BD70B515460C4606468F
+:101CB000FFF758FE00280CD06621017046800121F4
+:101CC000017221680161A18881820573FFF72BFEF3
+:101CD00070BD1321304607F078FB70BDC2494968DA
+:101CE000884201D210207047032101700020704704
+:101CF00070B5BD4C05462078002694B0002801D070
+:101D00000820E4E6BA4A6260954201D21020DEE67D
+:101D10006868002809D00921D82804D3C31C9B086F
+:101D20009B00834205D00846D1E60320400268604C
+:101D30000EE0012109074B6B896B4B43AD49511AEA
+:101D40000122591AD202891A814201D20421EAE7FA
+:101D500000F052FF6178A0680CF04EFBE068401E76
+:101D600007280BD8302269460A70887068460DF043
+:101D700088FF002802D009A80CF0FBFC2846FFF7DA
+:101D800010FD012020703046A1E6F8B504469648C3
+:101D90000F464068814208D3002C01D0844204D30E
+:101DA000E01C80088000A04201D01020F8BD8C48C3
+:101DB0008178002911D039880091417860225143FF
+:101DC0000D18287B0C350007000F3B4600222946E2
+:101DD000FFF776FD060004D015E0002038800520CE
+:101DE000F8BD002C13D039880098814201D90C2607
+:101DF0000DE028783B460007000F22462946FFF7F2
+:101E00005FFD060005D00C2E01D000203880304642
+:101E1000F8BD734C6078401CC0B26070092801D1D5
+:101E200000206070A078401EA07068784107490FBC
+:101E300001290ED0022906D003291AD066496E481E
+:101E400019F089F9E3E7C006E1D46868FFF7FFFEFF
+:101E5000DDE7644869684C3001F073F86079401C34
+:101E6000C0B260710128D2D15F48407800F04CFACE
+:101E7000CDE7E079401CE071C9E7604A10B59042B7
+:101E800009D3594A0124A4045268A04201D39042C4
+:101E900001D3914201D2102010BD00F0FEFE10BD12
+:101EA000564B10B5994209D34F4B0124A4045B68EB
+:101EB000A14201D3994201D39A4201D2102010BD10
+:101EC000022803D0102801D0092010BD00F00BFF1C
+:101ED0000028FAD0052010BD484B10B598420DD30C
+:101EE000414B0124A4045B68A04201D3984205D36E
+:101EF000994203D3002A03D09A4201D2102010BD88
+:101F000000F017FF0028FAD0072010BD10B50446D6
+:101F1000354894B04068844202D2102014B010BDFD
+:101F20000F2008A9087369460BA809F006FE0028CF
+:101F3000F4D16846007A207068464089608068461F
+:101F40008089A0800020E9E710B500290BD0264A3F
+:101F50005268914202D30B68934201D2102010BD07
+:101F60008A88002A02D001F037FE10BD092010BD7A
+:101F700010B5224A94B091420ED31B4A01239B0410
+:101F80005268994201D3914206D3441E1E2C41D877
+:101F9000994203D3914201D21020BFE7012837D1E3
+:101FA00008780024C007C00F002803D0032069462A
+:101FB000887001E06846847038206946087009A975
+:101FC000684609F0BAFD002804D004480CA18B38FB
+:101FD00019F0C1F82046A1E7841B0000AA02000006
+:101FE00088070020A40B002024000020FFFF000031
+:101FF00000220020000000202104000000C0010099
+:102000007372635C686F73745F636F72652E6300D5
+:10201000072083E70246203A1F2AF9D806F001FE7E
+:102020007CE710B5604A5268914201D2102010BD81
+:102030000246203A1F2A02D806F068FE10BD07208B
+:1020400010BD70B50546594C002020702046461939
+:1020500055484660E01C80088000A04204D0FF2064
+:102060005349293019F077F801200007C06AC043AE
+:102070000006000E03D14F480068401C03D04E48B4
+:102080004E49301AC862A8B20422214604F00DF964
+:10209000002804D0FF204649393019F05CF870BDA3
+:1020A000F0B595B03B2008A9087369460BA809F064
+:1020B00044FD002804D0FF203D49813019F04BF841
+:1020C0003F4E00246D4630E02F19B87DC10706D081
+:1020D000400704D460004019C08809F0E9FB394882
+:1020E000807900281FD0B87D80071CD5600040197A
+:1020F000C0880022062109F0F7FB002813D03C21FC
+:1021000008A8017360004019C1886846C185694606
+:102110000BA809F012FD06000BD0FF2024499630D1
+:1021200019F019F805E0641CE4B268460079A04291
+:10213000CAD8304658E5F7B50546007800270009AB
+:102140000C463E46062804D0FF201949BF3019F03E
+:1021500002F8287A00280ED0012814D0FF20144954
+:10216000E03018F0F8FF0298002C068001D027809C
+:1021700066800020FEBD02270926002C10D0A88909
+:10218000A080A87B0AE003271426002C08D06888CA
+:10219000A0802869E060A88A2082287B2072E2E77C
+:1021A00002980680E5E700002400002000220020BD
+:1021B000002000000010001000000020000500407A
+:1021C000043000008807002010B56038030019F0C3
+:1021D000E3F80A060A0F13181F252930353A086854
+:1021E000FFF786FD10BD05C91146FFF7CEFD10BDF6
+:1021F0000868FFF773FD10BD05C91146FFF73DFEE6
+:1022000010BD4B6808788A681946FFF749FE10BD73
+:102210008A6809C91946FFF75FFE10BD0868FFF715
+:1022200075FE10BD08884A6880B21146FFF78CFE23
+:1022300010BD05C91146FFF79BFE10BD05C911462B
+:10224000FFF7EFFE10BD012010BD01207047000018
+:102250000E4A12680C498A420AD118470B4A126882
+:10226000094B9A4204D101B500F08EFE03BC8E46A4
+:10227000074909680958084706480749054A064BAF
+:102280007047000000000000BEBAFECA64000020D3
+:1022900004000020F0210020F021002001203F490F
+:1022A000400608603E4908603E490A68FF231B0259
+:1022B0009A4383121A430A6038498039086070478C
+:1022C00010B502460420384904E0C3005B181B79AE
+:1022D000002B0AD00346401EC0B2002BF5D133A11B
+:1022E000432018F038FFFF2010BDC300CA50002261
+:1022F00059184A718A7101220A7110BD2A4A0021B7
+:10230000C00080180171704710B50446042803D33B
+:1023100026A1522018F01FFF2348E1000C18207955
+:10232000012803D021A1532018F015FF6079A1796D
+:10233000401CC0B2814200D06071012017494006A4
+:102340008031086010BD70B5164804250068164E2F
+:102350000004800F1B4C02281AD014A1692018F029
+:10236000FAFE15E02078C10088190279012A07D108
+:10237000427983799A4203D04279827170588047BA
+:102380002078401CC0B22070042801D300202070A7
+:1023900028466D1EEDB20028E4D170BD80E100E05A
+:1023A00080E200E018E400E0200C00207372635C1F
+:1023B000736F635F7369676E616C6C696E672E63C0
+:1023C000000000003400002010B5EFF31080C407B7
+:1023D000E40F72B6D2484178491C41704078012818
+:1023E00001D10AF0FFF9002C00D162B610BD70B522
+:1023F000CB4CE07800280AD10125E570FFF7E4FF17
+:102400000AF0F8F9002804D000200AF0CBF90020E7
+:1024100070BDC44865714560F9E770B5EFF3108091
+:10242000C507ED0F72B6BE4C6078002803D1BEA17F
+:102430008F2018F090FE6078401E60706078002851
+:1024400001D10AF0D3F9002D00D162B670BD10B5EC
+:10245000B348C178002904D000214171C170FFF751
+:10246000DCFF002010BD10B504460AF0C3F9AC49EA
+:10247000C978084000D001202060002010BDF8B5C8
+:102480000246A74C0026A67108200421012510272A
+:10249000130018F081FF0D080A0C0E101214161EFE
+:1024A000262123252800257122E0022001E0217148
+:1024B0001EE020711CE027711AE02020F9E70126B8
+:1024C00016E0FFF781FF0AF095F90028FBD00226FD
+:1024D0000EE02171A5710BE02771FBE7202000E0E1
+:1024E00040202071F6E7FF208FA1763018F033FEF0
+:1024F0000AF08CF9002809D00AF08EF9B04205D113
+:1025000030460AF08CF90028FAD02CE00120800730
+:10251000C560894900224A60884A9661814B02223F
+:102520005A60856086480269D243D206D51702698F
+:1025300010231A4302610F466D1C00E020BF78682B
+:102540000028FBD030460AF06AF90028FAD0002DA6
+:1025500004D17B48026910218A430261714902203B
+:10256000886000207860A07900280CD00AF042F939
+:1025700005460AF09FF8734A002D02D0A260E06081
+:1025800001E0E260A060002E01D100F0A5F8F8BDE6
+:1025900010B504460AF034F9002805D0604901203E
+:1025A000C8704A78521C4A702046FFF768FF10BD79
+:1025B000F8B5614DA8680026012802D1AE600AF086
+:1025C000F1F86868012800D16E6028680127544C32
+:1025D000012812D12E606079002803D000200AF073
+:1025E000E1F866712078002807D00AF003F9002886
+:1025F00003D0012080070761A770286901282AD12C
+:102600002E6100F05FF8012080074761A079002863
+:1026100015D00AF0EFF800900AF04CF80099002964
+:1026200001D0E16800E0A168411A022901DA8A1CA0
+:1026300011DC0099002901D0E06000E0A060FFF704
+:10264000C3FE0AF0D7F8002804D0012080070761F4
+:10265000A77000E02770E868012812D100F032F876
+:1026600000F030F800F02EF8A078002804D1FF2008
+:102670002DA1033018F06FFDEE60A6702670FFF7F5
+:10268000CCFEF8BD10B5264CE078002801D10AF048
+:10269000ADF801208107886100F014F8A0780028C7
+:1026A0000BD0254CE068002803D10AF0B8F80028C8
+:1026B000F8D10020E06000F005F800201949C0437F
+:1026C000886010BD08B55020694608806A461088A9
+:1026D000411E1180FAD208BDF8B51248192787604B
+:1026E000154900200860C8600AF084F8BE0701247C
+:1026F0000B4D002802D03461AC7000E02C70FFF765
+:1027000063FE084847600D4928798863FFF7DAFFC0
+:10271000B461FFF7D7FF0849002008617461F8BD74
+:1027200038000020000300407372635C736F635FC6
+:10273000636C6F636B2E6300000100400005004076
+:1027400000ED00E0FFFFFF7F8107C90E002808DAD7
+:102750000007000F083880082E4A80008018C069E2
+:1027600004E080082C4A800080180068C8400006F9
+:10277000800F704710B50D20FFF7E6FFC4B20420AC
+:10278000C043FFF7E1FFC0B2844203D023A11A2067
+:1027900018F0E1FC26490120486010BD0121254ABE
+:1027A00048031060244B00221A60244A5160244AD6
+:1027B0001060244A11601F49803908607047012168
+:1027C0001C4A480310601F4A51601B4A00211160D7
+:1027D0001B490860704710B517490868012804D0E4
+:1027E0000EA1572018F0B7FC10BD114880680022D8
+:1027F000C0B20A6009F0BEFC10BD10B50E480168F9
+:102800000029FCD0FFF7E7FF01200D4940030860D5
+:1028100010BD000000ED00E000E400E07372635CB6
+:10282000736F635F68616C5F726E672E6300000098
+:1028300000D5004080E100E000D1004000D300401E
+:1028400080E200E000D0004030B40121BC48C90261
+:102850000160CD1005604A030260BA4803681B029C
+:102860001B0A036004680023240A24020460B6489B
+:102870000468240A24020460B4480124446084608B
+:10288000B34C23606360A360B24B19601D601A6093
+:10289000B14B19601A600121016030BC704710B45F
+:1028A0000121A748CA0202600B0203600C06046003
+:1028B000A64841608160A94841680029FCD1A4492B
+:1028C0000020086048608860A248026003600460DD
+:1028D00010BC704701219F48C9020160C910016006
+:1028E0007047002805D0012805D0022805D19C4852
+:1028F00070479C4870479C48704710B59BA18B203F
+:1029000018F029FC002010BD70B500219E4C9F4D91
+:102910009F4A8F4B002808D001281DD0022822D0C2
+:1029200092A1B32018F017FC70BD01200004A06034
+:10293000A86011601960974BC2039A60964A906034
+:102940007F4A0012106095480160864801609448F3
+:1029500001609448017070BD01204004A060A8602F
+:102960005160596070BD01208004A060A860916032
+:10297000996070BDF8B59446834A8B4F834D00240F
+:102980000126002808D0012832D0022840D077A1A3
+:10299000E82018F0E0FBF8BD891E0902090A0120B1
+:1029A000000490603C6468606C4A1164012B1DD087
+:1029B00000217C4A7D4B51706146DC63DE637C4BB9
+:1029C0005C6002249C6004241C61744B3D311960DE
+:1029D00073490E605F4B891519606F4B58605E48F4
+:1029E00001606C49C00548601670F8BD0121E0E740
+:1029F0000120704E4004704F012B04D134645060AC
+:102A000068603964F8BD9060346468603964F8BD0A
+:102A100001206A4E80046A4F012BF4D1EEE74F4843
+:102A20004068704770B54A4D28680026564C01280A
+:102A300006D1A068C00303D501200004A0602E6069
+:102A40006868012809D1A068800306D501204004E8
+:102A5000A0606E6001200AF0B9FEA868012809D1C3
+:102A6000A068400306D501208004A060AE6002206B
+:102A70000AF0ACFE70BD10B54A490878002818D09D
+:102A80000120444AC0079060434AC00B90602C4A22
+:102A900000121060414A00201060324A1060404A23
+:102AA000106008704A78002A02D048700AF08EFE42
+:102AB00010BD0320FAE70120424900060860704774
+:102AC0000120244900060860704701203D49400567
+:102AD0000860704701201F4940050860704733496E
+:102AE0000020C86388151B4908607047410A364AB0
+:102AF000C005C00D5043801C5143400A0818704760
+:102B000010B4324C430B63431B0C5C020C602E4C24
+:102B10006343C31A2E485C0258432B4B400D43437A
+:102B2000E31A0124DB0324041B191B1613700A6823
+:102B30001018086010BC704710B50AF01BFF10BDDC
+:102B400080E100E008E400E018E400E000B00040AC
+:102B500040B1004080E200E000E100E000B500404C
+:102B600048B100404081004044B100407372635C52
+:102B700072656D5F68616C5F6576656E745F7469C0
+:102B80006D65722E6300000000B3004040B300404A
+:102B900040B5004000F50140008300404085004002
+:102BA000008200404800002000B10040C08F00407B
+:102BB0000085004004B1004004B5004008B1004069
+:102BC00008B5004000E200E0093D00003786000043
+:102BD0006F0C010010B50AF0B9FE10BD00200449C9
+:102BE000C863012001218140024A116000BF704783
+:102BF000C01F004080E200E010B50DF05DF909F063
+:102C0000F7F9FEF7C3FB0FF0F5FA0DF08FFF0DF0AB
+:102C10001BFF10BD70B50C46054603F0A7FA214610
+:102C200028460EF0C2FF70BD70B50D46040012D0EC
+:102C3000002D10D02101284618F060F910225449C7
+:102C4000284618F0FEF852480121083801804480D7
+:102C50004560002070BD012070BD70B54C4E002451
+:102C60000546083E11E0716820014018817BAA7B6F
+:102C7000914209D1C17BEA7B914205D10C222946C0
+:102C800018F0B2F8002806D0641C30888442EADBD1
+:102C90000020C04370BD204670BD70B50D460600D3
+:102CA0000AD0002D08D03A4C083C20886188401C8E
+:102CB000884203D9042070BD102070BD3046FFF754
+:102CC000CCFF002801DB401C0AE02088616800017D
+:102CD00040181022314618F0B4F82088401C20809B
+:102CE0002870002070BD70B514460D001FD0002C58
+:102CF0001DD00021A170022802D0102817D108E0B1
+:102D0000687829780002084311D00121A170108051
+:102D10000BE02846FFF7A1FF002808DB401CA0704D
+:102D2000687B297B000208432080002070BD0120C1
+:102D300070BD70B5054614460E000AD000203070F4
+:102D4000A878012807D004D9114908390A88904287
+:102D50000BD9012070BD002C04D028782070288861
+:102D6000000A50700220087010E0002C0CD0496856
+:102D70000001411810222046103918F062F8287816
+:102D800020732888000A607310203070002070BD06
+:102D9000540000205A4910B5884207D30121890404
+:102DA000884205D357490968884201D2102010BDD6
+:102DB0000146012005F0CBF810BD30B5044693B0B4
+:102DC00000200D46079014210BA818F099F81C213B
+:102DD000684618F095F86A46112010770020507761
+:102DE000107802210843107007A80C90012008AA4F
+:102DF000907245486A4610850AA80B902088108476
+:102E000060885084A0889084E088D084907FF921E5
+:102E10000840801C4008400090770820908610876A
+:102E200008A80F9010AA0BA9684600F05CFF0028C4
+:102E300003D110A800882880002013B030BD3EB513
+:102E400004460820694608802D48844207D30120A3
+:102E50008004844205D32B480068844201D21020AC
+:102E60003EBD2146012005F072F80028F8D12088E7
+:102E7000694688806088C880A0880881E088488189
+:102E800005F065FE01AB6A46002101F0BBFB694617
+:102E900009880829E4D003203EBD1FB50446002060
+:102EA000029008206946088115480391844207D39F
+:102EB00001208004844206D312480068844202D272
+:102EC000102004B010BD05F042FE014602AA0F48D2
+:102ED00001F02EFD0028F4D169460989082901D0A6
+:102EE0000320EEE7694609882180694649886180A8
+:102EF00069468988A1806946C988E180E1E70000C8
+:102F000000C0010028000020042A0000FFFF00008C
+:102F100010B5031D03600020521E04E05C181C6005
+:102F2000401C2346C0B29042F8DB0020186010BD60
+:102F300001460A680020002A02D0104612680A6082
+:102F4000704702680A6001607047000010B50146D2
+:102F50002022094817F075FF07490020C877084666
+:102F600010BD0649012048610548064A01689142A2
+:102F700001D1002101607047B00E00200005004023
+:102F800064000020BEBAFECA0C4908784A78401C8A
+:102F9000C0B2904200D008707047094A074820BF6D
+:102FA00040BF20BF4178037843701368002B02D1E3
+:102FB00003788B42F3D00020704700006B000020A4
+:102FC00000E200E00A4A022151600A490B68002B26
+:102FD000FCD0906008680028FCD000205060086891
+:102FE0000028FCD0704701200007406970470000AE
+:102FF00000E5014000E401407047704770477047AA
+:1030000010FFFFFFDBE5B15100C001006700FFFFCB
+:1030100003B40148019001BD09000020002803D03D
+:103020008178012939D101E0102070470188FE4ADA
+:10303000881A914233D01BDCFC4A881A91422ED068
+:103040000BDC00292BD00320C002081A27D001284E
+:1030500025D001210903401A07E001281FD00228CA
+:103060001DD0FF281BD0FF380138002815D116E0ED
+:10307000FF220132811A904211D008DC01280ED0C3
+:1030800002280CD0FE280AD0FF2806D107E001292B
+:1030900005D0022903D0032901D0002070470F205A
+:1030A000704700B50B2826D009DC030018F074F92E
+:1030B0000B1D2125251B25292325271F1B00112832
+:1030C0001BD008DC0C2816D00D281CD00F2814D0DB
+:1030D000102808D10FE0822809D084280FD0852835
+:1030E0000FD0872811D0032000BD002000BD05208F
+:1030F00000BDCF4800BD072000BD0F2000BD04204B
+:1031000000BD062000BD0C2000BD0D20800200BDCA
+:1031100070B500290BD0CB1FFA3B81241E46CDB2DF
+:10312000112B1BD2012805D0022806D009E000206F
+:1031300010701DE0FF20043001E0FF2003308142C9
+:1031400018D0330018F028F9111613131613161699
+:103150001316161613131313161316000846FF380A
+:1031600081381F2803D9FF39FE39022902D815708A
+:10317000002070BD1470072070BD00B5030018F06A
+:103180000BF9060406040C080A0C002000BD1120EF
+:1031900000BD072000BD082000BD032000BD007851
+:1031A0000207120F04D0012A05D0022A0AD10EE02C
+:1031B000000907D108E00009012805D0022803D042
+:1031C000032801D0072070470870002070470620B0
+:1031D0007047002807D0012807D0022807D003280D
+:1031E00007D007207047002004E0112002E02120D2
+:1031F00000E0312008700020704738B50C4605000B
+:103200004FD06946FFF7CBFF002822D12088032149
+:1032100089028843694609788907090D0843208097
+:103220006946681CFFF7BBFF002812D121880320E4
+:1032300000038143684600788007800C01432180A9
+:10324000A8784007820F2020012A03D0022A03D049
+:10325000072038BD814300E00143218088B2010589
+:10326000890F08D0012189038843A9780907C90F6C
+:1032700089030843208080B28104890F0AD0A9788D
+:103280004004C906C90F400CC903084320808004CC
+:10329000800F02D12088400403D5208840210843B4
+:1032A0002080002038BD70B50446002008801546F7
+:1032B0006068FFF7A2FF002815D12189A08981420B
+:1032C00010D861688978C90708D00121490288426D
+:1032D00008D8491C17F01EFE298009E0FF21FF31A4
+:1032E000884201D90C2070BDFF30FF3003302880A8
+:1032F000002070BD10B5137804785B08E4075B000C
+:10330000E40F23431370FD2423400478A407E40F43
+:10331000640023431370FB24234004786407E40F04
+:10332000A40023431370F724234004782407E40FF8
+:10333000E40023431370EF2423400478E406E40FF1
+:10334000240123431370DF2423400478A406E40FF0
+:103350006401234313700078BF244006C00F23404C
+:10336000800103431370002906D00878C10701D1FA
+:10337000800701D5012000E00020C0015906490E58
+:103380000843107010BD30B50A8803239B020488DF
+:103390009A4323059D0F02D1A3049C0F01D09B0FDC
+:1033A00000E001239B021A4303230A801B039A4374
+:1033B00003889804840F02D11805830F01D0800F71
+:1033C00000E00120000302430A8030BDF3B593B052
+:1033D0000D000FD0139800280FD01221284617F0A7
+:1033E0008DFD03AAFF21012003F0D5F80024264615
+:1033F00037467AE0102015B0F0BD0720FBE768469D
+:10340000807D01280BD16846818A0520C002081AF8
+:1034100010D0012810D0022812D0032812D0042C7A
+:1034200014D0052C15D113E002290000012800005A
+:1034300003300000012400E002246846468A08E0C8
+:10344000032406E068460424478A02E0052400E0DD
+:1034500006246846418A1398814246D12C74002E76
+:1034600041D00DAA0EA905200292019100901023CF
+:103470000022FF21304603F02FF9002823D16846AF
+:10348000808E2A46C0B20EA9FFF72DFC00281AD163
+:10349000AE81002F27D00DA9052008AE0291009023
+:1034A000132300220196FF21384603F015F9002866
+:1034B00009D16846808EF11CC01EC0B22A1DFFF7DC
+:1034C00012FC002801D0032095E708A881784278F3
+:1034D00008021043E881062C05D16846807DA87259
+:1034E0006846808A2881002085E703A803F05CF8FD
+:1034F000002884D0FFF7D5FD7DE7002805D0FE4ADF
+:10350000012903D0022903D003207047518800E02D
+:103510009188814201D1002070470720704770B523
+:103520000C4605461C21204617F0E8FC00202080B0
+:10353000002D08D0012D04D0F0A1F54817F00BFEA6
+:1035400070BD062000E00520A07070BD70B592B07F
+:103550001546064601206A461071107453740846D9
+:1035600008300395029048889082FEF7FBF904002A
+:1035700019D06580172069468883203600940AABED
+:103580007178023307AA01A80EF017F90646607891
+:10359000000701D5FEF7C7F9002E0AD03046FFF725
+:1035A000ECFD12B070BD1321284605F00EFF03207C
+:1035B000F7E708A800906846838B0422012128467B
+:1035C00007F0B3FEEDE770B506468AB000200D4661
+:1035D00007900590069003A90490052402460291E5
+:1035E0000190102300942946304603F075F8002816
+:1035F0000DD108A804A9009102900194684683891E
+:1036000000222946304602F083FE002801D0FFF751
+:1036100048FD0AB070BD10B50EF0D5FA10BDF0B57A
+:1036200089B000260546059600780C460827030059
+:1036300017F0B2FE0CFD070C390B75759BBEFCD361
+:10364000E3FD68680A38FEF702FB07E1A88800225C
+:1036500080B20421009008F067FB0290002C04D097
+:10366000AB48A6A16E3017F076FD0298002804D171
+:10367000A748A2A16F3017F06EFD0298009908309C
+:103680000DF0D0FCFEF76EF9040007D060783843E7
+:10369000607000986080FEF746F9E1E01321009821
+:1036A00005F093FEEAE0002C04D1BD2093A1800038
+:1036B00017F051FD60880022042108F035FB0090CE
+:1036C000002804D192488DA1883017F044FD00995C
+:1036D000002008802A7994461EE0C3005B199B688D
+:1036E00007936B469B8B1A0708D5DA0606D560460A
+:1036F000C20050194038C08F088006E05B0409D52D
+:103700000871C2005019C0884880607838436070E2
+:103710000226A3E0401CC0B28445DED89EE0E888C3
+:10372000694608800090002C04D1794873A1983034
+:1037300017F011FD2878062813D10098C00B10D07F
+:1037400060880022042108F0EFFA060004D17048D6
+:103750006AA1A23017F0FFFC00203071A8887080A9
+:1037600039E060783843607078E0002C04D1684814
+:1037700062A1B43017F0EFFC60880022042108F049
+:10378000D3FA0090002804D161485CA1B73017F04B
+:10379000E2FC009808300EF068FA0121484002D19E
+:1037A000E888C00B5AD0009861880226C180D8E70B
+:1037B000002C04D1564851A1D03017F0CCFC6088C1
+:1037C0000022042108F0B0FA002804D150484BA18F
+:1037D000D33017F0C0FC0226C3E7002C04D14C48BC
+:1037E00046A1DC3017F0B7FC022661880122204692
+:1037F000FEF73EFA01200590B3E7A889002280B2C7
+:103800000421009008F090FA0746002C04D04048AC
+:103810003AA1EE3017F09FFC002F04D13C4837A1AD
+:10382000EF3017F098FC6868029001E009E010E0C2
+:10383000288969468881012202A90098FEF734FA96
+:103840000CE0002C8DD16D202CA1C00017F083FC62
+:1038500087E72F4829A1FE3017F07DFC002C0DD002
+:10386000607800070AD50598002807D184202070C9
+:103870002046582229460830FDF7A6FC304609B0FC
+:10388000F0BDF7B50C460546007A224688B00A32EC
+:103890000492921C01920027811E16323E4602922B
+:1038A0000B0017F079FD08F405F348488ED0F2F3C9
+:1038B00068880022042108F037FA0190002803D11B
+:1038C0000EA1144817F047FC01980088002802D088
+:1038D0005227072600E151271E26002C70D0688849
+:1038E000A0800120A071019804990079C0004019BE
+:1038F000C089FFF76BFD0FE0400C00207372635C22
+:1039000067617474735F636F72652E6300000000FB
+:103910006F0200008603000000287DD10198007925
+:10392000C0004019C089208101980079C000401969
+:10393000408AA083F0E0698A0091062820D1E889B6
+:10394000C00B1DD008462230512786B2002CC5D0AE
+:10395000A8890199FFF73AFD002872D16888A080F4
+:103960000220A071A88920810120A072288AE0830A
+:10397000009820846969009A029817F062FACBE0F7
+:1039800008462030502786B2002CA7D0A889049979
+:10399000FFF71CFD002854D16888A080A889E0802A
+:1039A000287A06280AD002202072288AA08300984C
+:1039B000E083204669692030009ADEE70120F3E7C2
+:1039C0008FE068880022042108F0AEF90690688A2A
+:1039D00000900698002803D1FD49FE4817F0BBFB74
+:1039E000069808300EF041F90121484002D1E889DB
+:1039F000C00B25D000985127223086B2002C7AD0F7
+:103A00006888A080A8890199FFF7E0FC002818D1F8
+:103A10000220A071A88900E013E020810420A07298
+:103A2000288AE083009820846969009A029817F038
+:103A300008FA0699002008710698A98941806BE070
+:103A400003200BB0F0BD688804F0DDF900906888B1
+:103A50000022042108F068F901900098002804D1A0
+:103A6000DC48DB492C3017F076FB0198002804D1A4
+:103A7000D848D7492D3017F06EFB0198D649C08839
+:103A8000884205D05127222604E01EE03FE035E0C1
+:103A900050272026002C2ED06888A080502F07D0D9
+:103AA0000220A0712146287B0831FFF738FD33E062
+:103AB000287BA11DFFF733FD6A8800230199009838
+:103AC000FFF744FD0028BCD126E0C449A889C98875
+:103AD000814207D154270626002C0CD06888A0808C
+:103AE0001AE008E053270826002C04D06888A0803C
+:103AF000A889E08010E00A98068013E05527072681
+:103B0000002CF8D0A889A0800020A07104E08D20AE
+:103B1000AF49C00017F01FFB0A98002C068001D0A7
+:103B20002780668000208CE7AC4900200870704731
+:103B300030B585B00C4601F0DBF90546FF2804D10D
+:103B4000A448A349953017F006FB0020208020717F
+:103B50006080401EE0802046294608300DF056FA6D
+:103B60006A462946012002F016FD102412E068463C
+:103B7000808800070ED56846C0882946FFF723FDD8
+:103B800068468188FF2321438180C0882946019AA5
+:103B900002F02CFE684602F007FD0028E7D005B0D1
+:103BA00030BD0A46014610B5104608300DF042FA05
+:103BB00010BD70B505460022042108F0B5F80400D8
+:103BC00004D184488249B73017F0C5FA2046294607
+:103BD00008300DF027FA70BDF0B591B00C460746DD
+:103BE00004F011F9050005D02878222804D2082015
+:103BF00011B0F0BD7A48FBE700220421384608F0F6
+:103C000093F80646002C02D0A08800280CD0012092
+:103C1000694608710220087400204874002C05D001
+:103C2000A0880883206802E00920E1E70883059066
+:103C30003046083003970290FDF794FE040018D038
+:103C40006780172069468883203500940AAB69781D
+:103C5000023307AA01A80DF0B0FD05466078000701
+:103C600001D5FDF760FE002D09D02846FFF785FA43
+:103C7000BEE71321384605F0A8FB0320B8E708A8E3
+:103C800000906846838B04220121384607F04DFBE3
+:103C90000021C943F180ABE7FFB585B00E9E778860
+:103CA000384604F0B0F8054600220421384608F0F2
+:103CB0003BF80446002D03D145494A4817F04BFA1A
+:103CC000002C04D147484249401C17F044FA0834FC
+:103CD000089869460394C1C105A80DC820356978C4
+:103CE0000DF0DAF9CBE5F0B50446002099B00D46A9
+:103CF00001460D9010A88181164601818180374AC6
+:103D000068469180018510A80180684601878185F9
+:103D100081841078012808D0022806D0032804D016
+:103D2000042802D0082019B0F0BD2F4A944273D362
+:103D30002E4F0121890438688C4201D3844278D304
+:103D4000294A954275D3012189048D4201D38542C8
+:103D50006FD36168002913D0234A914269D30122AD
+:103D60009204914201D3814263D3608921898842C0
+:103D700003D801225202914201D90C20D3E70D90C1
+:103D800016AA0EA92846FFF78EFA0028CBD168683C
+:103D900080784007800F02280AD16846008F80048F
+:103DA000800F05D02869002802D03968884240D3A6
+:103DB0000AA92069FFF721FA0028B4D12069002858
+:103DC0001CD0607880076846008D14D580040FE011
+:103DD000FC380000EE030000FFFF0000400C002054
+:103DE000023000000C05000000C001002800002087
+:103DF000800F68D002E08004800F64D16846008D97
+:103E0000810618D58004800F606806D0002812D083
+:103E1000396888420DD302E00BE000280BD0FE4940
+:103E2000884206D301218904884204D33968884234
+:103E300001D2102077E709A96069FFF7DEF90028B1
+:103E40009CD16069002808D06846808C0105890FE4
+:103E5000012938D18004800F35D00BA9A069FFF764
+:103E6000CCF900288AD16846808C80062BD468461D
+:103E7000808D810627D4A169002906D00105890F0C
+:103E8000012920D18004800F1DD0E068002804D0D3
+:103E90000078002817D01C2815D204AA611C2046DF
+:103EA000FFF728FA0121890210A80180012768463E
+:103EB0008773DA49818104AA033217A92868FEF7BB
+:103EC00038FF002801D007202DE710A8007F15A992
+:103ED000C01CC2B200200C920190FF320090034639
+:103EE0000291FF3203A80332109902F0ACFA0028C5
+:103EF00026D110A9888A0F902A892969C84801917A
+:103F00000092029010A90A8B6B8928680E9902F022
+:103F10009AFA01007ED1C2480025001F81886846B8
+:103F20004174090A8174052104A86A4623C210A8B5
+:103F30002A46FF21808A0C9B02F0EAF9002802D071
+:103F4000FFF7AFF8EFE66846007C0322C1090020C6
+:103F5000920290430122920280181490002928D0E6
+:103F6000014610A8018068462921877309028181D2
+:103F7000058608A8007C0023410860784900C00736
+:103F8000C00F014308A80174FD2001406078A54AD4
+:103F90008007C00F4000014308A801740CA902204B
+:103FA00001910090029503A8109902F04CFA0100CB
+:103FB00030D16068002828D0206900280DD10AA9D6
+:103FC0000EA8FFF7E0F96078800706D46946088DEF
+:103FD0000321090388436946088590496846877329
+:103FE000FE3181818F492089891E16F093FF626816
+:103FF0000D9811AB0192009002930A46002303A88A
+:104000000A9902F020FA010004D12078C10603D4F5
+:10401000800600E085E02AD56846058660690028AC
+:104020000DD109A90EA8FFF7AEF96846818C0320CF
+:104030008002814301208002091868468184694614
+:10404000888CC82108436946888474488F73FF3080
+:10405000888112AA0CA902200292019100900023EB
+:10406000704A03A8099902F0EEF9010059D12078AD
+:10407000C00729D068460586A06900280DD10BA984
+:104080000EA8FFF780F96846818D032080028143E6
+:10409000012080020918684681856846818D40208C
+:1040A00001436846818587735F49818113AA0CA902
+:1040B000022002920191009000235A4A03A80B9912
+:1040C00002F0C1F901002CD1E06800282DD010A821
+:1040D00014990180544968468773491C8181E168BD
+:1040E00008A80A78027449784174E068412241883E
+:1040F00068464186E0680023017908A80175E068F8
+:10410000D200C18808A84175090A81750CA8072149
+:1041100001900091029503A8109902F094F9010012
+:1041200003D00F9800F0E8FEFDE53D480321001F95
+:104130000170002E0AD08088308010A8808870809E
+:1041400010A80089B08010A88089F0800020EAE5DE
+:1041500030B501248BB015460B46012802D0022849
+:104160001CD104E0684605218473C90203E02B4991
+:1041700068468473891E8181002B12D003210020A0
+:10418000890288430121890240186946888405AA6A
+:1041900004A91846FEF7CDFD002804D007200BB077
+:1041A00030BD1020FBE76A46127C1D480092801E3D
+:1041B00005A9FF3201910290FF32002303A80332C8
+:1041C000099902F040F9002802D0FEF76AFFE6E7FD
+:1041D0001348001F002D01D0418829800470002061
+:1041E000DDE770B592B00446012608A886700F4935
+:1041F0006846018410AA08A93046FFF7A9FF0028E5
+:104200004ED12078064DC00700242D1F002849D02C
+:104210001C2168460CE0000000C0010003280000DB
+:10422000440C0020030200000329000001180000D4
+:1042300016F066FE6846017820200143684601704A
+:1042400008A88670F9496846018411940794817F13
+:10425000F92001406846891C8177002001466846A4
+:104260000177002001466846417704218185C48595
+:10427000018607A80A9011A80D9008A809900EAA17
+:1042800009A96846FFF72FFD002809D16846008F6D
+:10429000E8806846808F2881401C68812C7000204F
+:1042A00012B070BDEC802C8110A80088F4E7F7B53F
+:1042B000DF4900260A789EB0012A04D0022A02D0E3
+:1042C000082021B0F0BD4A88824201D00620F8E7DC
+:1042D0001F98824201D10720F3E7012210A98A75B5
+:1042E000D4488882002003239B020146994393020D
+:1042F000CB1810A90B8669468A81CF4ACA8118A9B2
+:10430000887110A9888419A904916946CA82069007
+:10431000FF20087503A802F06AF900242546274605
+:1043200008AA052103A802F065F9002810D0822808
+:104330006FD1002C6FD0002D6DD010A88480C58067
+:104340000021017418A8807B11AC012865D06DE0B4
+:1043500008A88079002F21D0012857D16846818C88
+:10436000B44881421CD113AA0DA905206B4607C38E
+:104370006846408C10230022FF2102F0ADF900288E
+:1043800068D110A88089042801D006284CD168463D
+:10439000818E1F98814239D10F2092E7012835D1B3
+:1043A0006846808C0521C902884202D0491C884297
+:1043B0002CD19F4841886846408C814201D1012719
+:1043C00000E00027002C01D0002D10D01F9988425A
+:1043D0001CD113AB0DAA05216E460EC60446102350
+:1043E0000022FF2102F078F9002833D101E03546A0
+:1043F0000CE010A88089022801D0102814D1C0B286
+:104400001BAA0DA9FEF76FFC00280DD16846468C4B
+:1044100086E71FE0FFE7052053E714A91BA8221D2C
+:10442000FEF787FC002801D003204AE710A8007C93
+:104430000023001DC2B210A80274209802900194BB
+:10444000009215A81C9901F0FEFF002802D17849BE
+:1044500002220A70FEF725FE33E710B50B46401E18
+:1044600086B084B203AA00211846FEF743FF04AACF
+:10447000052103A802920191009001230022FF214F
+:10448000204601F045FF04466846008A012804D012
+:104490006D206A49000116F05EFE2046FEF701FE1F
+:1044A00006B010BDF0B5624F0446387887B00E46AE
+:1044B000032804D0042802D0082007B0F0BD04AAC5
+:1044C00003A92046FEF7EFFE0500F6D1606880786C
+:1044D0004007800F02280DD1684680898004800F34
+:1044E00008D02069002805D055490968884201D2C2
+:1044F0001020E2E7208905AA6B46216907C36946B7
+:104500000A8A63892068039901F09DFF002802D080
+:10451000FEF7C7FDD1E7002E02D06846808A3080C2
+:10452000042038702846C8E738B50C00054609D085
+:1045300000236A46FF2102F031F9002804D0FEF77B
+:10454000B0FD38BD102038BD69462046FEF755FE47
+:104550000028F8D1A078FF21C307DB0F2846009A76
+:1045600002F044F9EBE73EB50C0009D002AB6A4615
+:10457000FF2102F013F9002804D0FEF792FD3EBDA2
+:1045800010203EBD0321204616F0B8FC6846008886
+:1045900001A90005800FFEF71CFE00280BD168461C
+:1045A000007920706846008801A98004800FFEF71A
+:1045B00010FE002801D003203EBD684600796070DF
+:1045C000A278EF20024068460088C10B09010A4327
+:1045D000F7210A404104C90FC9000A43A270F9211A
+:1045E0000A40800601D5022000E001204000694613
+:1045F0000243097A50084000C907C90F0843A07058
+:1046000000203EBD7FB514460522019203AD029500
+:1046100000930A462388FF2101F07AFE69468989C2
+:104620002180FEF73EFD04B070BD0000052A0000A9
+:10463000400C002002280000FFFF0000FC380000B2
+:1046400028000020F3B5002799B068460C4607877C
+:104650003D4600291DD0E068002806D0A06800284B
+:1046600017D001886A4611870780199803F0CBFBA1
+:10467000002811D0007822287ED3199800F038FC49
+:10468000009000220421199807F04EFB060009D182
+:1046900004E010201BB0F0BDFC48FBE7FC49FD48DE
+:1046A00016F059FDA078012803D0022801D0072078
+:1046B000F0E72088002808D0401E80B203AA0099A5
+:1046C00001F069FF002859D11DE0F048401CE1E7E6
+:1046D0006946498A228891420BD26846807D00252E
+:1046E000012810D16846808AEB4988420BD1012508
+:1046F00009E0914203D1002D2AD06D1C01E0022D6A
+:104700000BD0032D04D203A801F04EFF0028DFD008
+:1047100082281BD0002831D11DE06946897D0129FE
+:10472000F1D16946DC4B8A8A5B1ED11A9A420FD0BE
+:1047300005DCDA48101A0BD00128E4D108E0012981
+:1047400006D0FF390129DED10325E1E7022D15D17D
+:104750000D2080029EE7E068002816D00EA90522F1
+:1047600002910192009069460B8FA2882088FF2158
+:1047700001F0CEFD002800E01DE002D0FEF791FC24
+:1047800088E76846A168008F08806846008AC006EE
+:1047900001D5C3487EE70798002803D06846008B00
+:1047A000022801D0032075E70798A1780078012935
+:1047B00003D0800710D408206CE7C007FBD000228C
+:1047C0000721199807F090F8002802D00725022049
+:1047D00004E0AE48801C5DE70225032008A90870AC
+:1047E000218868468185199808360A90099617210C
+:1047F0006846818712AB02330FAA052108A80097EB
+:104800000CF0DBFF002802D0FEF7B7FC42E710A84F
+:1048100000906846838F04222946199806F085FD8A
+:1048200038E770B5064615460C460846FEF7F6FB17
+:10483000002804D12A4621463046FFF789FCF3E6DA
+:1048400010B5FFF734FD10BD70B51E4614460D00BF
+:1048500014D0002C12D0616800290FD00121FEF77E
+:104860004CFE002809D12068FEF7D8FB002804D1AF
+:10487000324621462846FFF736FAD5E61020D3E621
+:1048800070B515460C000ED00221FEF736FE00284A
+:1048900008D12068FEF7C2FB002803D12946204634
+:1048A000FFF700FEC0E61020BEE6F8B506467D48DC
+:1048B0000D46016814468A4231D36068002808D04A
+:1048C000794A90422BD301229204904201D388422C
+:1048D00025D37648864204D0304603F094FA002867
+:1048E0000CD0304600F004FB0646284600F0BDFA26
+:1048F000002804D16068002802D012E06348F8BDA7
+:1049000000236A463146284601F048FF002802D0BD
+:10491000FEF7C7FBF8BD68460088800601D410206A
+:10492000F8BD6188224628466368FFF76BFEF8BD34
+:10493000F7B55C4E0746306886B01446824202D214
+:10494000102009B0F0BD384600F0D2FA05465748AD
+:10495000874201D0FF2D08D0002304AA29460798DA
+:1049600001F01CFF002826D101E04848E9E768462D
+:10497000008AC00601D54A48E3E703A90020029156
+:104980000527019000976288484B2946079801F057
+:10499000A3FE00280FD161683268914208D30191CB
+:1049A00002900097238862882946079801F094FEB8
+:1049B000694689892180FEF774FBC2E7002907D088
+:1049C0003B4B0A881B899A4202D83048401C7047EA
+:1049D00038E610B586B004236C46A382344BDC88DD
+:1049E000002C07D01B898B4201D2914204D9274861
+:1049F000401C55E5062053E56B4619825A8200217A
+:104A0000009101911C800221997005A9029104A9CD
+:104A100003916946FFF716FE42E5F3B50C4685B0F3
+:104A2000812069460873002C1AD0059803F0EBF931
+:104A3000070017D03878222868D3059800F058FA74
+:104A4000049000220121059806F04EFF00280BD0AB
+:104A500000220421059807F067F905000AD105E056
+:104A600010202AE5094828E5112026E508491148C3
+:104A700016F071FB284608300CF0F6FA064620784E
+:104A8000012819D0022838D0072016E5023000008E
+:104A9000FC380000E10800000328000000280000A6
+:104AA000013400002800002000C00100FFFF0000CA
+:104AB000400C0020840A0000A18803AAFEF728FB0E
+:104AC0000028CED1B00721D56846007B00281FD131
+:104AD000A079C0071CD0E068002205216B4607C3FF
+:104AE000638922896888049901F012FC6946087379
+:104AF00000280DD0FEF7D5FADFE4A18803AAFEF75F
+:104B000007FB0028ADD13420064201D10820D4E4AF
+:104B10006846037B29463846059AFEF717FDCCE424
+:104B2000FFB597B0002001901F4615460C460E4673
+:104B3000179803F068F9002804D00078222803D2DF
+:104B40000820A7E5F348A5E5B80801D00720A1E5AE
+:104B5000032F00D10027179800F0CAF90890002C05
+:104B60001BD0022D77D3EC48006884427CD36119B6
+:104B70000091012902D0491E814275D3AD1EAAB20F
+:104B80002146E6480DF0F0F800991E394A7F0B7F68
+:104B900011021943884267D1ADB2E148B90702D585
+:104BA0000189491C00E0012189B20091F90701D077
+:104BB000078900E0D94F03AA0899009801F0EBFC9F
+:104BC0000DE0F078B1780002084310284CD8019924
+:104BD000091D401880B20190A84245D82618002E21
+:104BE00060D0707831780002084300998842E8D399
+:104BF00058E06946098A0A0754D5002C3FD0019A2B
+:104C0000A618121D92B20992F278B37812021A43D2
+:104C10009446102A28D8099A6244AA4224D8727865
+:104C2000337812021A4390421ED1C8061ED5099845
+:104C30000AAA052120186B4607C370783178000254
+:104C4000084363460022089901F062FB002803D064
+:104C5000FEF727FA1EE507E0F078B1780002084376
+:104C60006946098D884201D00B2013E5F078B178B0
+:104C7000000208430999401880B2019006E0C90675
+:104C800004D50899FEF79FFC0028E3D16946088AFD
+:104C90001021884369460882488AFF23049A0899AC
+:104CA00001F0A4FD03A801F07FFC002803D16846B1
+:104CB000408AB8429DD900220421179807F034F8A1
+:104CC000040003D19749984816F045FA2088002837
+:104CD000C0D0012108A80170017300264673218805
+:104CE0006846018620460830099017980A90FCF71C
+:104CF00039FE05001BD01798688017206946888008
+:104D000010AB023301AA052108A800950CF055FD4F
+:104D100007466878000704D583488249223016F098
+:104D20001AFA002F09D03846FEF727FAB2E4132109
+:104D3000179804F04AFB0320ACE40EA800906846E4
+:104D4000838804220121179806F0EFFA00288CD1FD
+:104D500026809FE4F0B500248DB01F4615460E4610
+:104D6000002A04D0B90804D007200DB0F0BD1020EF
+:104D7000FBE7032F00D1002700F0BAF80390FF28CB
+:104D800004D06749B80703D5488902E06148ECE7D9
+:104D90000120FA0702D04989491E00E05F4906AAAE
+:104DA0008FB2039901F0F7FB38E06946898B090758
+:104DB00034D504AB05210022029300910192574B98
+:104DC000039901F089FC002821D1002E21D06A46E8
+:104DD000128A2988A2183019121D914234D36946CB
+:104DE000CA8B0270120A42700A8A8270120AC2705A
+:104DF00004A90522001D0092029101906946C88B0A
+:104E00000B8A0022039901F067FC002801D00320DF
+:104E1000ABE76846008A2018001D84B206A801F09E
+:104E2000C3FB002804D0822806D0FEF73AF99CE79D
+:104E30006846C08BB842B8D9002C07D0002E10D0DD
+:104E40002988A01C814203D20C208EE705208CE724
+:104E50002246314631480CF087FF31190870000AAC
+:104E60004870A41C2C8000207FE700B585B06946FF
+:104E7000FEF7ACFA00280AD16846007C030016F061
+:104E80008BFA08052F2F2F2F08080531032005B0B6
+:104E900000BD68468078012807D168460088032154
+:104EA000C902401A1CD001281AD06846807901280E
+:104EB00006D16846808815214902401A05280FD975
+:104EC0006846807A012811D16846018929200002AC
+:104ED000081A05D0022803D0032801D0042805D1E0
+:104EE0000F20D4E711A1164816F035F90020CEE7BF
+:104EF00010B506F00FFF10BD10B50C4601F01EFBFB
+:104F0000002803D009A10F4816F025F92046FEF726
+:104F1000C8F810BD0230000028000020FFFF00008C
+:104F2000400C0020FC3800003F0B00007372635CF3
+:104F300067617474735F636F72652E6300000000B5
+:104F400022020000BB060000F8B500780C461646A9
+:104F500010340E36069F022809D0032836D00528C3
+:104F60007ED0FF20F6A1E53016F0F5F8F8BDCD892A
+:104F70000A2068430E30188031203880002AF5D08E
+:104F8000087B9581801FC7B21AE020886168308055
+:104F900048780A7800021043F080C8788A780002C6
+:104FA00010433081B21C3846091DFDF79CFE002FCE
+:104FB00001D0002802D000203071708008340A36F9
+:104FC00028466D1EADB20028DFD1F8BDCD890A207C
+:104FD00068430E30188032203880002AF5D0087BD4
+:104FE0009581401FC7B243E0616822880878F2804B
+:104FF0003279C30752085200DB0F1A43FD231A40CF
+:105000008307DB0F5B001A43FB231A404307DB0FC8
+:105010009B001A43F7231A400307DB0FDB001A43F8
+:10502000EF231A40C306DB0F1B011A43DF231A408C
+:105030008306DB0F5B011A43BF231A404306DB0FD5
+:105040009B011A433271C00970718A784B78100243
+:105050001843308132463846C91CFDF744FE00E053
+:105060000CE0002802D00020B070308008340A36EE
+:1050700028466D1EADB20028B6D1F8BD087BCD899B
+:10508000801E86B2304608306843103018803420C5
+:105090003880002AF1D0174695811037E800D68174
+:1050A000C01900900DE02088388000987860324662
+:1050B0006168009815F0C5FE00980834801908371B
+:1050C000009028466D1EADB20028ECD1F8BDFFB5AA
+:1050D00081B00A9D1E460C46002A05D0607AFF303A
+:1050E0000130D080E089108101980E2700780300FC
+:1050F00016F052F90B7E0719293541536C787878F0
+:105100007E000092087B082805D0032803D091A1D7
+:10511000954816F020F8378030200FE000990020E5
+:10512000888105B0F0BD0092087B042804D08E4829
+:1051300088A1143016F00FF83780312028800098AD
+:105140000028EBD1EDE70092087B042804D09320DF
+:1051500080A1800015F0FFFF37803220EEE700923B
+:10516000087B022804D080487AA13A3015F0F3FF7A
+:1051700037803320E2E7087B1746042804D07A48BA
+:1051800074A14C3015F0E7FF1020308034202880C7
+:10519000002FC6D00020B88116E0207B17460528D6
+:1051A00006D0062804D070486AA1603015F0D3FFFD
+:1051B0001220308035202880002FB2D0E089B881BD
+:1051C0000020388201984088F881AAE70092087B85
+:1051D000072804D064485FA1713015F0BCFF378008
+:1051E0003620ABE733460095019800F00AFC98E7BB
+:1051F0002F2053A1000115F0AEFF92E770B50C46C9
+:10520000054602F000FE002804D00078222803D2D0
+:10521000082070BD554870BD00220521284606F0C3
+:1052200083FD2060002801D0002070BD032070BDE8
+:10523000FFB58BB00D4607461720694608850E98C6
+:1052400003261446002805D10EA93846FFF7D6FFDD
+:10525000002834D1002D0BD000220321384606F05F
+:1052600043FB002834D00E980078002830D108E0A5
+:105270002078092819D00F2823D031A13C4815F0F7
+:105280006AFF0E98A760801D03AA606002320AA917
+:10529000204600F00CFC002827D0030016F07CF814
+:1052A000071A182323211C1E23000726002231463B
+:1052B000384606F019FB0028E3D12C48801C0FB0BB
+:1052C000F0BD00220321384606F00EFB0028D8D19D
+:1052D0001120F4E70020F2E70820F0E72348401C03
+:1052E000EDE70720EBE70320E9E701A80090684617
+:1052F000038D04223146384606F017F80028DED127
+:10530000002DDCD00E990D70D9E730B587B01D4661
+:105310000C46002A11D0042369460B7013888B8138
+:105320005288CA81A2788A7422880A8200236A4637
+:105330002946FFF77DFF07B030BD1020FBE70000D6
+:105340007372635C67617474635F636F72652E630D
+:10535000000000007372635C67617474635F636F65
+:1053600072652E630000000025020000023000007C
+:105370004F030000F3B581B001980C460078082671
+:10538000030016F009F8125E46461B134A0A0A0A81
+:105390000A0A0A0A0A0A0A0A0A5E002C02D1F64917
+:1053A000F64808E06078304360703BE0002CF9D1AB
+:1053B000F248F149083015F0CEFEF3E701980022DB
+:1053C0008088052187B2384606F0AEFC0546002CE1
+:1053D00004D07520E849C00015F0BDFE002D04D1B1
+:1053E000E648E549143015F0B6FE3946A81D00F030
+:1053F00055FBFCF7B7FA040006D0607830436070C4
+:105400006780FCF790FA0FE01321384603F0DDFFC8
+:1054100015E0DA48D849283002E0D848D6492D307E
+:1054200015F099FE002C0AD06078000707D593206C
+:1054300020702046582208300199FBF7C5FE002055
+:10544000FEBDCE48CC493130EAE710B500210170ED
+:10545000801D00F020FB10BD0A4610B50146901DCE
+:1054600000F024FB10BD70B505460022052106F0B2
+:105470005BFC040004D1F920BF49800015F06BFEED
+:105480002946A01D00F00AFB70BDF7B5054684B0A3
+:105490000C4600206946088188806F8802460521F5
+:1054A000384606F041FC060004D1FD20B2498000D8
+:1054B00015F051FE002C03D0A7800020E080208151
+:1054C000297A20461230C91E142700900B0015F0CF
+:1054D00063FF0FFDFCFB3809A95E657A2FB2C9E9AD
+:1054E0009191FB003078012804D0A3497020143139
+:1054F00015F031FEA9896A46C8000E309080302030
+:105500001081002C13D0A18100200DE0C100327960
+:1055100009190A747288CA8182005319DA894A8289
+:105520001A8A401C8A8280B2A1898142EED8F1E0B9
+:1055300002A8009001AB22462946304600F02AFA24
+:10554000E8E03078042804D08B49BD20143115F0F0
+:1055500002FEA8890622014650436A460E3090801A
+:1055600033201081002CE2D0A18100200BE0062125
+:1055700041434F190919FA89CA81BA7C8A743A8A57
+:10558000401C0A8280B2A1898142F0D8C2E0307802
+:1055900006280BD078491431D72005E0307806284A
+:1055A00004D07549EB20143115F0D5FDE889694622
+:1055B0001230888035200881002CB8D0A989A181BB
+:1055C0007188E18126E03078072804D06A49FF20FD
+:1055D000143115F0C0FDA8896A4601460E3090804E
+:1055E00036201081002CA2D0A1812046AA890E303D
+:1055F000296954E0E8896946123080B238228880EF
+:105600000A81002C7ED0A989A181287A102807D090
+:105610000221A173E9892182EA89296900983EE083
+:105620000121F6E702A8009001AB22462946304648
+:10563000FFF78AFC6EE03078082805D04E49FF203D
+:105640001431EE3015F087FD6846372187800181DF
+:10565000002C5FD0A989A1810020608220820120D6
+:10566000A07357E03078092805D04349FF20143152
+:10567000FF3015F070FD288A694614308880372085
+:105680000881002C46D00421A173A989A181E98950
+:105690002182298A618220462A8A1430696915F09C
+:1056A000D0FB37E030780A2804D03349344814312D
+:1056B00015F051FD6846372187800181002C29D0E3
+:1056C0000521A173002002E01FE004E00DE0A081AD
+:1056D000208260821EE002A8009001AB224629468B
+:1056E0003046FFF7F4FC15E00CE00D206946392246
+:1056F00088800A81002C05D00120E08000202081D4
+:10570000207307E00699088019E01C481A49A43064
+:1057100015F021FD6846069980880880002C0ED07F
+:10572000684600892080684680886080287A03283F
+:1057300005D0102803D0112801D00020307000209F
+:1057400007B0F0BDF7B5568815460F4682B0002267
+:105750000521304606F0E8FA040004D1074806495E
+:10576000C43015F0F8FCA41D33462A46394600948F
+:10577000029800F022FBD4E440530000950300009F
+:1057800013020000F7B58CB00D46144607A90C981B
+:10579000FFF734FD002812D1B64E0127002C0FD0A0
+:1057A0000321684601701021818208A802460690F4
+:1057B000204605A9FDF7BDFA00280BD007207EE59D
+:1057C0000821684601708581C68105218774C90258
+:1057D00001820BE00798A178017121884180684619
+:1057E00005218774C90201828581C6810246012193
+:1057F000079B0C98FFF71CFD61E508B501236A467D
+:1058000093709D4B13800A4602236946FFF77DFD86
+:1058100008BD08B501236A469370974B5B1C138043
+:105820000A4603236946FFF770FD08BD00B587B03F
+:1058300000290CD002236A4613700B889381498893
+:10584000D18100230421FFF7F3FC07B000BD102035
+:10585000FBE710B5002903D00523FFF756FD10BD67
+:10586000072010BD70B588B00D461446064607A93E
+:10587000FFF7C4FC00280DD1002C0DD0062168468E
+:1058800001708581C481079B02465C8006213046F9
+:10589000FFF7CEFC08B070BD052168460170858118
+:1058A000F1E710B588B000290BD007246B461C70B7
+:1058B0009A81049100236A462146FFF7B9FC08B09B
+:1058C00010BD1020FBE770B50024172288B0002916
+:1058D00014D00D782B0015F05FFD06230505190483
+:1058E0001B231522D21E93B2CA88002A02D08E68CA
+:1058F000002E03D09A4203D90C20CBE71020C9E731
+:10590000042D05D08A88002A0AD101E00620C1E7CB
+:10591000012D11D0022D05D0042D18D0052D23D036
+:105920000720B7E709236A4613704B889381CB8819
+:10593000D381896804911DE00C236A4613704B885B
+:105940009381CB88D38189680824049112E00D23C8
+:105950006A4613704B8893818B88D381CB881382DE
+:1059600089680924059105E00E236A461370497879
+:1059700011730A2400232146FFF75AFC8AE700B579
+:1059800087B00F236A461370918100231946FFF7F1
+:105990004FFC5AE7FEB50078089D1C4616460F4698
+:1059A000012803D03549912015F0D5FBF889C000B6
+:1059B0000E30208030202880387B001FC0B201903C
+:1059C000002E1DD0F889B081002516E0E80084196A
+:1059D000C0190090224641690E320198FDF783F903
+:1059E000002802D000202074E08100986D1C008AFD
+:1059F00060820098ADB2408AA082B089A842E5D802
+:105A0000FEBD70B514461425049A1D8037231380FB
+:105A1000002C0ED0CA89A281002262820078082858
+:105A200008D0092810D00A2819D01449144815F0B4
+:105A300092FB70BD087B0C2804D011480F490C382C
+:105A400015F089FB012008E0087B0D2804D00C48E4
+:105A50000A49083815F07FFB0420A07370BD087B4D
+:105A60000E2804D006480549001F15F074FB0520D8
+:105A7000F3E70000FFFF000002280000545300007D
+:105A8000BB02000010B5FE4B586019721A80C900A5
+:105A900015F036FA10BD00210180704710B50022C4
+:105AA000D2430280032006F0A8FD10BD7047F0B578
+:105AB0000E460446017801208840F24999B008401A
+:105AC0000090616815460888EF4A904206D0009A17
+:105AD000002A06D0EB4A521E104202D0012019B013
+:105AE000F0BD009A10430880002D12D000202870CD
+:105AF0002178EA1C0027681C01920B0015F04CFC71
+:105B000010F30E16233A59616F3CB4B08AB8F2F123
+:105B1000F0F320780B28EBD00420E0E70221297075
+:105B2000A1890170090A4170032097E004212970BE
+:105B3000A1890170090A41700198E1890170090A7F
+:105B4000417005208AE006212970A1890170090AA7
+:105B500041700199E2890A70120A4A70218A017122
+:105B6000090A4171A28AE81DA16915F06AF9A08AA3
+:105B7000C01D73E0082129702178082901D1102166
+:105B80002970A1890170090A41700198E1890170A9
+:105B9000090A41700520308020466A1D02A9103094
+:105BA000FDF7C7F800287DD169463088097A40188A
+:105BB00054E00A212970A1890170090A417003206B
+:105BC0000BE00C212970A1890170090A417001982C
+:105BD000E1890170090A4170052030809CE0A089AC
+:105BE00084464000401C81B2308888425AD305293F
+:105BF00058D30E202870002008E0236942009B5AE9
+:105C0000521953701B0A401C937080B26045F4D344
+:105C10003180B9E09A48417A002973D0491E417217
+:105C2000217B4068C9004518A988286808224018C7
+:105C30000838216915F005F9022168460171002133
+:105C4000417128680390A98868460181002101A854
+:105C5000FFF790FB0020A880002E00D0308093E05A
+:105C60002978802211432970297840221143297014
+:105C700029788909890112312970A1890170090ADD
+:105C80004170E289E81C216915F0DBF8E089C01C4D
+:105C90003080287841063FD5C00975D0012168467B
+:105CA000017200E02CE0002141723188091D8181E0
+:105CB0000495E189019808180590001D0690704828
+:105CC000017A68460177002102A8FFF753FB0746D7
+:105CD00030880C303080022F06D0002F54D065E081
+:105CE0003DE033E01CE05EE065486946097F4268BC
+:105CF000CB00D218037A994202D29188002902D0AF
+:105D0000042753E02FE0417A491C41721560308826
+:105D100090800020308049E06168A089888033E06D
+:105D200029788909890116312970A1890170090A28
+:105D300041700198E1890170090A4170228A681D49
+:105D4000616915F07EF8208A401D46E728788009B1
+:105D5000800118302870207B687002207EE7606820
+:105D60000188090401D4052720E0C088A189884260
+:105D700001D006271AE01E202870012030806068BC
+:105D800001884904490C0180009800280ED03C4845
+:105D900000220088A1688300032006F087FB616869
+:105DA0002078887007E00020308003276068009921
+:105DB00002888A430280384691E6FFB59FB0289D4D
+:105DC0000E46002805D0172803D82A882E4B9A4261
+:105DD00002D1072023B0F0BD3278530601D4D20996
+:105DE00001D00820F6E700226B461A715A7114465A
+:105DF0003278431E1D939BB2189303AB1A939706F8
+:105E0000CB1CBF0E1B93821E711C3B0015F0C4FA05
+:105E1000209011EE66EE74EEB0EED4EEEDEEECEE08
+:105E2000EBEEEAEEE9EEEEEEE8EEE7EEE6EEE5EEBC
+:105E300090EE05287CD1042168460171A978017291
+:105E4000F078B2780102114368464181317941719D
+:105E500070788006800E0C282ED009DC801E03008E
+:105E600015F09AFA0919661C6621662466276600F1
+:105E700012282AD00ADC0E2821D01028DAD121E0FD
+:105E80004C0C0020FF710000FFFF000016281FD0FF
+:105E90001828CFD11FE02878800701E02878400734
+:105EA000002845DA45E128780007F9E72878C00698
+:105EB000F6E728788006F3E728784006F0E72878A8
+:105EC0000006EDE72888C005EAE72888C004E7E770
+:105ED00028888004E4E728884004E1E72A789207CC
+:105EE00026D50328A6D105206A461071487809787E
+:105EF0000002084310811CE129784907F0D50628E3
+:105F000016D3717890B2012902D0022992D101E012
+:105F1000022100E01021189106216A46117100212A
+:105F2000118102AF189AB11C0237921C1B921AE021
+:105F3000B3E04A780B7812021A433A80801E891C1B
+:105F40001790BA1C1A911898FCF7CDFE1A99189858
+:105F5000189A091817986B46801A1A8980B2521C31
+:105F60001A811B9ABF1D8242E3D9002886D1E0E046
+:105F700028780007B4D51D98694682B207200871B9
+:105F800000200881701C0A3111E0437807781B0259
+:105F90003B430B80C37887781B023B434B806F46A3
+:105FA0003B89121F5B1C001D92B23B81091D042A14
+:105FB000EBD2002A71D1BCE02978C9066DD5022840
+:105FC0006BD30820694608710020488170780872F8
+:105FD000844692B2B01C1A9919E089E090E07EE004
+:105FE00067E05BE030E025E019E013E0BCE04378D7
+:105FF00007781B023B430B80831C4B606346D21A1D
+:106000006F467B8960445B1C92B27B81083194456A
+:10601000EDD9CEE7287880063FD5092203E028781D
+:1060200040063AD50A2268460271AA880281189A67
+:10603000428107E0287800062FD50B206A461071B0
+:1060400018981081039174E02988C90525D5022884
+:1060500023D30C20694608710020488170780872AB
+:10606000844692B2B01C1A9914E0437807781B0258
+:106070003B430B80C37887781B023B434B80031D57
+:106080004B606346D21A6F467B8960445B1C92B2B8
+:106090007B8108319445E8D98BE763E02988C904FE
+:1060A00060D501285ED10D2168460171A988018162
+:1060B0003FE02988890455D5052853D30E22694627
+:1060C0000A71AA880A811B99401F4A78097812022E
+:1060D0000A4369464A818881701D049029E0298815
+:1060E00049043FD501283DD10F206946087120E0C1
+:1060F0002A88120436D44A780B7812021A43EA80AE
+:1061000003282FD332789206920E1B2A26D0112212
+:106110006B461A712A880123DB031A432A804A78C6
+:10612000097812020A4369460A81C01E48811B98F9
+:10613000039030788006800E1B2809D01D2807D0D8
+:106140000320229906F059FA2888C00BC003288042
+:1061500001A82199FFF70EF920463BE610226B4675
+:106160001A71DCE70724F7E70824F5E700B597B0D4
+:10617000032806D16A461070019100216846FFF796
+:10618000F9F817B000BD000010B58B78002B11D0C6
+:1061900082789A4207D10B88002B0BD003E08B79D1
+:1061A000091D002B08D08B789A42F8D103880C88FF
+:1061B000A342F4D1002010BD812010BD052826D0B7
+:1061C000002A02D0012A0DD102E00988090501E068
+:1061D00009888904890F07D0012918D0022909D01C
+:1061E00003290ED081207047002A01D00320704778
+:1061F0000220704703280AD0042808D0002804D0C1
+:1062000007E0042803D0022803D0052070470020AF
+:1062100070470F20704770B51388054614460B80F1
+:1062200018061DD5FE481022807AA84203D81343D1
+:106230000B80002070BDA06893430078E840C00741
+:10624000C00E03430B802078A1788007800D08439F
+:10625000F44914F05FFEA06869430818401C70BD43
+:10626000906870BD37B569468B88138019061BD5B9
+:10627000EB4C0125A47A9168844209D8FE280FD1FD
+:10628000D80602D5A5406D1E00E000250D7007E080
+:1062900085400C78DB06DB0FAC4383401C430C705D
+:1062A00010881021884310803EBDF8B50746C81CF1
+:1062B00080080E468000B04201D08620F8BD082A32
+:1062C00001D90E20F8BDD64D00202E60AF80288168
+:1062D000AA723446E88016E0E988491CE980810604
+:1062E00010D48007A178800D0843CE4914F012FE27
+:1062F000206800F0BAFA2989401880B22881381A3B
+:106300008019A0600C3420884107E5D40020F8BD36
+:10631000FFB589B09F041646139DBF0C01930998E1
+:1063200000F095FA04000AD02078000609D5BC4890
+:10633000817A0A98814204D887200DB0F0BD0120EF
+:10634000FBE7224669460A98FFF765FF06900020A2
+:1063500069460872052D14D0012221462846FFF710
+:106360002DFF0028E9D1207840060AD50221684691
+:106370000172099981810188C18106824782129840
+:1063800005900198000404D500273E460125079793
+:1063900009E02078A1788007800D0843A149079083
+:1063A00014F0B8FD0D46019840040AD50798A8429C
+:1063B00007D12088E1788005800F00020843B042B1
+:1063C00001D3AE4201D90720B7E7B81980B20190D6
+:1063D000A84201D90D20B0E76846007A002804D011
+:1063E00002A8FDF718F90028A7D10798A8420BD1F9
+:1063F000208803210902884301998905890F090230
+:10640000084320800198E0701498002800D007808D
+:106410001298002815D006983A468019129914F05F
+:1064200010FD224669460A98FFF7F5FE694608887E
+:106430001021884369460880224600990A98FFF790
+:1064400011FF002079E7FFB5754D0C22E888296817
+:10645000504383B00C180D9F7249059814F05AFDF3
+:106460000091049800F001FA29682A898E46611A81
+:106470000C310918944651188AB2A988914202D861
+:10648000842007B0F0BD6A46168A320603D5B206EC
+:1064900001D58520F5E7EA88521C92B2EA800E9B6E
+:1064A000002B00D01A80B20601D5A76006E0604438
+:1064B00080B22881091A70460818A0602246FE2082
+:1064C0000499FFF7CFFE0598A0700098E07020882F
+:1064D0000599800889058000890F08430321090276
+:1064E000884300998905890F09020843042108435C
+:1064F000208003988078A07103980088A0800020F5
+:106500002073310601D5AC7A00E00124B10600D534
+:10651000002700260EE0052100200191029000973F
+:10652000E88831460C9B069AFFF7F2FE0028A8D1B6
+:10653000761CF6B2A642EED30020A2E7F1B5009891
+:1065400000F085F9060002D00025009C14E001202F
+:10655000F8BD204600F07BF90746007831498007F6
+:10656000820DB878104314F0D5FC386800F07DF93E
+:106570004019641C85B2A4B22948C188601E8142BA
+:10658000E7DC00992648491EC1800189491B018129
+:1065900000203070F8BD002804D0401E108091709B
+:1065A000002070470120704710B5044601881C4840
+:1065B000C288914201D3822010BD00680C22514351
+:1065C00042189079A072908820811088D178800537
+:1065D000800F00020843A081A078211DFFF71BFE59
+:1065E00020612088401C2080E080002010BD012117
+:1065F00001827047F7B50546002084B0C043108083
+:1066000068681746817868468170686801886846BE
+:10661000018000218171288A2C88A04205D303E0E3
+:10662000580C00200102000004462C8235E0288A24
+:10663000401C2882301D6968FFF7A6FD00282AD17A
+:1066400039889248814201D1601E38806888A04212
+:1066500028D33088F1788005800F0002084302902B
+:106660006946301DFFF790FD002814D169898748DD
+:1066700081421BD0002231460598FFF79FFD00287C
+:1066800009D16A890298824205D1E968B06814F09C
+:10669000ABFB00280AD0641CA4B2204600F0D7F857
+:1066A0000600C4D1641E2C828220EAE67C80B07988
+:1066B000B871B088B8803078B1788007800D084311
+:1066C00078810298B8813946287A32460831FFF736
+:1066D000A2FD38610020D4E6FFB585B01C460F4608
+:1066E000059800F0B4F8050009D02878000608D510
+:1066F0006748807AB84204D8872009B0F0BD0120ED
+:10670000FBE707982A468605B60D69463846FFF727
+:1067100082FD07460E98052816D000222946FFF76D
+:106720004DFD0028E9D1287840060DD501216846A5
+:10673000017105990181018841818681C48101A887
+:10674000FCF769FF0028D8D12888AA788107890D2D
+:1067500011438005800FEA7800021043079A9642A1
+:1067600007D04C4A914204D3611E814201DD0B20C7
+:10677000C3E7864201D90720BFE7801B82B2A2424D
+:1067800000D922461098002800D002800F980028D7
+:1067900002D0B91914F055FB0020AEE7F8B51D463C
+:1067A00017460E4600F053F8040008D02078000683
+:1067B00007D53748807AB04203D88720F8BD01203A
+:1067C000F8BD224639463046FFF725FD002D0BD097
+:1067D0002078A1788007800D08432E49884201D295
+:1067E000012000E0002028700020F8BDF8B51E460A
+:1067F00017460D4600F02BF8040008D0207800065C
+:1068000007D52348807AA84203D88720F8BD012005
+:10681000F8BD224639462846FFF724FDFF2E14D046
+:106820002588A178A807800D08431A4914F072FB47
+:10683000002E03D1FF31FF31033189B2A170A808C6
+:1068400080008905890F084320800020F8BD104989
+:10685000CA88824207D3002805D00C220968504319
+:106860000C38081870470020704703B50846694681
+:1068700009888A0607D4090604D50549897A41435F
+:10688000491C88B20CBD00200CBD0000FFFF0000B9
+:10689000580C002001020000F8B507780D460446A8
+:1068A000012F19D0072F02D00C2F19D114E0A068A6
+:1068B000216906780B2E0BD0052005F09EFE052ED3
+:1068C0000ED0782300220520216905F0EFFD07E0B6
+:1068D000782300220620F8E70520216905F08DFEC7
+:1068E000002D0ED0002028702946204603F0E2F942
+:1068F000FE482978C05D884201D10320F8BD0220FE
+:10690000F8BD0021204603F0D5F90020F8BD70B590
+:106910000E460C462036317901208AB015460029F2
+:1069200009D0012905D12978042902D10520107048
+:1069300000200AB070BD6068019005A802900D218A
+:10694000C01C14F0DBFA032205A8A16814F079FA40
+:1069500001203071062069460870206A049029469B
+:106960006846FFF799FFE4E770B50C4615462031FD
+:106970000A790120062686B0002A2CD0012A28D1C7
+:106980002978042925D169681022A06801F0B5F999
+:106990006868C07B000606D5D44AA0681023103A68
+:1069A000014601F09FF91022A168E06801F0A5F905
+:1069B000A068C07B000606D5CC4AE0681023103AD8
+:1069C000014601F08FF92E70A0686860E068A86049
+:1069D000002006B070BD60680190C4482038029065
+:1069E0000120087168460670206A049029466846AE
+:1069F000FFF752FFEDE7027B032A06D00022242393
+:106A00005A540B78092B02D003E0042070470A7611
+:106A1000CA61027B9300521C0273C150032070476D
+:106A2000F0B50E4615460C46203602463179012057
+:106A3000072393B000290CD0012924D002292ED09D
+:106A4000032904D12978042901D12B70002013B027
+:106A5000F0BD01203071606800280DD0A1690B7075
+:106A600060684860206988606069C860206A086260
+:106A70001046FFF7C0FFEAE706202870206968602B
+:106A80006069A86009E029780629E0D10220307108
+:106A9000042028709548203868600320D7E72978BB
+:106AA0000429D4D1A08910280AD9103880B2A08135
+:106AB000A1681023091805A86A6801F013F923E0FA
+:106AC00010282FD0C2B21020801AA1680DAF1190EB
+:106AD000C01914F0B6F911980006000E06D0401E39
+:106AE000C1B280207854384614F008FA6269102345
+:106AF0000DA909A801F0F6F8102309A905A86A68EC
+:106B000001F0F0F8032030716068019005A8029050
+:106B1000062069460870206A049029466846FFF7F7
+:106B2000BBFE94E710232269A168E2E7F0B50E46A8
+:106B30000C4620363179012006278FB015460029F2
+:106B40000BD0012932D0022905D12978042902D19C
+:106B50000820107000200FB0F0BD217D08A8CA07E2
+:106B6000D20F02718807C10F08A801716846027030
+:106B700041700722801CE16814F063F902A8072223
+:106B80000130216914F05DF9606805900AA806904B
+:106B900010236A46A16801F0A5F80120307168460B
+:106BA0000774206A0890294604A820E0297804295F
+:106BB000D1D1062205A8E16914F043F906A80622FE
+:106BC0000230A16914F03DF900200890606801903E
+:106BD00009A80290102305AA696801F083F8022031
+:106BE000307168460770206A049029466846FFF7AE
+:106BF00053FEB0E770B50D460C46203529790120CB
+:106C00008CB01646002909D0012905D13178042914
+:106C100002D10920107000200CB070BD6068019096
+:106C200006A802900822E16814F00BF9082208A8CF
+:106C3000A16814F006F90120287106206946087041
+:106C4000206A049031466846FFF726FEE4E770B5F7
+:106C50000D460C462035297901208CB016460029B6
+:106C600008D00129D8D131780429D5D10A20107053
+:106C70000020D1E76068019006A802900822A16870
+:106C800014F0DFF8002008900990012028710620F8
+:106C900069460870206A049031466846FFF7FCFD9B
+:106CA000BAE730B50B4620331C7901208BB0002C9D
+:106CB00009D0012C05D11178042902D10B201070C4
+:106CC00000200BB030BD4868019005A802908C6888
+:106CD00068462578057564784475CC68257885758F
+:106CE0006478C47500200690079001E0E4B30100C9
+:106CF000089001201871062368460370086A049002
+:106D000011466846FFF7C8FDDBE770B50C46203436
+:106D1000034625790120002D0AD0012D14D0022D23
+:106D200005D111780A2902D10C201070002070BD05
+:106D300001202071C868052202704A684260F84A42
+:106D40008260921CC2600BE015780B2DEFD10220FF
+:106D50002071C86804240470526842608A688260A6
+:106D6000096A016201461846FFF745FE70BD30B55D
+:106D7000011D02463132947803258379ED432C437B
+:106D800023408371DB070DD04B79547923404B713D
+:106D90000B79127913400B718278C9788A4200D935
+:106DA000817030BD00224A710A71F5E7F7B50C46D3
+:106DB00086B00020694626460870203631790127C2
+:106DC0001E2015461F2977D24B007B449B885B0011
+:106DD0009F441E0017023E025602690288029A0270
+:106DE000D102F5022E03590371037F03AE03C303DF
+:106DF000CC03F7031A0464049A04AB04DF04FE0412
+:106E000010052A0565059B05C605830587058B05C5
+:106E10006069002802D0007813287DD0A068059012
+:106E2000002849D0012168460170206A049003219E
+:106E3000684601710A214171E069029020790028B9
+:106E4000EFD0059909780029E7D00C2964D20B000E
+:106E500014F0A2FA0CFD1A4B90B5E8FCFBFAF9F815
+:106E600007FD022828D16069002802D00078082890
+:106E700052D1022168460170206A04900598417839
+:106E8000684601710021B9E20620216A05F0B5FBD0
+:106E900020790728E6D1606900F051FF02280CD064
+:106EA000606900F04CFF042807D060690028B8D062
+:106EB00000780128D6D103E01BE261690120087047
+:106EC00005980079C11F0A2901D30A2050E06169A1
+:106ED0000722887060690599303013F0B2FF0120F5
+:106EE000307161690320087034E00728BAD1606905
+:106EF000002896D001780929B4D10599C978890765
+:106F000007D1059949790029DFD1059989790029A7
+:106F1000DBD105994A7900E04EE2014620314B7DF4
+:106F20009A43D2D1059A8B7D92799A43CDD1059A15
+:106F30001279D31F0A2BC8D20979914236D8072279
+:106F4000C01C059913F07DFF0120307161690A2092
+:106F50000870032069460870206A04906069313027
+:106F600001906069001D029060691C300390A1E2ED
+:106F70002076F2E311288DD1606900F0E0FE04284C
+:106F800004D0606900F0DBFE0B2893D1606905999D
+:106F900010223730491C13F054FF6069017804292E
+:106FA0007CD12421095C8278914201D90620DFE757
+:106FB000052101700320307168460170E2E3112859
+:106FC00094D1606900F0BBFE062804D0606900F02F
+:106FD000B6FE0C288AD1E068002813D0206900286A
+:106FE00010D060690178062910D00D210170606908
+:106FF000059910225730491C13F023FF6069573060
+:1070000009218CE100206946087072E107210170B6
+:107010006069059910224730491C13F012FF60691E
+:107020004730EDE70228F0D1606900F088FE0028C3
+:10703000EBD0606900F083FE0128E6D0606900F0C3
+:107040007EFE05E0B1E08DE06CE02AE00AE0D6E0EB
+:107050000828DAD00521684601710598417868460C
+:10706000417146E11128D0D160690028CDD0017866
+:107070000E29CAD1C16A4078022810D000201422FB
+:1070800050431430085805991022491C13F0D9FEBA
+:107090000520216A00F041FE0F205EE0F1E10120B1
+:1070A000EDE70B28B1D160690028AED001780F2937
+:1070B000ABD1C16A4078022826D000201422504368
+:1070C0000C300958059842780A70807848706069D9
+:1070D000C16A4078022819D0002014225043103091
+:1070E000085805990822C91C13F0ABFE0520216A37
+:1070F00000F013FE60694178022909D000220832AD
+:10710000825C5208520073E00120D7E70120E4E7D7
+:107110000122F4E7012100E0002108314254BCE3E0
+:10712000BEB3010011289CD16069002899D0017874
+:10713000102996D1C16A4078022811D0002014226B
+:1071400050431830085805991022491C13F079FE55
+:107150000520216A00F0E1FD112061690870B4E3A7
+:107160000120ECE7082884D1606900289DD00178CF
+:10717000112997D10599C06A49780170606905990C
+:10718000C06A0622401C891C13F05BFE0520216AA0
+:1071900000F0C3FD60694178022904D00022083262
+:1071A000825CFD2323E00122F9E71128BBD160694D
+:1071B0000028BBD001781229B5D1C16A40780228D5
+:1071C00019D00020142250431C3008580599102271
+:1071D000491C13F036FE0520216A00F09EFD60690F
+:1071E0004178022909D000220832825CFB231A4030
+:1071F000022991D18EE70120E4E70122F4E707207C
+:10720000B6E6287801288ED16069696814221C309E
+:10721000F9F7DAFF6069017F002901D02176ACE33C
+:107220000178032901D0032037E00227C770817954
+:107230004907490F8171017A4907490F0172417A63
+:107240004907490F41726069FFF791FD377196E276
+:1072500028780F28E3D1072069460870216A049135
+:10726000916802916946087161690722C91C0298F8
+:1072700013F0E7FD61690420087000203071BBE065
+:1072800028780328CBD1606901780529696807D07F
+:107290000822473013F0D5FD0420307105206FE23D
+:1072A00008225730F6E728780328B8D160690178BA
+:1072B0000529696811D008224F3013F0C2FD05205E
+:1072C00030716069006A00280AD00220287000200E
+:1072D00028716069006AA860F9E008225F30ECE775
+:1072E00004204DE22878022899D12879002801D07D
+:1072F000207642E36069A96801626069002901D1D2
+:10730000F949016206200BE228780F2887D1A86886
+:10731000E0616069017805292BD047300721317180
+:10732000E16802220A706269126A4A6088606069D4
+:107330003030C8606069C01C08616269087D926A6B
+:10734000400812784000D207D20F104308756269D6
+:10735000926A521C8A61FD2210406269D26A1278D8
+:10736000D207920F104308756069C06A401CC8615B
+:1073700053E25730D2E728780828BAD160690178FB
+:1073800005291AD00B210170072069460870206A70
+:107390000490E069029011200871029803210170A5
+:1073A00051681022401C13F04CFD00216846FFF785
+:1073B00073FA00203071E06187E20621E3E7287864
+:1073C0000F2896D1072069460870206A0490A868A3
+:1073D00002901120087102980421017061690A78F5
+:1073E000072A0ED0002232710C220A706169102225
+:1073F000401C473113F025FD00216846FFF74CFA89
+:1074000063E21022401C573113F01BFD0021684637
+:10741000FFF742FA0A203071E168032008706069C2
+:10742000006A486060695730886060694730F3E1FE
+:1074300028780828A1D1606969681022373013F0D4
+:10744000D3FC002801D0042092E560690078072869
+:1074500017D00A203071E168032008706069006A63
+:10746000486060695730886060694730C860206A4A
+:1074700008620698FFF7BFFA07466069FFF777FCD6
+:107480006BE208207AE1287809289AD10B20307124
+:1074900061696868897810224018511A13F02EFD2E
+:1074A000082069460870206A049068680190606945
+:1074B0008078087268E129780D29BBD161698979E2
+:1074C000C90703D00C20307109203EE0307103273A
+:1074D00070E228780E28ADD160691422291D1C3075
+:1074E000F9F772FE6069018DC06A4172090A817202
+:1074F00060698178C06AC1716169CA6A081D117AC0
+:10750000C909C90111724379626919438378D26A42
+:107510009B079B0F012B00D0002300799B01C0002B
+:1075200003431943117260694078012876D0B4E1B1
+:1075300060694178022901D0012100E00021083171
+:10754000405CC00707D00E20EAE069460870206A58
+:107550001146049019E11320B8E728780F2894D138
+:10756000A868E0610F2030710520EEE72878032835
+:107570008BD16069C16A4078022801D0012000E007
+:10758000002014225043103008580822696813F074
+:1075900058FC10203071E16806202269087060698B
+:1075A000406A48606069C36A4078022801D00120BF
+:1075B00000E000201427784310301858CA60886013
+:1075C0002BE128780C2886D16069C26A40780228AD
+:1075D00001D0012000E00020142148430C30105855
+:1075E00002230932696800F07DFB11203071E168E7
+:1075F000052008706069006A48606069C06A0930E7
+:1076000088603948001F07E128780B28A7D16169F5
+:107610004878CA6A022802D0012001E059E100201E
+:1076200014235843143010588A78696813F009FC01
+:1076300060694178C26A022901D0012100E000217D
+:107640001423594314315258817850181022511A7A
+:1076500013F054FC072069460870206A0490E06922
+:107660000290112008710298062101706169CA6AAE
+:107670004978022901D0012100E000211423594357
+:10768000143151581022401C13F0DBFB00216846D6
+:10769000FFF702F90020E06112206FE028780F2840
+:1076A00091D1072168460170206A04909068029089
+:1076B0000B2268460271029801706169CA6A4978B2
+:1076C000022901D0012100E00021142359430C318B
+:1076D00051580A784270497881706169CA6A49785C
+:1076E000022903D0012102E0C4B3010000211423C8
+:1076F0005943103151580822C01C13F0A2FB00213D
+:107700006846FFF7C9F826E760694178022901D089
+:10771000012100E000210831405C800703D51420DE
+:1077200030710A2011E71620D0E628780F287AD188
+:10773000A868E061072069460870206A0490E06943
+:107740000290112008710298082101706169CA6ACB
+:107750004978022902D0012101E011E1002114231E
+:107760005943183151581022401C13F06AFB002174
+:107770006846FFF791F80020E061152030710A207B
+:1077800069460870206A049029466846FFF784F825
+:107790002BE028780F2846D1072069460870206A18
+:1077A00004909068029008200871029809210170E5
+:1077B00061690622C969097841706169801CC969DB
+:1077C000491C13F03EFB00216846FFF765F8AAE765
+:1077D00060694178022901D0012200E000220832CC
+:1077E000805C400703D51720C8E70746B5E00129AC
+:1077F00053D070E028780F2815D1A868E0611820D0
+:107800003071E168052008706069006A486060694D
+:10781000C06A09308860F848C860206A0862069823
+:10782000FFF7E9F8E1E76FE028780B286CD1606991
+:10783000C16A4078022801D0012000E00020142213
+:1078400050431C3008581022696813F0FAFA0720D8
+:1078500069460870206A0490E0690290112008715E
+:1078600002980A2101706169CA6A4978022901D027
+:10787000012100E00021142359431C3151581022EA
+:10788000401C13F0DEFA00216846FFF705F80020DF
+:10789000E0616069407801281DD1192016E6606911
+:1078A0004278022A09D000210831411809780029BC
+:1078B0000DD0CA0703D00E2106E00121F4E78907A5
+:1078C00001D5102100E012210170002772E0012A89
+:1078D00001D00D20FAE51C20F8E51D2030710B20A9
+:1078E00033E62978102948D1F0E56069017801294B
+:1078F00043D0082941D00021317100F01AFA0C2040
+:1079000069460870206A049037E028780F2805D06F
+:107910001020107003271B2030714BE007216846B0
+:107920000170206A0490A8680290022168460171E3
+:10793000029805210170217E417000216846FEF702
+:10794000ABFF0B2168460170206A04902946684607
+:10795000FEF7A2FF07461B203071012F0DD029E052
+:10796000012168460170206A049004216846017173
+:10797000217E41710020207612E0207E00280FD069
+:107980006169132008701A2030710A206946087056
+:10799000206A049029466846FEF77EFF074609E004
+:1079A0006069002801D01421017068460078002821
+:1079B00000D021E5384609B0F0BDF7B50F462037B5
+:1079C0003879012686B00C46002804D0012828D03A
+:1079D00002281CD197E02079012804D0022811D078
+:1079E000032814D10AE0A068407801280ED10620AF
+:1079F000216A04F0DCFD00287FD10CE0A16813208F
+:107A0000087008E0A0684178022901D0052674E0DA
+:107A10000078082871D1012038710A206946087061
+:107A200033E0089800780F2867D107216846017075
+:107A3000206A049008988568029522790220012A1C
+:107A400004D0022A29D0032A57D10FE006466846FF
+:107A500006710B202870207B00214007400F6870C2
+:107A60006846FEF719FFA068067045E006466846BE
+:107A7000067105202870207B687000216846FEF79B
+:107A80000BFF3E710B2168460170206A0490684626
+:107A90000899FEF701FF06462FE0684601710120B4
+:107AA0002870207C6870607CC007C00FA870A07C24
+:107AB0004007400FE870E17C2971C0071FD0207D8E
+:107AC0004007400F6871607D4007400FA87100219A
+:107AD0006846FEF7E1FEA06807222946303013F021
+:107AE000B0F9E068017AA06820300171A1682879B6
+:107AF0008870A16809200870002630465BE70020E6
+:107B0000A8716871E3E7A168142008700121684634
+:107B10000170206A0490042168460171217B417143
+:107B20000021FEF7B9FEE7E7F0B585B00F46054640
+:107B30000124287B800040198038C66F3078411EB0
+:107B40000A290AD22C498000323140188038C36F8C
+:107B50003A463146284698470446002C01D0012C6D
+:107B600011D1287B401E0006000E287301D003248B
+:107B7000DFE70D2069460870306A04900021019605
+:107B80006846FEF789FE032CD3D0204605B0F0BD31
+:107B900070B515460A46044629461046FFF7C4FF4D
+:107BA0000646002C0FD0207814280CD1207E002807
+:107BB00006D000202870204629460C30FFF7B4FF7D
+:107BC000204600F0B6F8304670BD704710B5012968
+:107BD00003D0022901D0052010BD417000F0A9F8A2
+:107BE000002010BD002809D0027E002A06D00A46D7
+:107BF00001460C31CCE70000C2B301000120704700
+:107C000030B5044687B00D46062004F0F6FC294640
+:107C1000052004F0F2FC2078142805D000206946E5
+:107C200008702046FFF7DEFF07B030BD7FB50E4677
+:107C300000216A4611730178092903D00A2903D06B
+:107C4000002407E0446900E08468002C02D0217E13
+:107C5000002912D0154601462846FEF7CCFE03281F
+:107C600009D1324629462046FFF792FF6946097B33
+:107C7000002900D0042004B070BD25460C35EAE789
+:107C800000B50023012285B005280CD0062808D1B4
+:107C90006846027004910221017143710021FEF7D0
+:107CA000FBFD05B000BD6846027004910271F4E767
+:107CB00010B590B00C4605216B4619700190234811
+:107CC00002900892001D03900AA96846FFF7AEFFD4
+:107CD000002805D1102220460B9913F0B2F800209D
+:107CE00010B010BD30B505E05B1EDBB2CC5CD55CDE
+:107CF0006C40C454002BF7D130BD10B5002409E00E
+:107D00000B78521E5B00234303700B78401CDC0988
+:107D1000D2B2491C002AF3D110BD70B50C460546FD
+:107D200004F06BFC782300222146284604F0BEFBB9
+:107D300070BD4178012900D00821017070470028EA
+:107D400001D000787047082070470000BCB30100E4
+:107D500070B5F84D040008D0012C10D0022C07D0CB
+:107D6000032C05D0F4A1752007E0F3A16C2004E0FA
+:107D70002878012803D0F0A1722013F0ECF92C70C0
+:107D800070BD70B5EB4D044610280AD0112C16D0EA
+:107D900028468178122C07D0132C0AD0E6A1A42003
+:107DA0000BE0E5A1992008E0112908D0E2A19E206E
+:107DB00003E0112903D0E0A1A12013F0CCF9AC70AD
+:107DC00070BD10B5DB4894B0007B002819D0172097
+:107DD00069460870D74900A806220D31023013F019
+:107DE00030F809A9684603F0A8FE0446112805D01A
+:107DF000002C03D0D0A1C02013F0ADF9204614B060
+:107E000010BD3220E4E710B50022022103F08CFF00
+:107E100010BDFFB595B01D460E460746FFF7F3FFB0
+:107E200004000AD02078222804D3A07F8006C00F47
+:107E3000A84204D1082019B0F0BDC348FBE73721A0
+:107E4000684601704780002D05D0012101714671FF
+:107E50001799817102E000206946087109A96846F6
+:107E600003F06BFEA07FDF21084069010843A07783
+:107E70000020E0E770B50446084620380D460300B0
+:107E800013F08AFA0A060A11232C3342495057612B
+:107E9000FF20A9A10D3052E02078202851D1FF20E9
+:107EA000A5A110304BE0A3480178032949D0807880
+:107EB000132846D02078242843D0252841D02328D1
+:107EC0003FD0FF209CA1133039E02078222838D001
+:107ED000232836D8FF2098A11A3030E020782228B5
+:107EE0002FD0FF2094A11E3029E02078222828D00E
+:107EF000242826D0262824D0272822D0292820D07C
+:107F0000FF208DA121301AE02078252819D0FF20EC
+:107F100089A1283013E02078252812D0FF2086A1DF
+:107F20002B300CE0207825280BD0FF2082A12E30AA
+:107F300005E02078282804D0FF207FA1313013F0FD
+:107F40000AF9257070BDFF207BA13430F7E730B50A
+:107F50007E4C0B887E4A022801D0934204D09D1F9C
+:107F6000A54225D2022802D04D88954203D04D88E3
+:107F7000AD1FA5421CD24C88A34219D88B88FF257F
+:107F8000F435AB4214D8022802D0C888904205D0FC
+:107F9000C8886E4D0A382D1FA84209D2C888904261
+:107FA00008D0944206D05B1C63438000834201DB0F
+:107FB000072030BD002030BDF0B56649884245D36A
+:107FC000654A0125AD041368A84201D398423DD308
+:107FD0000279002A06D0082A02D8067B082E05D985
+:107FE0000720F0BD047B002CFAD0F6E7002A06D06B
+:107FF00004688C422AD3AC4201D39C4226D3002E83
+:1080000006D084688C4221D3AC4201D39C421DD35C
+:1080100000240CE00568A700ED598D4216D3012716
+:10802000BF04BD4201D39D4210D3641CE4B2A242FE
+:10803000F0D800220125AD040CE084689700E459D3
+:108040008C4203D3AC4203D39C4201D21020F0BD3A
+:10805000521CD2B29642F0D80020F0BD10B5028971
+:108060003E4B111F994213D24189042910D3DB1CC6
+:1080700099420DD891420BD80178890706D54068FE
+:10808000002803D0FFF798FF002800D1002010BD82
+:10809000072010BDFFB50022099B002802D099429D
+:1080A00005DC6EE0002902D1002004B0F0BD0920FB
+:1080B000FBE7845C002C12D087187D78112D59D0F5
+:1080C00010DC2B0013F068F90A561726262C2C2EEC
+:1080D0002E4C4C56835C002B46D1521CD2B28A42A5
+:1080E000F8DBE1E71C2D45DA123D2B0013F054F9C3
+:1080F000044242121A42022CD9D1BB78039C072BAE
+:10810000237001D25B0701D40A20CEE7029B012431
+:108110001B782CE0E343DB0708E0012C08D029E0C2
+:108120000620C2E70F2523072D075B19002BF4D08B
+:108130003046BAE7640C00207372635C6761705F5D
+:10814000636F72652E630000023000007B0C00003C
+:10815000FFFF000000C0010028000020FD3F0000DC
+:10816000029B1B789C0701D50B209EE7022423432A
+:10817000029C2370835C521C9A18D2B28A4202DDA0
+:1081800095E7192676028A4293DB8DE710B50478CD
+:108190000B46002C08D00121F94A012C07D0022CF3
+:1081A0000BD0032C13D10EE00021197011E01970CF
+:1081B0008179890903290AD10BE01970817989092C
+:1081C000012904D105E019708179890901D010468F
+:1081D00010BD411C0622581C12F033FE002010BDB9
+:1081E00008B51346002806D0E6A00068009048793C
+:1081F0006A468009105C18700622581C12F021FE95
+:1082000008BD30B50C46097895B0222902D2082065
+:1082100015B030BD282369460B704880132A03D05F
+:108220003B2A01D00720F3E708460A7109A903F0A9
+:1082300084FC050003D121212046FFF71BFE2846C0
+:10824000E6E700B595B0232369460B704880108897
+:1082500088805088C880D088488190880881002014
+:108260008881C88109A9684603F067FC15B000BD84
+:1082700070B50C00064610D0FFF7C5FD050003D110
+:10828000C149C24812F067FFA6802889E08028898A
+:10829000208168896081A889A08170BD70B50E4673
+:1082A000050003D00021092004F0A7F90120B84CF3
+:1082B000022E207324D0032E04D0D320B249800094
+:1082C00012F049FFB24806210D3003F02DFFA07CCB
+:1082D0008006800EA074FFF774FDA08B00280ED0DE
+:1082E000002D0CD0830001220021092004F0DEF8CB
+:1082F000092804D0A548A449283012F02CFF70BDED
+:10830000A3480321103003F00FFFA07C402180061A
+:10831000800E0843A0749E480C3002F04EFBDAE752
+:108320007FB501A9022003F06EFD002851D09748C7
+:108330009549673012F00FFF4BE0029C207821280E
+:1083400047D0A07F01072BD52046223000906846F9
+:108350002346628E80882146343301F084FC050078
+:1083600005D011282ED089488749843028E0A07F85
+:10837000F7210840A077E17F480889074000C90F2E
+:1083800008432021095D4007400FC9000843E077FA
+:108390002078282824D129212046FFF76BFD1FE0F3
+:1083A000400716D568462246808821460E32FFF7E0
+:1083B00048FF050008D0112804D074487249933052
+:1083C00012F0C9FE00250BE0A07FFB210840A0773A
+:1083D00006E001A803F025FD0500AED0052D02D072
+:1083E000284604B070BD0020FBE7F8B5040004D1B6
+:1083F00066486549A13012F0AEFE722020706068B8
+:1084000008260178091F0B0012F0C6FF11FD0A466D
+:1084100068FC460EFCFC4746464646FD92FD46007B
+:108420007B205949C00035E087883846FFF7EBFCD0
+:10843000050004D11F205449400112F08CFE6078E1
+:10844000042130436070524CA07F0843A077212163
+:108450002846FFF70FFDA87F8007800F012801D174
+:10846000801EA080384603F0B1F83846FCF7FBFFC9
+:108470003846FBF79EFB3946022004F0BEF8A87F81
+:10848000EF210840A877FFF74BFF002804D03F48B2
+:108490003D49C93012F05FFEF8BD85882846FFF7D8
+:1084A000B2FC002804D139483749D33012F053FECA
+:1084B00060688078012804D034483349D53012F000
+:1084C0004AFE60688179284603F09CF90028E3D0D1
+:1084D0006178314361706168C880F8BD878838462B
+:1084E000FFF791FC050004D128482749E63012F037
+:1084F00032FE60783946304360706068C0882881F9
+:1085000060680089688160684089A881022004F061
+:1085100074F80020A875A87F8007800F0228DCD19E
+:10852000FFF7FEFE0028D8D0212017494001B1E70F
+:1085300080783C2803D00025022814D000E00125D3
+:108540000027002808D03C2806D0022804D00F4875
+:108550000D49FF3012F0FFFD002F06D002263046F5
+:1085600001F06CF9F8BD0127EBE7607830436070EB
+:108570000748817F31438177002D0BD00126EEE73C
+:10858000023200000302FF01388100002E030000C8
+:10859000640C002060688788384601F07BF9054646
+:1085A00060688079012832D00226A87F06228008E0
+:1085B00080003043A8776068C08A28816068008B9B
+:1085C00068816068408BA8816068C079E8756168DF
+:1085D00028461830083112F034FC60680622807B8F
+:1085E00068706168A81C0F3112F02BFCA87F81070E
+:1085F000890F384602F0D4FFA87F8007800F01283A
+:10860000ADD101E005E008E0FE488780A7E701263C
+:10861000CBE7204601F01EFEF8BD60783043607065
+:10862000F8BDF7B505460078002700090C463E4620
+:1086300001287DD00022F44902287AD0072804D0EE
+:108640000A2877D0F149F24839E1686803780D2BA0
+:1086500035D006DC042B6ED0072B3AD00A2B69D11B
+:1086600006E0122B3CD0132B44D0142BF7D1BEE0E4
+:1086700011270726002C7CD08088A0806968FB2306
+:108680008979A171DF4905468A7F1A408A770421DA
+:1086900003F071FB0521284603F06DFB00212846FD
+:1086A00003F069FB0121284603F065FB03212846FE
+:1086B00003F061FB0221284603F05DFB01E1012785
+:1086C0000926002CD7D08088A08068688079207225
+:1086D000F7E012270E2680882146FFF7C9FDF0E05B
+:1086E0001A270726002CC6D04088A0806868007929
+:1086F000A071E6E081783C293ED010271E26002C90
+:10870000B9D08088A0806868C08A20836868C08AE1
+:10871000E0826868008B60836868408BA08369682A
+:10872000607D497F40084000C907C90F084303E046
+:108730006CE097E0BAE029E060756968C007497F9E
+:10874000C00F49084900084360756968A21DC879CF
+:108750000831FFF745FD69682246887B0D320F31ED
+:10876000FFF73EFD68688079002803D0012020755E
+:1087700007E076E00220FAE719270726002C70D0E0
+:10878000A271A048F722817F11407DE01B272E2691
+:10879000002C66D0A1806968A21D0879491DFFF7E9
+:1087A0001FFD68682030C07A60736868C07804284C
+:1087B000A07B19D040084000A073F92108406968E7
+:1087C0001F22C9788907490F0843A07369684007C9
+:1087D000C97A400FC9000843A073696820460F306A
+:1087E0000C3112F02EFB6CE001210843E4E71E2758
+:1087F0000E26002C6DD0A1806868E21D407AA07121
+:1088000069688878C91CFFF7EBFC5AE0287A0128D0
+:1088100005D0022815D07E487C4932384FE01D270C
+:108820000E26002C55D06888A080A889E080E889B1
+:108830002081288A6081688AA0817248DF22817F36
+:10884000A2E712270E266888FFF712FD002C40D001
+:1088500068784007400F032833D16A48FD22817FA2
+:1088600092E736E0287A030012F096FD0604101015
+:108870002020202619270726002C2AD0A180614815
+:10888000A271817F4908490081771AE019270726DC
+:10889000002C1ED0A180287A012805D00320A071C9
+:1088A0005848EF22817F6FE70220F8E721462846EB
+:1088B000029A01F068FEFEBD55485449801F12F02F
+:1088C0004AFC0298002C068001D027806680002098
+:1088D000FEBD02980680FAE710B54A4894B0807849
+:1088E000132802D0082014B010BD22206946087059
+:1088F00009A9684603F021F904460021072003F086
+:108900007CFE2046EFE700B53E4895B080781228FF
+:1089100001D00820AAE41E21684601700021817060
+:10892000C17009A903F009F90028F3D1002107203B
+:1089300003F063FE1120FFF724FA002096E400B54F
+:10894000304895B00078022801D0032818D11B21A7
+:1089500008A801730021817369460BA803F0EDF8A4
+:10896000002804D1684640781B2801D003207DE40C
+:108970000021084603F041FE68468078002801D0B7
+:10898000082073E40120FFF7E3F900206EE4F8B556
+:108990001C4C030012F000FD0A06791779797979E9
+:1089A00044356779FFF7CBFF00282AD1F8F7DAFFC3
+:1089B000002826D02221017000210172F8F7B3FFB0
+:1089C000A07F01214BE08EB23046FFF71CFA050074
+:1089D00004D10F480D492E3012F0BDFB2878212814
+:1089E0000FD0F8F7BFFF002814D012210170022722
+:1089F000077246800020A875F8F795FFA07F3843DE
+:108A0000A077F8BD640C0020FFFF00003881000053
+:108A10005F050000132229463046FFF7F2FBF0E71E
+:108A2000A578122D06D0132D07D0F849F84812F07A
+:108A300092FBE6E7FFF767FF01E0FFF74DFF002835
+:108A4000DFD1F8F78FFF0028DBD022210170122D33
+:108A500007D002210172F8F766FFA07F10210843BA
+:108A6000CEE70121F6E7A07C810901290BD080091E
+:108A700004D0E748E549223012F06DFB03210020C5
+:108A8000FFF70CFCBDE70221F9E7E148DF49293097
+:108A9000CDE7F7B514460D0004D1DD48DB49313090
+:108AA00012F059FB28780827012807D002281FD088
+:108AB000D748D649623012F04EFBFEBD0098FFF752
+:108AC000A2F9060004D1D248D049383012F043FB55
+:108AD0000220B0751030207060783843607007CD88
+:108AE000083407C4CB482022817F11438177FEBD23
+:108AF0000098FFF788F9060004D1C548C3494630FD
+:108B000012F029FBA988C448814208D1EA88824230
+:108B100005D1132231460098FFF773FBFEBD814259
+:108B200002D1E888002809D01220207060783843EC
+:108B3000607007CD083407C4002006E078230022C7
+:108B40000220009903F0B2FC0120B075FEBDB148CF
+:108B500040897047FFB591B01498FAF71BF90028C7
+:108B60005DD10124684603218471C90281800022FD
+:108B700001A92046FBF7ECFA002850D168461521E0
+:108B800084714902818000261C2102A8009612F0FF
+:108B9000B7F90120014668461031017000200146F6
+:108BA000684641708178F9273940891C21438170DA
+:108BB000017A02252943017212998186C6861F21F6
+:108BC00001870C9011980F9001A80B9009AA0BA98E
+:108BD00002A8FBF788F8002821D168468D4E808CCA
+:108BE000F080684684718D498180807809AA384078
+:108BF000801C41084900684681708586058713A856
+:108C00000F900BA902A8FBF76EF8002807D1684661
+:108C1000808C308131460A311498FAF7CEF815B0BD
+:108C2000F0BD30B50C467E4995B08C423CD37D49B1
+:108C3000012292040968944201D38C4234D3203833
+:108C400000220125030012F0A7FB06042A44484E27
+:108C5000575F0021082003F0AAFC002802D0112051
+:108C600015B030BD24206946087000A80522A11C5B
+:108C7000023012F0E6F809A9684602F05EFF05002E
+:108C80002FD1082300221146184603F00FFC0828B4
+:108C900027D05F485D49D63012F05DFA21E0606868
+:108CA000002803D0884201D21020D9E73D21684630
+:108CB0000170218841806188818009A902F03DFF0F
+:108CC00005000ED1606800280BD06946098D01802F
+:108CD00007E0206801F0B2FE02E0204600F024FE2A
+:108CE00005462846BCE73E2007E0857000E082701C
+:108CF00009A902F022FFF3E73420694608702078C2
+:108D0000C0076846F3D0F0E70720A9E730B50C4666
+:108D1000444995B009688C4201D21020A0E7203860
+:108D2000030012F039FB05042121232132002088A1
+:108D3000FFF769F8002804D00078222803D2082021
+:108D40008EE739488CE725216846017021884180EB
+:108D500009A902F0F2FE050015D10AA90522023187
+:108D6000A01C12F06EF80EE006250CE0206800282A
+:108D700005D0884201D2102505E001F055FE2548B6
+:108D80000025808BA08028466AE7072068E72148F5
+:108D90001330704710B520211E4812F0AFF80120A3
+:108DA000FEF7D6FF1120FEF7ECFF00211948C9435A
+:108DB000818000218176E1218900818301460C3088
+:108DC0000D310446F8F74EFE1248072221461330B3
+:108DD00012F037F8FEF7F5FF002803D00B491348CF
+:108DE00012F0B9F901F0E5F910BD10B504463C21C7
+:108DF00012F084F8A07F80088000A07720202070E7
+:108E00000020A0752034607010BD00003881000083
+:108E1000B5050000640C0020FFFF0000012A0000DF
+:108E200000C0010028000020023000001C070000E4
+:108E30007047FEB50546FF480C46814207D3012026
+:108E40008004844205D3FC480068844201D210208B
+:108E5000FEBD002D02D0012D32D126E0F7490822B7
+:108E60000F46684611F0EDFF39462046FFF78EF9B0
+:108E70000028EDD1FEF7A5FF060006D007226946BF
+:108E8000384611F0DEFF3046FEBD2078002801D0C4
+:108E9000012805D1E94807223946C01D11F0D1FF4C
+:108EA0000021092003F0A9FB0FE00978002907D071
+:108EB000012905D0022905D0032903D0E048FEBDD1
+:108EC0000720FEBD0120FFF7E9F9DC480C38857664
+:108ED0000020FEBD10B5D8490968884201D2102093
+:108EE00092E7D64902460C390B7B0D311846FFF745
+:108EF00077F9002088E7FFB599B00546002008A95A
+:108F000008746946087108A908730875CA481446A8
+:108F10000121C84A890400681E46002D05D09542EB
+:108F20000BD38D4201D3854207D3002C08D0944245
+:108F300003D38C4204D3844202D210201DB0F0BD72
+:108F40002846204318D01F270BAB0CAA00972846B1
+:108F50001A99FFF79FF80028F0D10DAB01AA31460E
+:108F600020460097FFF796F80028E7D16846007979
+:108F7000C00703D00A20E1E70720DFE702AF002D9A
+:108F80000FD01A20694608721A9888722946F81C70
+:108F90001A9A11F056FF0EA902A802F0CEFD002881
+:108FA000CCD1002C0ED02021684601728672324648
+:108FB0002146F81C11F045FF0EA902A802F0BDFDE4
+:108FC0000028BBD19D4908A8007B0C3948700020BF
+:108FD000B4E770B506460A200C46087015461146DF
+:108FE000204602F0AAFD002807D139212170204631
+:108FF000294602F0A2FD002804D0082801D190489B
+:10900000401C70BD2A462146304600F0B9FC04469B
+:10901000082803D18B498C4812F09DF8204670BD7A
+:10902000F0B5044689A003C897B0824D002715917A
+:109030001490AC4211D380480121890403688C420A
+:1090400001D39C4209D32078012809D16268AA4241
+:1090500003D38A4204D39A4202D2102017B0F0BD43
+:1090600076490C390A78012A0CD18A88794B9A42C0
+:1090700003D0002806D0012804D08A7F13079B0F55
+:1090800006D101E00820E9E7D30701D1910701D516
+:109090001120E3E7218A704B0A46203A9A4207D30F
+:1090A000012877D1002975D1628A002A72D111E096
+:1090B000022801D0032801D1A0296BD3012809D0AF
+:1090C0005E4A0C3A5278D20704D0628A002A61D0F4
+:1090D000B42A5FD8002806D0012808D0022804D07E
+:1090E000032857D117E0002518E0022516E00029D3
+:1090F00002D1608A00280CD004256068007800281E
+:109100000CD0012809D0022807D0032805D04C48EC
+:10911000A4E70125F1E7032500E00127207A0028D4
+:1091200006D0012806D0022806D0032867D105E022
+:10913000002604E0012602E0022600E00326002DBE
+:1091400001D0022D16D1002E14D0E068002803D0E3
+:10915000FEF732FF002881D138480C38407880076C
+:1091600002D03748401E79E7022D03D1022E46D0A7
+:10917000032E44D0182168460170218A4180218A3B
+:10918000818085712D480C38007B002803D0012890
+:109190006FD104E033E000216846C17102E0012094
+:1091A0006946C8716846077221780930012920D0C4
+:1091B000062111F0A3FE69460E74207D8207C107C7
+:1091C000D20F4007C90F5200C00F11438000014366
+:1091D00014A8405C6946C873002810D009A96846E5
+:1091E00002F0ABFC002893D1002D0AD0022D08D04C
+:1091F00012E061680622491C11F023FEDBE707201C
+:109200002CE7002E08D0E068002805D009AA69469E
+:10921000FFF7DFFE0028A6D11B2069460870012059
+:10922000887009A9684602F088FC00289BD108A82C
+:10923000407913E000C0010028000020700C0020DD
+:1092400002320000388100002708000007060504EC
+:1092500003020100FFFF0000E13F00001B2819D1BD
+:109260002B0012F099F80504040707040A000320F4
+:1092700001E00FE00220FEF76BFD012D0CD0608AAB
+:10928000002809D0002283001146104603F00EF991
+:10929000002801D00320E1E60020DFE6F3B5032635
+:1092A00087B00D4600290AD0FE4885426FD30120C1
+:1092B0008004854203D3FC480068854267D3079841
+:1092C000FEF7A1FD040005D02078222804D2082052
+:1092D00009B0F0BDF548FBE7A07F8707BF0F002D61
+:1092E00005D029463846FEF732FE0600F0D1394651
+:1092F0000027EF48012907D0022931D0ED49EE4877
+:1093000011F029FF3046E3E7A27D2946012A02D069
+:10931000827F920701D51120DAE700291BD10821AD
+:109320006A46049711820592418904AAE348FBF733
+:10933000FFFA0028CCD16846008A082801D0032013
+:10934000C6E7684601880181418841818188818121
+:10935000C188C18102A9079802F0E7F90646D1E762
+:10936000A17D022916D1807F800613D4002D04D060
+:10937000A07F40070CD4002100E00121079802F0F3
+:1093800014FA0600BED1A775002DBBD004E01AE088
+:109390001126B7E7002D16D02A4621460798FEF77A
+:1093A00050FF06461128ADD1A07F4007AAD4204621
+:1093B000082229460E3011F044FDA07F0421084305
+:1093C000A07700269EE7102082E770B50C46054680
+:1093D000FEF719FD010004D022462846FEF711FFD2
+:1093E00070BDB24870BD00B50146143195B0192961
+:1093F00001D2810707D001461E3104D00A3102D0C4
+:10940000072015B000BD312269460A70887009A98D
+:10941000684602F092FBF4E701B582B0022069468B
+:109420000880A34802AB00896A460021FBF7EAF8EE
+:1094300069460988022900D003200EBD1CB5002111
+:10944000009102216A46118097490190096888427B
+:1094500001D210201CBD964801899848FBF768FA94
+:10946000694609880229F5D003201CBDF0B50E46D7
+:109470008C4985B0174605468E4207D38A4801229B
+:1094800092040068964204D3864202D2102005B0AE
+:10949000F0BD1F2F01D90C20F9E7854C8D4226D352
+:1094A000954201D3854222D3E08803A9FBF75BF8FC
+:1094B0000028ECD1287869464873E08803A9FBF7B7
+:1094C00033F80028E3D16946009008780221084368
+:1094D00069460870497B090703D00821084369469B
+:1094E0000870E0886946FAF7B8FF0028CFD16946CE
+:1094F0008F80E088334601AA0021FBF783F8694694
+:109500008988B942C3D00320C1E71CB50C460021AD
+:1095100000910191228869460A8063490190096897
+:10952000002801D0884201D38C4201D210201CBDFA
+:10953000002801D0002A09D05D486A46C1885F48EA
+:10954000FBF7F6F96946098821801CBD0C201CBD7B
+:1095500010B50123FEF75DFC56E4002310B51A4652
+:109560001946FEF756FC4FE470B504464D4894B0DA
+:10957000844207D301208004844206D34A4800680D
+:10958000844202D2102014B070BD2046FEF766FD62
+:109590000028F8D146488178112901D00820F2E747
+:1095A000817FC90601D51120EDE71D2269460A70A9
+:1095B00021780025CA07D20F69468A7022898A80DD
+:1095C0006289CA80217801268907CA0F69464A72D2
+:1095D000007B002803D0012804D00320D3E70846ED
+:1095E0000D7201E008460E7209A902F0A6FA0028E1
+:1095F000C9D12078800708D56068002805D009AA5D
+:109600006946FFF7E6FC0028BDD11E2168460170BF
+:109610008670C57009A902F090FA0028B3D1A0891C
+:1096200000F073F90400AED11220FEF7AAFB204629
+:10963000A9E7F0B516461C4A0C4605001948204912
+:10964000126899B005D085420FD38D4201D395425F
+:109650000BD3844209D38C4201D3944205D3864272
+:1096600003D38E4204D3964202D2102019B0F0BD2B
+:109670000F4FB87FC106890F01D1400701D51120D6
+:10968000F4E72046FEF7EAFC0028EFD120788107B6
+:10969000C90F294303D0800714D5002D12D007200D
+:1096A000E4E7000000C001002800002002300000B4
+:1096B000640C002038810000F3090000FFFF000067
+:1096C0000000040031460220FEF741FC0028CDD105
+:1096D000C9488078112803D0122801D00820C5E796
+:1096E0000220002714A9189002F08DFB00280DD04D
+:1096F000C2A1C64811F02FFD08E01598807F8107B0
+:109700001898890F814201D17F1CFFB214A802F082
+:1097100088FB0028F1D0032F01D30420A6E7B64828
+:109720008078122803D1FFF7EEF800289ED1207828
+:10973000800708D56068002805D009AA6946FFF7A8
+:1097400048FC002892D1212168460170218941807E
+:1097500061898180207800278007C10F6846817168
+:1097600020788007002815DB2878002807D00128FA
+:1097700008D0022806D0032804D0A54876E768461A
+:10978000C77102E001206946C8710622691C02A85F
+:1097900011F057FB9848007B002803D0012804D023
+:1097A000032063E76846877302E0012069468873F7
+:1097B00031886846018271884182B1888182F1884E
+:1097C000C1820783478309A902F0B7F9002886D12F
+:1097D000A08900F09AF80400A0D11320FEF7D1FA76
+:1097E000204643E730B505468A4895B000680C46E8
+:1097F000814202D2102015B030BD2846FEF703FB8F
+:10980000002807D00178222902D3807F800603D464
+:109810000820F0E78048EEE7132168460170458094
+:1098200009A902F08AF90028E5D108AA0A215156AF
+:109830007F2901D02170DEE70520DCE710B56E49F5
+:10984000012807D0022815D0FF206CA14D3011F05F
+:1098500082FC81E60878032804D0FF2067A143300A
+:1098600011F079FC0021084602F0C7FE0120FEF746
+:109870006FFA71E68878132804D0FF205FA1483082
+:1098800011F069FC0021072002F0B7FE1120FEF75D
+:1098900078FA61E6F8B504460122022102F044FAA2
+:1098A000074601220321204602F03EFA0646012225
+:1098B0000521204602F038FA0546012204212046FF
+:1098C00002F032FA0446002F04D1AF204BA18000F1
+:1098D00011F041FC002E04D14C4848A11A3811F077
+:1098E0003AFC002D04D1494844A1193811F033FC49
+:1098F000002C04D1454841A1183811F02CFC22213C
+:109900003846FEF7B7FA3846F8BD10B5002809D03A
+:10991000830000221146072002F0C8FD072801D06D
+:10992000032019E6002017E610B504460068002859
+:109930000CD03A49884207D301218904884205D3D3
+:1099400034490968884201D2102005E601F060F828
+:10995000A088294CA083A07E01280DD100210920D8
+:1099600002F025FE002800D00120A17C89090129F0
+:1099700004D00321FEF792FC0020EDE50221F9E777
+:10998000F7B500260C4605460B271AE02968B000FB
+:1099900009580978002903D0012901D00720FEBD0C
+:1099A000A170296806220958E01C491C11F049FAE7
+:1099B00027702046029902F0C0F80028EFD1761CEB
+:1099C000F6B22879B042E1D800263A270FE0A8681D
+:1099D000B10041581022A01C11F033FA2770204624
+:1099E000029902F0AAF80028D9D1761CF6B2287B99
+:1099F000B042ECD80020FEBD640C00207372635CA2
+:109A00006761705F636F72652E630000D7020000AC
+:109A100002320000280000200230000000C00100D7
+:109A200030B5FE4B9A4207D301239B049A4205D3DB
+:109A3000FB4B1B689A4201D2102030BD1578EB0613
+:109A40005B0F042B07D85478072C04D39378102B82
+:109A500001D8A34201D2072030BDD3785B0702D4DE
+:109A600013795B0701D5062030BDC37FAC075B08C7
+:109A70005B00E40F2343C3770878EF231840137883
+:109A80009B06DB0F1B0118430870F1231840137865
+:109A9000DB065B0F5B0018430870507808730020EA
+:109AA00030BD30B500240C70C378DB07DB0F0B70C2
+:109AB000C578AD07ED0F6D002B430B70C5786D07B2
+:109AC000ED0FAD002B430B7014700179C907C90F5E
+:109AD000117003799B07DB0F5B001943117000794C
+:109AE0004007C00F80000143117030BD70B51446AF
+:109AF0000D460646F7F736FF002809D0A22101706F
+:109B0000142221460830F7F75FFBF7F70CFF70BD12
+:109B1000132229463046FEF774FB70BD70B514461B
+:109B20000E460546F7F71EFF002809D022210170D6
+:109B300045802178017261784172F7F7F4FE70BDBB
+:109B4000132231462846FEF75CFB70BD10B5B54CBC
+:109B5000207C00280DD12046B34A21461038FEF75C
+:109B6000A7F8002803D0B1A1F12011F0F4FA0120E8
+:109B7000207410BDFFB581B00A9D06461C461746ED
+:109B80001421284611F0BCF90B9800210160F80758
+:109B90000ED0A34920680968884239D31230286062
+:109BA0002068143068602068A8600B982168016004
+:109BB000B80726D56068002803D09949096888420B
+:109BC00026D3029900290AD0FC3600280ED031464F
+:109BD0001030FEF7DBFA00281BD1606810E0002887
+:109BE00016D0E86080366068B0670AE0FFF7CFF80B
+:109BF00001460722304611F024F9FFF7A7FF8948F4
+:109C0000E860780708D58649A0680968884202D2CA
+:109C1000102005B0F0BD28610020FAE770B50546B8
+:109C200011200C460870002161702121495D002936
+:109C300008D003290ED0042910D0FF207BA1523078
+:109C400011F089FA20780009012802D9E87FC008BC
+:109C5000607070BD0007000F203002E00007000FA9
+:109C600030302070EEE770B594B015460C462C22CB
+:109C70006946189E0A704880002B17D008221946A2
+:109C800001A811F0DEF868468581102231460E30B9
+:109C900011F0D7F809A9684601F04FFF002803D159
+:109CA000A17F10221143A17714B070BD0020019054
+:109CB0000290E8E7F0B50646008A97B080B20D46FC
+:109CC0000190FEF7A0F804465648317848385B4FBB
+:109CD00009900B0011F060FB0EFEFD43084A7283F1
+:109CE000B8D9FCFBFAF9F8FEA07F8007800F0128A5
+:109CF00007D000210022019802F016F8050007D1D4
+:109D000001E00121F6E7FF2048A1943011F023FA89
+:109D1000387CC00904D049484038406DA86112E041
+:109D20002B20694608720BA902A801F006FF002843
+:109D300004D0FF203DA19F3011F00DFA40490C984E
+:109D400011F0E8F8A9617068A862B068E86220784C
+:109D5000252804D0FF2035A1A53011F0FCF93246AA
+:109D600021460198FFF7C2FE17B0F0BDA07F800723
+:109D7000800F012807D000210022019801F0D4FFB4
+:109D8000060007D101E00121F6E7FF2027A1AF304F
+:109D900011F0E1F92078252804D03078012108431A
+:109DA0003070E1E702202870B068A860B068002831
+:109DB00002D000202871D7E70120FBE72B2069465D
+:109DC0000870184968464C3901F0B7FE002804D0E5
+:109DD000FF2016A1CE3011F0BEF903201BE02A208F
+:109DE0006946087000A810220230716811F029F845
+:109DF00004A810220230B16811F023F8094968461E
+:109E00004C3901F09AFE002804D0FF2007A1DF3072
+:109E100011F0A1F904202870099813E000C0010096
+:109E200028000020300D0020FFFF00007372635CEB
+:109E30006761705F7365632E63000000500E002041
+:109E400040420F0068608FE7B068002804D1FF200F
+:109E5000F649EB3011F07FF9E07F400704D5FF2091
+:109E6000F249EC3011F077F9B06806220A38009018
+:109E700033790421019801F058FA002891D0FF208D
+:109E8000EA49F13011F067F96EE7002C04D1FF20A8
+:109E9000E649F93011F05FF92046223010220546DC
+:109EA000716810F0CEFF28212046FDF7E3FFA07F68
+:109EB0008007800F022814D100231A4621460095FE
+:109EC0000198FFF7D0FE06E055E1B6E0ACE089E08E
+:109ED0002CE065E069E111280BD029212046FDF72F
+:109EE000C9FFE07F317A4007400FC9000843E0779F
+:109EF0003AE7A07F000703D5CC49CD4811F02BF9F4
+:109F0000A07F08210843A0770020608620463430D7
+:109F100010F0F4FFE07FFD220146C9071040890FD1
+:109F20000843E077307A203420701DE7A07F800757
+:109F3000800F012807D000210022019801F0F4FED3
+:109F4000040007D101E00121F6E7B948B7491D3007
+:109F500011F001F92B2069460872B64902A801F0F8
+:109F6000ECFD002804D0B248B049223011F0F3F8DB
+:109F7000B0488188204621300176090A41760E21B9
+:109F800029702146FC316960017E2974407E687425
+:109F9000A8482C30A860103030346C61E860E3E6EB
+:109FA000002C04D1A248A149363011F0D4F8207811
+:109FB00021289DD93079012802D0022808D103E058
+:109FC000E07F04210843E077387C0121084338749E
+:109FD000324621460198FFF789FD23212046FDF7EF
+:109FE00049FFC1E601220421019801F07DFC00280F
+:109FF0009BD0A07F8007800F012807D0002100227E
+:10A00000019801F091FE040007D101E00121F6E77B
+:10A0100087488649543011F09EF80F202870172089
+:10A0200028716E34AC609FE60421019801F0ABFC0E
+:10A030000028B4D11020287096E6A07F8007800FFA
+:10A04000012807D000210022019801F06DFE0500D3
+:10A0500007D101E00121F6E7754874496D3011F030
+:10A060007AF82E462036307E41064DD5A17F8F07E7
+:10A07000BF0FC00713D02A468032516F00290ED07F
+:10A08000087CF37DC007C00F5B0018430874516F54
+:10A09000E27F40084000D207D20F10430874307EA0
+:10A0A000000713D528468030026F002A0ED0117C9D
+:10A0B000F37DC907C90F5B0019431174E27F49089A
+:10A0C0004900D207006FD20F11430174307E800720
+:10A0D0000BD5F8204259002A07D0012F05D0294678
+:10A0E000307C31311032FEF77BF8307EC0060BD564
+:10A0F000F8204259002A07D0012F05D12946307C8B
+:10A1000031311032FEF76CF8052368460370357E56
+:10A110004570484822226038019902704278D2087E
+:10A12000D200D21C4270418003724572F7F782FD63
+:10A130002078252809D021280BD0AD203B4980006C
+:10A1400011F009F82078222803D922212046FDF7B2
+:10A1500091FEA07F8007800F01280AD0002101987E
+:10A1600001F009FE002800D1FEE5AF202F49800054
+:10A1700088E60121F3E774682E4D207860350928C0
+:10A1800002D00A28F0D10BE0E168002902D028466D
+:10A19000F8F7D7FE2169002902D02846F8F7D1FE4A
+:10A1A00021462846F8F7CDFEDEE521481F49DC3080
+:10A1B00068E6204810B5072228216030F8F7A8FE8D
+:10A1C0001D480024017C4906490E0174403844654D
+:10A1D000FDF7FBFC17493C3108461038F7F779FCCE
+:10A1E00014484C30047410BD70B50D46FDF70BFEDD
+:10A1F000040004D103200D49000210F0ACFFFF2140
+:10A200000531284610F07CFEA07F8007800F0128D2
+:10A2100016D0022128468830FDF7D8FC002803D04C
+:10A220000249064810F097FF70BD00002C9E000008
+:10A2300005020000E40C0020500E00200503000081
+:10A240000121E7E70A46014610B510468830FDF7C0
+:10A25000D7FC10BDF0B505464068082601789BB0D4
+:10A2600008290DD00B2903D00C293FD10121817180
+:10A27000686887883846FDF7C6FD040041D13BE099
+:10A2800047883846FDF7BFFD040003D1FD49FE486D
+:10A2900010F061FF2078212828D0282828D168686C
+:10A2A00002210C3000F0BEFF002821D06868082190
+:10A2B000001D00F0B7FF00281AD02D21684601705C
+:10A2C000478021461022223101A810F0BAFD0FA9C3
+:10A2D000684601F032FC002804D0CB20E949800018
+:10A2E00010F039FF29212046FDF7C4FD1BB0F0BD59
+:10A2F000687830436870F9E7E348E2492D3010F0A0
+:10A300002AFFA07F8107890F022902D1EF2108408F
+:10A31000A0772078212810D068688179002902D0A0
+:10A320008078002818D0A07F8007800F022864D092
+:10A330000720D449C00110F00EFFA07F8007800FD6
+:10A340000228D3D1FDF7ECFF0028CFD0CE48CD496D
+:10A35000733010F000FFC9E7687830436870E07F21
+:10A36000C00701D0042100E00321212001552078FD
+:10A37000292818D02428E0D13946062002F03DF9DA
+:10A3800022212046FDF776FDA07F8007800F01285F
+:10A3900031D00021384601F0EEFC0028CDD0BA487B
+:10A3A000B8495830C7E7A07F8007800F012807D041
+:10A3B00000210022384601F0B7FC050007D101E07A
+:10A3C0000121F6E71B20AF49400110F0C4FE252112
+:10A3D0002046FDF74FFD0D2008A90871284609A960
+:10A3E0008830FDF7FFFB0228A7D00028A5D0A6489B
+:10A3F000A4494D309FE70121CCE76878304368706D
+:10A400009BE7F7B58AB00A98FDF7FDFC050056D02A
+:10A410002878222853D3232851D0E87F40074ED4F0
+:10A42000A87F8007800F01280ED0002201280DD0C0
+:10A4300000210A9801F078FC064694480290F8F74B
+:10A4400077FD040009D103E00122EFE70121F0E7E5
+:10A4500075208C49C00010F07EFE002E0FD088368B
+:10A4600066610298F8F764FD07460298F8F760FD08
+:10A4700006462878222807D0242805D008E00020A6
+:10A4800007460646606103E025212846FDF7F2FCF9
+:10A49000092020700A9820620C9820710B98E760C0
+:10A4A0002661A06004A92046FDF7C0FB022806D063
+:10A4B000002804D074487349AF3010F04CFE0DB042
+:10A4C000F0BD30B587B00446FDF79DFC0546807FA2
+:10A4D0008007800F01280BD000210022204601F0C8
+:10A4E00023FC0446287822281ED9002C07D101E03D
+:10A4F0000121F2E764486349BB3010F02CFE0F21C4
+:10A50000684601701721017120466E30029069463D
+:10A510001A30FDF767FB022806D0002804D05A48FD
+:10A520005849C03010F017FE07B030BD30B587B0C5
+:10A530000446FDF768FC0546807F8007800F0128F0
+:10A540000BD000210022204601F0EEFB04462878C3
+:10A550002228E9D9002C07D101E00121F2E74A487D
+:10A560004849CD3010F0F7FD1020694608702046AC
+:10A570008830FDF737FB0028D6D043484149D0301A
+:10A5800010F0E9FDD0E7F7B505460078002700098F
+:10A5900082B00C463E4602287CD0072802D00A280A
+:10A5A00049D149E068680178082906D00B292FD0E5
+:10A5B0000C292DD03349364865E114271A26002C82
+:10A5C00069D04088A080FDF71EFC0090002804D1CF
+:10A5D0002F482C49243810F0BEFD00980099C07D0A
+:10A5E000A21D1831FDF7FCFD686808228089E08112
+:10A5F000696820461030091D10F023FC207E0121DF
+:10A600000843F9210840207600984021807F50E0DF
+:10A6100018270826002CD3D08088A080FDF7F3FBF4
+:10A62000050004D11A481749401F10F094FDA11DE0
+:10A630002846FFF7F3FA28E1002C01D0288BA080F0
+:10A64000287A01287ED0022805D0032838D0104867
+:10A650000C49853017E11C270726002CB0D0A088B4
+:10A66000FDF7D1FB0090002804D1094805491330BB
+:10A6700010F071FD287B8007800F0128A0791CD085
+:10A68000400809E02C9E00001A030000440D002041
+:10A6900027040000E9E0E3E04000A071FD2108404C
+:10A6A000297B4907C90F49000843A0710098802100
+:10A6B000807F084300998877E7E001210843ECE7B1
+:10A6C00013270B26002CA6D0A088FDF79CFB00903A
+:10A6D000807F8007800F012807D00021A0880022FA
+:10A6E00001F022FB050006D101E00121F6E7FB495C
+:10A6F000FB4810F030FD0098807F8007800F012814
+:10A7000050D0E86A81788907890F0129A1794BD057
+:10A7100049084900A1718278FD255207D20F2940CE
+:10A7200052001143A171E322114002785207D20E68
+:10A730001143A171DF2211404278D207920E1143DA
+:10A74000A17100E033E00021E171C178217242790A
+:10A750000179607AD30740084000DB0F1843930764
+:10A76000DB0F28405B0018435207FB23D20F184031
+:10A77000920010436072A07ACA0740084000D20FCE
+:10A7800010438A07D20F2840520049071043C90FCF
+:10A79000184089000843A07200980078232874D9D3
+:10A7A0002621C4E0A86AADE701221143B2E7297B64
+:10A7B000CC48022911D017270C26002C50D0012993
+:10A7C00012D003291FD0042920D005291ED09320A0
+:10A7D000C249C00010F0BFFC23E019270726002C57
+:10A7E00053D00121A17105E00121A171E17989080E
+:10A7F0008900E171017CCA094906D201890E49002C
+:10A800000A4302740DE00220A07106E0687B000795
+:10A81000000F8030A07105291DD0E07980088000EC
+:10A82000E071A088FDF7EFFA0546007821282CD0CA
+:10A83000232804D0AA48A949573010F08CFCA87FDF
+:10A840008007800F01280ED00021A08801F093FA24
+:10A85000222128466CE0E07980088000401CDFE778
+:10A860000498068017E00121EFE7002C01D06888EA
+:10A87000A080287A032832D004280FD005285AD087
+:10A8800097489649B03010F066FC0498002C06807A
+:10A8900001D027806680002005B0F0BD15270C266A
+:10A8A000002CDDD0A088FDF7AEFA807F8007800FF6
+:10A8B000012807D00021A088002201F035FA050008
+:10A8C00007D101E00121F6E785488449763010F090
+:10A8D00042FC0622A11DA86907F036FAD5E7162723
+:10A8E0000726002CBCD0A088FDF78DFA0090807F51
+:10A8F0008007800F012807D00021A088002201F0E6
+:10A9000013FA050007D101E00121F6E77448734905
+:10A91000843010F020FC2878C00601D5022000E029
+:10A920000120A071009800782328AED92721009833
+:10A93000FDF7A0FAA9E717270C26002C90D0A088D5
+:10A94000FDF761FA00906D7A002804D164486349EC
+:10A95000973010F000FC0621A01D10F0CFFA002067
+:10A96000A071207A032108432072FB21084000993E
+:10A97000C97FC907490F08432072680685D5E07969
+:10A9800004210843E071A07AE90740084000C90F9C
+:10A990000843E17A2A0749084900D20F1143FD22F2
+:10A9A000AB07DB0F10405B001843A072E806C00F36
+:10A9B000114040000143E17267E710B50446807919
+:10A9C00090B08009012804D045484449C93010F0AE
+:10A9D000C2FBFFF7BBF801206946087042480890A7
+:10A9E00042480190201D0290601C0B900AA9684605
+:10A9F000FDF71CF9002804D039483849D43010F04C
+:10AA0000AAFB0322601C0B9910F01BFA10B010BDBA
+:10AA100010B5364C002805D001461022204610F013
+:10AA200010FA0120207410BD10B50446FFF78EF80F
+:10AA300010222E49204610F004FA10BD70B50025F2
+:10AA4000284C00281CD02A49884207D301218904B8
+:10AA5000884205D327490968884201D210250DE0B4
+:10AA6000062107F05BF9411C07D01E4940394865B3
+:10AA7000207C80210843207400E00725284670BD13
+:10AA8000207C4006400EF6E7F3B5002089B00D4665
+:10AA9000029000290AD0164885421CD30120800468
+:10AAA000854203D313480068854214D30998FDF703
+:10AAB000AAF9060003D03078222826D102E00E48F9
+:10AAC0000BB0F0BD002D19D1B07FC10903D08007B4
+:10AAD000800F022812D01020F2E700002C9E000008
+:10AAE0004D040000500E0020FFFF0000300D00203C
+:10AAF00000C001002800002002300000B07FC10625
+:10AB000001D4010703D5002D01D00820D8E7FE4964
+:10AB1000097CC90717D1F17F490701D50D20CFE77F
+:10AB20008007800F01280CD000210122099801F034
+:10AB3000FBF8070007D0B07F8007800F022804D001
+:10AB40000DE00121F1E71120BAE7002D07D02A46D8
+:10AB500039463046FEF764FF02900028B0D1EB483A
+:10AB6000F8F7E6F9040003D1E949EA4810F0F3FAEE
+:10AB70000A2020700998206238468830A060B07F93
+:10AB8000FB218007800F012829D0002D3DD0022015
+:10AB90002071381DE06038780007400F2074387845
+:10ABA000C006C00F6074A07C2A788008D20780009D
+:10ABB000D20F1043A0740840F17F01AAC907490FC2
+:10ABC0000843A074A878E07469462846FEF769FF38
+:10ABD00068460079207568460078607519E00120A4
+:10ABE0002071207B2A788008D2078000D20F104382
+:10ABF0002073084029788907C90F8900084320730A
+:10AC000024213046FDF736F90BE0032020710520A2
+:10AC1000207325213046FDF72DF9B07F4006400E08
+:10AC2000B07703A92046FDF701F8022806D00028D6
+:10AC300004D0B848B6492B3010F08DFA02983FE79F
+:10AC4000FFB5B54A0E4607CA97B002AB07C3002747
+:10AC500001970C971798FDF7D6F8050005D02878CE
+:10AC6000262804D008201BB0F0BDAC48FBE7A87F25
+:10AC70008007800F012807D000210022179801F0DB
+:10AC800053F8040007D101E00121F6E7A148A049EB
+:10AC9000623010F060FAA87F8007800F16900128BC
+:10ACA00014D0022824D09B4899497B3010F053FAE5
+:10ACB00001210022852E31D01EDC002E26D0812ECF
+:10ACC00026D0822E26D0832E1ED125E0002EEFD155
+:10ACD00021462846199AFEF7A3FE0028C3D11998E9
+:10ACE0008078019019980078C007C00F0C90DFE7BA
+:10ACF0001998002808D1DBE7862E11D0882E11D0B4
+:10AD0000892E11D08A2E11D00720ACE710460EE014
+:10AD100008460CE002200AE0032008E0052006E0D7
+:10AD2000062004E0082002E0092000E00A200022BA
+:10AD3000227101216A461176211D0791002801D058
+:10AD400020710BE1169801280CD0A66AE06A022255
+:10AD5000012111900020A0602846173002291AD046
+:10AD6000012119E0E66AA06A119003203070207872
+:10AD7000FB23C006C00F7070B07801221840019B01
+:10AD8000F37080080C9B800018430221B0700020F3
+:10AD900070713071DEE70021890009190861681CB3
+:10ADA000022A01D0012100E000218900091908616F
+:10ADB000B0788007800F01285ED1119880788007D5
+:10ADC000800F012858D1119800790190119840798D
+:10ADD0000090169801281DD0317908A80174717966
+:10ADE000017508A8027C01980099024008A8007D1E
+:10ADF0000840149010433FD049491A98884207D31D
+:10AE000001218904884215D346490968884211D234
+:10AE1000102028E70CAA0DA91998FEF742FE08A8F1
+:10AE2000007C01990840307108A8007D0099084015
+:10AE30007071D6E720463C3021460090F0311698DC
+:10AE40000191022834D000211A9B20460C33FEF7D2
+:10AE500091FE0028DDD12046503021460090F4318B
+:10AE600016980191012825D0002120461A9B149A9A
+:10AE7000FEF780FE0028CCD111988078400702D4DC
+:10AE8000E87FC0072BD0169902A8012914D0119988
+:10AE900009784900405A21780907490F4900C840FC
+:10AEA0008707BF0F2AD0012F14D0022F0FD113E034
+:10AEB0000121C9E70121D8E721780907490F490095
+:10AEC000405A119909784900C8408707BF0F032FDE
+:10AED00004D004E0022711E001270FE002271698B2
+:10AEE00001280BD1B078FB210840E97FC907490F41
+:10AEF0000843B07020780007400F30702078400879
+:10AF00004000207011990FE0500E0020440D0020E9
+:10AF10002C9E0000A90500001CB4010002300000B6
+:10AF200000C001002800002049781022C907C90E7E
+:10AF3000D243114308402070C00622D4022F20D0F3
+:10AF4000012F20D00020A061E061206260622046D5
+:10AF50001830A060E87F40084000E877204606A946
+:10AF60008830FCF73FFE002805D0022803D0B44902
+:10AF7000B44810F0F0F825212846FCF77BFF0020AC
+:10AF800071E6032008E020460D211B300FF0B6FFCC
+:10AF900020461830A060042069460875E87F01212A
+:10AFA0000843E87705AA29461798FEF7B7FDD5E7C5
+:10AFB000F0B587B015460F0004460DD0A248854273
+:10AFC00007D301208004854206D3A048006885424B
+:10AFD00002D2102007B0F0BD2046FCF714FF060097
+:10AFE00004D03078272803D00820F3E79848F1E709
+:10AFF000B07F8007800F012807D000210022204663
+:10B0000000F092FE040007D101E00121F6E78D482F
+:10B010008B491F3010F09FF80020002F05D0022F21
+:10B0200008D0012F11D00720D4E701216A46117101
+:10B03000A06018E0234618336946A3600871102207
+:10B04000294618460FF0FDFE0DE021461831A1609B
+:10B0500069460871A061E0612062606206212846AD
+:10B0600006F05CFEA0612078C10714D040084000C3
+:10B070002070022069460870204618300290703017
+:10B08000FCF7B0FD022806D0002804D06D486C49BA
+:10B09000423010F060F825213046FCF7EBFE00202E
+:10B0A00098E7F8B515460E460746FCF7ACFE0400D7
+:10B0B00004D02078222803D00820F8BD6448F8BDC9
+:10B0C000A07F8007800F022802D06148C01CF8BD15
+:10B0D0005D4886420ED3012189045C4A8E4202D328
+:10B0E00013689E4206D3854204D38D4204D3106870
+:10B0F000854201D21020F8BD00953288B31C21464C
+:10B100003846FEF7B0FD112816D00028F3D1E17FB4
+:10B110002A7C4908D2074900D20F1143E1772A7CE3
+:10B1200049079206490FD20ED2001143E177A17F61
+:10B130004906490EA177F8BDA17F0907FBD4204637
+:10B140000822B11C34300FF07CFE30886086204627
+:10B150001022294622300FF074FEE07FFD210840C6
+:10B16000297CC907890F0843E077287C4108202003
+:10B170000155A07F08210843A0770020D7E770B5CC
+:10B1800094B00D460646002B02D0072014B070BDC7
+:10B19000FCF739FE040007D02078222802D3A07FD4
+:10B1A000400603D40820F1E72948EFE7002D19D025
+:10B1B0002D216846017046801022294601A80FF013
+:10B1C00040FEE07F297C4008C9074000C90F0843C2
+:10B1D000E077297C40078906400FC90EC900084363
+:10B1E000E07703E02E2168460170468009A9684691
+:10B1F00000F0A3FCA17FBF221140A177C6E710B5E4
+:10B200000C46FCF700FE002805D0104909688C4266
+:10B2100003D2102010BD0E4810BD2146FEF7FEFCE3
+:10B22000002010BD05E00278401C002A01D000205B
+:10B2300070470A46491E89B2002AF4D1012070479E
+:10B240002C9E0000ED06000000C001002800002038
+:10B250000230000030B50346072903D00620DA7813
+:10B260001C7916E00320FAE707290BD05500ED18EA
+:10B270006D79072D01D0401EC0B2521CD2B2092AEE
+:10B2800007D105E05500ED186D79072DF3D0F4E7EF
+:10B2900000222546641EE4B2002DE5D130BDFFB585
+:10B2A00081B00C461646114620460A9F0B9DFFF7BB
+:10B2B000D1FF00280AD02079092803D3FEA1A020BD
+:10B2C0000FF049FFA078C00907D019E0072E02D07F
+:10B2D000112005B0F0BDFD48FBE701982880381D1E
+:10B2E0006880002068712871EF80049828812846C2
+:10B2F00000F04BFC002803D1EFA1AD200FF02BFF95
+:10B30000E07821794018491CC0B22171092801D385
+:10B310000938C0B24000001946718179F12249080C
+:10B320004900114081710020D3E7FFB583B0164674
+:10B330000F461C46002203210C9D039800F0F4FCEC
+:10B34000010008D033463A46019500940398FFF770
+:10B35000A6FF07B0F0BDDD48801EFAE7F0B5054650
+:10B3600016460F4650888DB00022032100F0DCFC09
+:10B37000040003D1D0A1DF200FF0EDFE00206946CC
+:10B380000871A078400603D1CBA1E3200FF0E3FEC3
+:10B39000042F5ED32A78D007C017401C06D16178ED
+:10B3A0006B78994255D12178090752D00121142A8E
+:10B3B00046DA012A42D0122A02D0132A40D128E0CC
+:10B3C0000C2F3DD1A2785206520E012A38D0207897
+:10B3D00000090001401C20706878607068460171A7
+:10B3E00068792A790102114368460181E879AA79CE
+:10B3F0000102114368464181687A2A7A01021143A9
+:10B4000068468181E87AAA7A010211436846C181BF
+:10B410001AE0062F14D120780009000120707188ED
+:10B42000012001F0EAF8022168460171C91E01817C
+:10B4300068792A790102114368461FE0062F0AD075
+:10B440006A461279002A1BD07088324601A9FDF79E
+:10B4500020FB0DB0F0BD207800090001207071883C
+:10B46000012001F0CAF802216846017168792A7941
+:10B4700001021143684601810021C9434181E3E78C
+:10B480000028E6D07488684681766978C176022102
+:10B4900081830021C18304A8052200900623114660
+:10B4A0002046FFF742FF0028D3D089A1D6200FF015
+:10B4B00052FECEE7F7B58CB015460C990D98FAF709
+:10B4C00041F9C0B2082850D10020694688856888B3
+:10B4D0000022032100F028FC040004D1FF2076A103
+:10B4E00063300FF038FE01230021E07822790BE071
+:10B4F0004600361976799E4201D1491CC9B2401CDA
+:10B50000C0B2092800D100201646521ED2B2002E29
+:10B51000EED1002902D117206946888504AB023399
+:10B520000BAA00950C990D98F8F7B6FB0006000ED3
+:10B5300007D002281BD0032817D0FF205EA1893036
+:10B5400011E06846808D00280FD002A9019100907B
+:10B550006888042301222146FFF7A1FE002804D0B9
+:10B56000FF2055A176300FF0F6FD0FB0F0BD6878E2
+:10B57000102108436870F8E700205A49024643004A
+:10B58000401CCA520828FAD3704700218170017804
+:10B5900009090901017000214170C17001717047F2
+:10B5A00070B50D460022032100F0BEFB040004D15B
+:10B5B000FF2041A1CF300FF0CEFDA0786906C00971
+:10B5C000C001490E0843A07070BD704710B5014618
+:10B5D000012001F012F810BD3EB58DB2002203210A
+:10B5E000284600F0A1FB040004D1FF2032A1E43082
+:10B5F0000FF0B1FD2078694600090001207002209B
+:10B60000087039488880C88000222846FDF741FA32
+:10B610003EBDF7B505460078002700090C463E46BA
+:10B62000012804D0FF2024A1F3300FF094FD287AE4
+:10B6300003280CD0412020A1C0000FF08CFD0298FF
+:10B64000002C068001D0278066800020FEBDEA899C
+:10B65000702710460A3086B2002C0AD06888A08075
+:10B66000A8892081E28020460A3029690FF0E9FB91
+:10B67000E5E702980680E8E7F8B543680246D9791D
+:10B680009C79090221435C7A1E7A25025C88981D08
+:10B690003543241FA14238D11B79022B35D1042D0B
+:10B6A00034D0052D3DD0062D34D0402D2DD3061D90
+:10B6B0000F461446284619E07372635C6C3263616E
+:10B6C000705F636F72652E6300000000043000003D
+:10B6D0007372635C6C326361705F636F72652E635B
+:10B6E00000000000680E0020FFFF000000F0E3F9FA
+:10B6F00008280AD01120207003202072A581E7813C
+:10B7000026616078082108436070F8BD001DFFF7CE
+:10B71000D1FEF8BD031D50880A461946FEF771FE9A
+:10B72000F8BD001DFFF71AFEF8BD70B50D468CB0D0
+:10B7300006460022032100F0F7FA040031D02078F9
+:10B740000007000F01282ED0122069468874607807
+:10B750000523801CC874082088822888C8826888CD
+:10B760000883A8884883E888888302A90C2001916F
+:10B7700000901A4621463046FFF791FD00280ED171
+:10B78000F02300223146012000F090FE20780009CD
+:10B790000001401C20706078801C607000200CB09C
+:10B7A00070BDCB48FBE71120F9E770B50D468CB0B2
+:10B7B00006460022032100F0B7FA040006D02078E4
+:10B7C0000007000F012803D00820E8E7C048E6E79B
+:10B7D0001321684681746178C17402218182C58217
+:10B7E00002A906200523019100901A462146304601
+:10B7F000FFF755FD0028D2D1207800090001207004
+:10B800000020CCE7F3B581B00D460022032101985A
+:10B8100000F08AFA00260446002803D1AD49AE485C
+:10B820000FF099FC2079A8423BD2AB48A949401CB3
+:10B830000FF091FC35E0E07841000F19401C797958
+:10B84000C0B20091E070092801D10020E070207999
+:10B85000401E2071B879C00708D0009801990428CB
+:10B8600015D09C49822018310FF075FCB87900077B
+:10B87000410F08D0400F019904280CD095498F2022
+:10B8800018310FF068FC009807280AD107E0084635
+:10B89000FEF74CFEEAE70846FEF713FEF3E7761CD8
+:10B8A000F6B228466D1EEDB20028C4D13046FEBD6A
+:10B8B00010B50022032100F037FA040004D1B520AE
+:10B8C000844980000FF047FCE07821794018C0B22D
+:10B8D000E070092801D30938E07000202071A078B9
+:10B8E00080210843A07010BDF8B517460D46002210
+:10B8F000032100F019FA040005D0002D0CD0002F10
+:10B9000007D0062006E0072D01D00620F8BD032051
+:10B91000F8BD0820A84204D86F486E4942300FF0A5
+:10B920001AFC29462046FFF795FC0646002F28D032
+:10B93000002E26D1E07821791CE0420012195379BB
+:10B94000072B03D093791B075B0F04D0401CC0B2B8
+:10B9500009280CD00CE0400000198079F123184030
+:10B960006B071B0F1843907100290AD104E00020D7
+:10B97000491EC9B20029E0D1574856495A300FF044
+:10B98000EAFB3046F8BDF8B50D460022032100F071
+:10B99000CBF9040004D150484E4968300FF0DBFB6E
+:10B9A000681E052804D34C484A4969300FF0D3FB80
+:10B9B0000921E2782079002310E0560036197779C2
+:10B9C000AF4206D1B17949084900B1715B1CDBB2C5
+:10B9D0001146521CD2B2092A00D100220646401E4E
+:10B9E000C0B2002EE9D1092905D248000019817999
+:10B9F0000122114381711846F8BD10B50446402854
+:10BA000001D2072010BD00F056F8082802D03120DE
+:10BA1000000210BD0021314802E0491C082903D270
+:10BA20004A00825A002AF8D1082903D0490044521A
+:10BA3000002010BD042010BD10B5402801D2072001
+:10BA400010BD00F038F8082805D00021234A400036
+:10BA50001152084610BD052010BDF0B58BB016463A
+:10BA60000C00074607D0002E05D06188402904D27B
+:10BA700007200BB0F0BD1020FBE72088002801D084
+:10BA8000172801D90C20F4E7084600F014F808281C
+:10BA90000FD0258803A82A46314602300FF0D1F98D
+:10BAA00001A8009062882B4607213846FFF73DFC2D
+:10BAB000DFE70520DDE701460020084A02E0401CE0
+:10BAC000082803D24300D35A8B42F8D170470000B4
+:10BAD00002300000B8B60000AD020000680E002081
+:10BAE00000B51E2827D00FDC0C2820D008DC03006E
+:10BAF0000FF052FC0913211521211B1B17192100DE
+:10BB0000122818D1072000BD302814DD3A38030070
+:10BB10000FF042FC030F11091100002000BD214865
+:10BB200000BD042000BD0D2000BD0F2000BD082079
+:10BB300000BD112000BD032000BD10B50C4604F06F
+:10BB4000A0F800281ED0204602F013FE002816D0D0
+:10BB500022780E2A0DD00F2A0BD0022A09D0032AF0
+:10BB600007D0102A09D010A17E200FF0F4FA00208F
+:10BB700010BDA078FFF7B4FF10BD112010BD0AA1C1
+:10BB80008420F2E708A18A20EFE710B502F0A2FCBA
+:10BB900010BD10B502F0EDFD10BD10B502F01AFD9C
+:10BBA00010BD0000023000007372635C686F737434
+:10BBB0005F6863692E630000F8B5054606ACC1CC2A
+:10BBC000E44C21706270A370E070681C4208277119
+:10BBD0005200E14B66710021880000198446026220
+:10BBE000605C40008218002D0AD0002005E0664607
+:10BBF0004700366A401CF353C0B2665C8642F6D8F2
+:10BC0000491CC9B20629E7D30026D21C9708B00008
+:10BC1000BF0000198760304600F02AF9A15D761C4C
+:10BC20004843C219F6B2062EEFD3501B80B2F8BDBE
+:10BC3000F0B504468C46C7490020A500FF23024604
+:10BC40006D18C54E0C5D0BE02F6A5100795AB14258
+:10BC500004D1401CC0B2FF2B00D11346521CD2B2FB
+:10BC60009442F1D8002801D061460B70F0BD70B548
+:10BC7000B84C0023655CA678B54200D10346890024
+:10BC800009199D420AD90C6A5E00A45B844202D164
+:10BC90001370012070BD5B1C9BB2F2E7002070BDE9
+:10BCA000FFB583B00C9C1F460D46060009D0002D41
+:10BCB00007D0F01C80088000B04204D0102007B0EC
+:10BCC000F0BD0E20FBE70598A04201D8A74201D99C
+:10BCD0000720F4E701460094019423463A460020E9
+:10BCE0000294FFF769FF2988814207D0814201D27F
+:10BCF000042100E0092128800846E0E7009401942F
+:10BD000023463A46029430460599FFF755FF2880AE
+:10BD10000020D4E710B5044600F0B4F8002801D0A4
+:10BD2000E0B210BDFF2010BDF8B505468A481646A2
+:10BD30000C46854201D0062C01D30020F8BD002717
+:10BD400069460F7028466A462146FFF790FF002893
+:10BD50000DD068460178204600F09CF8002EEDD00A
+:10BD60000028EBD12146284600F0A0F8F8BD38465F
+:10BD7000002EF7D1F8BDF8B505460C460020764EEA
+:10BD80006946764F0870B5423BD0062C01D3072098
+:10BD9000F8BD0A4621462846FFF769FF002830D043
+:10BDA00068460178204600F075F823000FF0F4FA99
+:10BDB000060404090C11161B01462846FEF742FA38
+:10BDC00015E0FDF735F812E001462846FFF7FDFBC8
+:10BDD0000DE001462846F7F7E4FE08E00146284654
+:10BDE000F9F73AFB03E05EA17C200FF0B4F9594A61
+:10BDF0006846A10000788918096A40000E520020A8
+:10BE0000F8BD3846F8BD5A4A1268914201D2102056
+:10BE10007047062801D30720704708720020487237
+:10BE20007047F8B5044652480068844201D2102099
+:10BE3000F8BD207A474A83009B18617A464D125C10
+:10BE400011E01E6A4F00F65BAE420AD04A1C6272D5
+:10BE50001A6A4B00D25A228000F01CF86060002061
+:10BE6000F8BD491CC9B28A42EBD861720520F8BD01
+:10BE70000EB5404B40000ECB0091029301926946F3
+:10BE8000085A0EBD33498978814201D90120704793
+:10BE90000020704770B50C460546FFF7E9FF2D4AB4
+:10BEA000A900891889686043401870BDF8B5044638
+:10BEB0000E4600206946087005462046FFF7E2FF5F
+:10BEC000002803D126A1F3200FF045F92148214B8A
+:10BED000815D8278B000C718914209D1E0B269460D
+:10BEE0000870396A4000085A1B49884206D02EE083
+:10BEF00069463046FFF79CFE002828D06846007847
+:10BF0000396A40000C52684601783046FFF7C2FF9C
+:10BF1000054633000FF040FA060404090C0F14170D
+:10BF200029462046FEF760F911E0FCF75EFF0EE0BF
+:10BF3000FFF72BFB0BE029462046F7F7F9FD06E05B
+:10BF4000F9F783FA03E006A162200FF004F928460E
+:10BF5000F8BD0000780E0020FFFF00000230000056
+:10BF60007372635C686F73745F636D2E63000000AF
+:10BF70002800002028B401008107C90E002808DA33
+:10BF80000007000F08388008C24A80008018C06986
+:10BF900004E08008C04A800080180068C84000069D
+:10BFA000800F7047BD4948788978884201D3401A8C
+:10BFB00002E02122511A0818C0B27047B749233154
+:10BFC00048788978884201D3401A02E02122511A28
+:10BFD0000818C0B27047B14946314878897888421C
+:10BFE00001D3401A02E02122511A0818C0B270474A
+:10BFF000A94910B50C310868FF22120290430122B2
+:10C00000D20310430860A54900202331487088708E
+:10C01000233948708870463148708870A04806F00F
+:10C02000BCF89F48401C06F0B8F8F6F7A3FB00F0F8
+:10C0300028F910BD20207047B4E770B50C460546BE
+:10C040000026FFF7AFFF9549A04214D30A46203AD5
+:10C0500000232046641EE4B200280BD08878105CD0
+:10C06000287088786D1C401CC0B288702128F0D1DF
+:10C070008B70EEE7012600F004F9304670BD2020F9
+:10C0800070479BE770B50C4605460026FFF796FF04
+:10C0900082492331A04214D30A46203A0023204685
+:10C0A000641EE4B200280BD08878105C2870887871
+:10C0B0006D1C401CC0B288702128F0D18B70EEE757
+:10C0C000012600F0DEF8304670BD2021017000200E
+:10C0D000704710B50446FFF77EFF2070002010BDAA
+:10C0E00070B50C460546FFF776FF6C494631A04215
+:10C0F00015D30A46203A00232046641EE4B20028E5
+:10C100000BD08878105C287088786D1C401CC0B2F9
+:10C1100088702128F0D18B70EEE7002400E0614C9C
+:10C1200000F0AFF8204670BD70B50C4605462129D9
+:10C1300004D9FF205CA147300FF00DF85548406846
+:10C14000103840B2FFF718FFC6B20D20FFF714FFFA
+:10C15000C0B2864207D2FF2053A14D300EF0FBFF44
+:10C1600001E0F6F74AFB21462846FFF766FF002864
+:10C17000F7D070BDF8B507464948484C401E474EB9
+:10C180000078254646362335002806D1A9786878F8
+:10C19000212200F06BF800280ED0A17860782122CF
+:10C1A00000F064F8002814D0B1787078212200F0F3
+:10C1B0005DF8002828D033E038496878C91C0F544E
+:10C1C0006878401CC0B26870212829D100206870AE
+:10C1D00026E03249607820390F546078401CC0B2A4
+:10C1E0006070212801D1002060702D4F7F1E3878AB
+:10C1F000002815D0A1786078212200F037F80028B7
+:10C200000ED0002038700BE02449707826310F548E
+:10C210007078401CC0B27070212801D1002070706D
+:10C22000A9786878212200F021F800281DD0A17893
+:10C230006078212200F01AF8002816D0B1787078C2
+:10C24000212200F013F800280FD0F6F7B8FA1448AE
+:10C2500005F0ABFF01214903884203D016A1C1209C
+:10C260000EF079FF0E4805F0B8FFF8BD401C88427B
+:10C2700005D0904201D1002901D000207047012053
+:10C28000704710B5064805F090FF002801D1F6F779
+:10C2900085FA10BD00ED00E000E400E0F00E0020A3
+:10C2A00069000020072000007372635C736F635F96
+:10C2B00072616E642E6300007372635C736F635F00
+:10C2C00072616E642E630000FEB5F54C074660682F
+:10C2D000FF213E0181552178FF2913D00901083142
+:10C2E00041583246491E083209020192090A805813
+:10C2F00000F0CCF9002802D02478254615E06168CA
+:10C30000207888552770FEBDE5484268019811588D
+:10C31000280100900830105800F0B8F9002806D124
+:10C32000DF482C46416800980D5CFF2DECD1DC48BD
+:10C330002101406885554754FEBD70B5D84A044672
+:10C340000020157A53680AE00201561C9E5DA64241
+:10C3500003D10C329A588A4204D0401CC0B28542A4
+:10C36000F2D8FF2070BDF8B5CD4F3E7801F00AFE3F
+:10C370000146FF2E68D034012546786808354059BB
+:10C3800000F084F9022802D9786840595AE0C4497B
+:10C390004868025D0A70A11C425C002A0CD0521E43
+:10C3A000425441590122D20589180902090A415112
+:10C3B0003046FFF789FF30E0631CC25C0092221D0B
+:10C3C00094468258002A10D001239B029A420FD92A
+:10C3D0009205920D43595703DB191B021B0A435167
+:10C3E0006346C3589A1A920A09E0FF21C1540AE031
+:10C3F000435952039A181202120A4251002242541F
+:10C400003046FFF761FFA6480C344168C2680098C7
+:10C4100009598000125800989047A14C2078FF28B5
+:10C4200012D001F0AFFD01462078626800010830AB
+:10C43000105800F02BF9012896D920786168000186
+:10C440000830085801F091FDF8BDF8B51C461546B6
+:10C450000E460746FF2B03D392A1D3200EF07BFE9E
+:10C460008F48FF21C7604560047206740170002286
+:10C470004270104604E00201521C401CA954C0B294
+:10C48000A042F8D3F8BD70B5854C06466578207C8F
+:10C49000854203D383A1E6200EF05DFEE068A9008B
+:10C4A00046506078401C6070284670BDFFB581B072
+:10C4B0001D46FF2401F066FD794F06467978019804
+:10C4C000814203D877A1F4200EF045FE7448002184
+:10C4D000037A406810E00A019446521C825CFF2AED
+:10C4E00024D0019FBA4205D162460C328758029A85
+:10C4F00097421DD0491CC9B28B42ECD8FF2C17D0F3
+:10C5000021014B1C019AC2540B33029AC250039B67
+:10C51000634F0022012B0ED00B1DC25001239B0242
+:10C520009D4216D9AA05920D08D008E00C46E1E715
+:10C53000FF2005B0F0BD0B1DC550EFE71A465303B1
+:10C540009B190E461B0208361B0AAA1A8351920A2F
+:10C5500009E0002D00D101256B039B191D022D0A56
+:10C560000B460833C550891C42543D463E78204650
+:10C57000FFF7AAFE2878B04217D001F003FD01466C
+:10C5800028786A6800010830105800F07FF8012808
+:10C5900007D92878696800010830085801F0E5FCDF
+:10C5A00003E001F010F9F5F7AFFE0198C1E770B5AF
+:10C5B0000C46054601F0E6FC064621462846FFF7F4
+:10C5C000BCFEFF2817D0364D0401204669680830AC
+:10C5D0000858314600F05AF80121090340186968EB
+:10C5E000A41C095D400B002901D08902081800280D
+:10C5F00000D1012070BD002070BDF3B581B00F46A1
+:10C600000198FFF79AFEFF282AD0254D2E786968F9
+:10C610003246344604E0844205D026462301CC5CF1
+:10C62000FF2CF8D11CE0FF2C1AD0A64221D110011A
+:10C63000085C2870FF281AD001F0A4FC2A78014673
+:10C64000120168680832805800F020F8012809D9E2
+:10C650002878696800010830085801F086FC08E075
+:10C660000020FEBD01F0AFF8F5F74EFE01E001F04D
+:10C6700084FC39460198FFF79AFF22016968FF237D
+:10C68000541C0B558A5C3301CA54FEBD401A00028B
+:10C690000121000AC905884200D900207047000026
+:10C6A0003C0F00207372635C736F635F74696D6528
+:10C6B000722E6300F0B500241C4A01211C4B0803B4
+:10C6C000546018601B4B1C601B4C20601B480469A5
+:10C6D000E443E406E617046910252C430461184C72
+:10C6E0006160184D2960761C00E020BF1F68002F94
+:10C6F000FBD0002E03D107691026B743076190686D
+:10C700008005906801D5104A10436960A16000213E
+:10C7100019600121084A09031160F0BD10B50446F3
+:10C72000FFF7C8FF2060002010BD000000C50040DA
+:10C7300080E100E000C1004080E200E000ED00E0A8
+:10C7400000C3004000C0004000FCFFFF70B51F495F
+:10C750000A68002A17D000231D4601244A68521C8B
+:10C760004A60092A00D34D600E792246B2400E6815
+:10C7700016420AD072B60B6893430B6062B64968E2
+:10C780000160002070BD052070BD5B1C092BE5D346
+:10C790000FA136200EF0DFFCF5E7012010498005DF
+:10C7A00008607047EFF31081CA07D20F72B60121FB
+:10C7B00081400648036819430160002A00D162B62F
+:10C7C000EBE70248002101604160704770000020E3
+:10C7D0007372635C736F635F6576742E6300000031
+:10C7E00000E200E001208107086070470120810716
+:10C7F000486070471048C068C00700D001207047EB
+:10C800000D488068C00700D0012070470A48406981
+:10C81000C00700D0012070470748C069704706492B
+:10C820008A69D20306D589698907890F814201D1B6
+:10C83000012070470020704700040040F8B5F74C15
+:10C84000207EE17D88421CD00126F54D0027E07D49
+:10C85000215C14200A4642435019037C052B11D059
+:10C86000037C062B1CD0037C072B28D0437C012B98
+:10C8700033D0ECA1EE480EF06EFC207EE17D8842C4
+:10C88000E5D1F8BD0674E07D162807D0E07D401C98
+:10C89000E075491CC8B2AA5802210CE00020F7E755
+:10C8A0000674E07D162808D0E07D401CE075491C28
+:10C8B000C8B2AA5803219047DFE70020F6E70674C4
+:10C8C000E07D162807D0E07D401CE075491CC8B209
+:10C8D000AA580821EFE70020F7E74774E07D162803
+:10C8E00007D0E07D401CE075491CC8B2AA5807215A
+:10C8F000E1E70020F7E770B50024CE4E0C207072FF
+:10C90000CD4825464473047328300476C475CB485B
+:10C9100005F043FCCA480575F572CA49601E886077
+:10C920007571B570F57035717570C748E839057067
+:10C9300045701420604340180574641CE4B20B2C4D
+:10C94000F7D30120F5F7E0FF0020F5F7DDFF012028
+:10C95000B071F5F7A3FCBD48F5F7B2FCBC4C2070F4
+:10C96000BC48F5F7ADFC6070F5F76EFF70BD10B513
+:10C97000F5F795FFB64C2078F5F7C0FC6078F5F731
+:10C98000BDFCAC4C207A002803D0F5F746FD002012
+:10C99000207210BD70B5A74CA079002804D0A1A1C9
+:10C9A000AD480EF0D8FB70BDE07A002803D19DA100
+:10C9B000AA480EF0D0FB0126A6710025E572607A28
+:10C9C000042114225043964A801801749D488168BE
+:10C9D000491C04D0691E81600120F5F795FF0020F5
+:10C9E000F5F792FFF5F776FF05F018FDF6F777F803
+:10C9F0009B480560056001209A49C0030860F6F76E
+:10CA0000EDF891480078022804D0032804D1E0789A
+:10CA1000002801D0A67000E0A570F6F74CF870BDB4
+:10CA200003467F490B20142242435218203A127FBA
+:10CA3000002A04D0401E0006000EF4D170471422D4
+:10CA4000424351180A46803AD366012220390A77B8
+:10CA50007047012805D0032805D1002903D1002003
+:10CA600070470029FBD010B4724C00236370764AE3
+:10CA7000002890700CD002280AD007291AD208008A
+:10CA800078440079001887441505070D0F1113002D
+:10CA9000D37003E01B2000E03A20D07001206070CA
+:10CAA00010BC70475820F8E77720F6E79620F4E7A7
+:10CAB000B520F2E710BC0020704710B562484078FE
+:10CAC000F6F714F880B210BD411E1422504310B581
+:10CAD000534A8418203C0A2902D8207F002803D119
+:10CAE00050A161480EF037FB207F012804D0B3200D
+:10CAF0004CA180000EF02FFB0020207710BD70B5F8
+:10CB00004D4C607B217B884201D1012500E000254E
+:10CB1000F5F785FFF5F7EAFF617B227B914201D1B2
+:10CB2000012100E00021A942EBD170BDF7B5064616
+:10CB3000481E84468EB0C0B2142205905043384A35
+:10CB400085180495287C2D1D07282AD1334C0027F1
+:10CB5000E07D227E824221D0235C059A934201D15E
+:10CB6000012701E0002F04D0162811D0421CA25C3E
+:10CB7000225416280ED0401C227EC0B28242EBD135
+:10CB8000002F0BD0207E002806D0207E401E04E01F
+:10CB90000022ECE70020EFE716202076049801221F
+:10CBA00002746046234C0A2813D8142041431C48C1
+:10CBB00008182038007F00280BD00498007C01283A
+:10CBC0000BD00498007C012803D01098807A0128AB
+:10CBD00007D014A125480EF0BEFA1098807A0128DB
+:10CBE0006DD104980E4B007C022843D00B4C207E64
+:10CBF000162870D0207EE17D401C884203D109A117
+:10CC00001B480EF0A8FA049901204874217E05986B
+:10CC10006054207E162862D063E0000038110020A6
+:10CC2000541100207372635C72656D2E6300000006
+:10CC3000D40500005C1200201011002068120020B2
+:10CC4000201100203C1200207A00002067C3000061
+:10CC5000780000203DC800007D0200005E02000058
+:10CC600000F5004080E200E0CB0200001503000068
+:10CC700022030000607A059A0146904206D00146E0
+:10CC800014277843C018807C9042F8D1627A82429F
+:10CC900008D1617A14225143C918897C617201213B
+:10CCA000A17207E014224243D21814277943927CE0
+:10CCB000C9188A7414220C215043C018817410982A
+:10CCC000007A06281DD201007944097949188F4459
+:10CCD0000C161412100EE07D002890D093E700206F
+:10CCE00001E0207E401C2076B5E000210FE0B42159
+:10CCF0000DE073210BE0322109E00A2107E0062153
+:10CD000005E0FF20FDA1E0300EF025FA002110988B
+:10CD100002910068401A28601099097A002912D0FF
+:10CD20000221401A0102090A29601098026840682D
+:10CD300010180002000A68601098807A0228109883
+:10CD400003D0007B71E00421EBE7007A002812D0C9
+:10CD500002220298121810984368104610301818D2
+:10CD60000A90E948029B4078984202D9E378002B68
+:10CD700003D00A9805E00422EBE7029BC31A0A9845
+:10CD80001818637A10300C2B1CD0637A14277B435D
+:10CD9000DE4FDB195B68994214D0DD4F617ABC46E7
+:10CDA00014235943D94BC9184B6889689B1B891BAD
+:10CDB0001B0209021B0A090A984237D8634535D875
+:10CDC000614533D831180A980123081A0002000A75
+:10CDD000286010998018C9680002000A471ACD4AD5
+:10CDE0009B05BC469F4201D2384610E00F1A9F4275
+:10CDF00001D260460BE0944503D9511A0818401C33
+:10CE000005E0974206D9101A4018401C40420028FD
+:10CE10005FDC03E0B9A1C0480EF09DF929680A98CB
+:10CE200008180002000A686000202872686810274D
+:10CE300010300002000A68601098407AA8721098BA
+:10CE4000007A687203280ED200280CD0FFF7D2FCBB
+:10CE5000002803D007E0002011B0F0BD0298422165
+:10CE60000F1A32200290A8490878012801D003281F
+:10CE700009D148780299884205D9E178002902D180
+:10CE80000299401AC7196B6828689B1B801B9C4637
+:10CE900001021B029E4A090A1B0A8F4219D8174633
+:10CEA000914216D8BB4214D8617A0C2915D0677A02
+:10CEB00061460C22039200921422944B7A43D218BA
+:10CEC00093689B1B834216D80397977C0C2FF3D152
+:10CED00073E0059801F04CF9BDE70498022205992A
+:10CEE0000274627A0C2A00D0627A82746172012024
+:10CEF000A07211B0F0BD0C2F5FD0002238469446CE
+:10CF00001422824B4243D21853689B1B8B4225D27A
+:10CF1000907BAB7A98421BD804980521059D01743B
+:10CF20007E4C207E16280FD0207EE17D401C88425A
+:10CF300003D172A17A480EF00EF9207E2554207E8E
+:10CF4000162800D0CDE6CAE6E07D0028F1D0F4E74F
+:10CF500001208446907C0C28D2D102E06146002951
+:10CF60002AD03D46009014202A46424367480621B5
+:10CF7000161831741C38007E1628684816D0017EB9
+:10CF8000C07D491C814203D15CA166480EF0E3F8E4
+:10CF90006248017E4554017E16290BD0017E491C52
+:10CFA0000176B57C0098A842DDD106E0C07D00285E
+:10CFB000EAD0EDE70021F3E7009704990220534DF2
+:10CFC0000874607AB84207D104990098887405986B
+:10CFD00060720120A07221E003980C2F0FD00C2862
+:10CFE00003D146A150480EF0B6F8039814225043DE
+:10CFF0004019059981740499009888740EE00C28F2
+:10D0000003D13EA149480EF0A6F8039814225043DC
+:10D0100040190599817404990C208874012011B07D
+:10D02000F0BD70B50D46424A441900210B46101A56
+:10D030008B4103D231A13F480EF08DF83E48854226
+:10D0400003DD2EA13D480EF086F83D48854203DA07
+:10D050002AA13C480EF07FF83B48844205DA002CB8
+:10D0600001DB204670BD384800E03848201870BD0C
+:10D07000401E70B5C0B21421484324494418607B57
+:10D08000062813D201007944097949188F44020C0B
+:10D090000A080604002067E0B42010E073200EE0C8
+:10D0A00032200CE00A200AE0062008E0FF2013A14D
+:10D0B000E0300EF050F8617B0020002954D00221AE
+:10D0C0004018616840180002000AF5F70FFD0C25B2
+:10D0D0006557174A441900210B46101A8B4103D299
+:10D0E00006A114480EF037F81348854203DD03A16A
+:10D0F00012480EF030F81248854229E07372635CE2
+:10D1000072656D2E630000007A000020541100202B
+:10D11000FFFF3F00FFFFFF00130700003811002052
+:10D1200007020000C5030000DD030000E303000068
+:10D13000FF7F841EF50300000020A107F603000016
+:10D1400000E05EF8F70300000080841E00807BE1B1
+:10D1500003DAF749F7480DF0FEFFF748844207DA93
+:10D16000002C03DB204670BD0421A9E7F24800E053
+:10D17000F248201870BDF0B5064683B0F048019023
+:10D18000457A029534687068001B0702ED483F0A33
+:10D19000001B00900C2D2DD0142029464143EA4855
+:10D1A0000122081884464168E64892058646081B15
+:10D1B000904210D3631A93420DD3024670467245D3
+:10D1C00003D900984018401C05E073450ED9411A58
+:10D1D0000819401C404200280CDA60460295857C04
+:10D1E0000198C0790028D5D003B0F0BDD049D74808
+:10D1F0000DF0B1FF0298854226D014214843D24950
+:10D200000123401802908068CE499B058C46011B83
+:10D210008646994210D3221A9A420DD3634661453D
+:10D2200003D900997144491C06E0194662452DD97D
+:10D23000091A0819401C4142002905DD0298B17AFB
+:10D24000807B814200D374460C2D15D0BE4914203A
+:10D25000454368184268121B1202120ABA420BD2E6
+:10D26000B37A827B934200D38468857C0198C0792D
+:10D270000028B9D10C2DEAD13068A042B4D0E01911
+:10D280000002000A3460706003B0F0BDA849AF48E6
+:10D290000DF061FFD8E7F0B5AD490446486885B0A8
+:10D2A000C005C00D1CD0103840B200280CDA0207AF
+:10D2B000120F083A920892005118C9698007C00EEF
+:10D2C000C1400806800F09E08108A24A8900891838
+:10D2D00009688007C00EC1400806800F002808D0EA
+:10D2E00000272078002806D0012804D0002005B0AF
+:10D2F000F0BD0127F5E72079062813D20100794413
+:10D30000097949188F44020C0A080604002018E025
+:10D31000B42010E073200EE032200CE00A200AE076
+:10D32000062008E0FF208249E0300DF014FF21794B
+:10D330000020002905D002214618814D002F02D07F
+:10D3400003E00421F8E70020E871694602AAA0681A
+:10D35000F5F7D6FB694608228A56E06801A98018CD
+:10D360000122C01C1F2801DA019209E003AAF5F787
+:10D37000C7FB6846007B002802D00198401C019042
+:10D3800000990198401810300002000A0190881B93
+:10D390000002000A00906079694688720098039044
+:10D3A000F5F73DFB009A019B121A181A6A491202FE
+:10D3B0000002120A000A8A4216D8884214D8684627
+:10D3C000FFF7D9FE00990398814205D08819000221
+:10D3D000000AF5F78BFBA0600120E979002986D0CF
+:10D3E000002FB0D005B0F0BD0020F6E7F3B58FB048
+:10D3F0005A480C460B9004F0D8FE594A0F99504FEA
+:10D400005618584D203E00280BD05748007D002864
+:10D4100003D056A158480DF09EFE207801287CD0FC
+:10D420005AE1687B16280CD0687B297B401C884217
+:10D4300003D14EA151480DF08EFE2078012804D072
+:10D440000CE0287B0028F4D0F7E7F07F002803D019
+:10D4500046A14B480DF07FFE0120F077697B0F98C5
+:10D460001422484E5143891908742078022822D08A
+:10D47000687B142148438619207930726079707274
+:10D4800032460C323146A068F5F73AFB0C20305694
+:10D490000F2804DD1F3830733068401C30600C21C9
+:10D4A0007156301DE26801905018C01C1F283EDAEA
+:10D4B00001200199F7E026494868C005C00D21D038
+:10D4C000103840B200280CDA0207120F083A92080E
+:10D4D00092005118C9698007C00EC1400806800F2C
+:10D4E00009E081081B4A8900891809688007C00E75
+:10D4F000C1400806800F002804D105201BA10002AE
+:10D500000DF029FE687B1421484386190021E0684C
+:10D510006A460691117006A900E0D3E0F5F7F0FA2B
+:10D520006A46002010560F282EDD01202DE0AEE0C7
+:10D53000FCD00000F70300000080841E00807BE127
+:10D540005C120020FFFFFF005411002013070000B1
+:10D5500000ED00E000E400E0FFFF3F006812002063
+:10D560003012002010110020201100207372635C23
+:10D5700072656D2E6300000011050000EF040000CD
+:10D58000F4040000500F0020002006994018079076
+:10D590000220B0722079307260797072A068311DFB
+:10D5A000C01C06911F2801DA012009E0F5F7A8FA4E
+:10D5B00068460078002804D0069806990068401C48
+:10D5C0000860307A062813D2010079440979491895
+:10D5D0008F44020C0A08060400200FE0B4200DE07E
+:10D5E00073200BE0322009E00A2007E0062005E066
+:10D5F000FF20FE49E0300DF0AEFD0020217900292A
+:10D6000043D002214018069071681030081807991D
+:10D61000089009180698081A0C900020F871F5F780
+:10D62000FEF904463060079820180002000AF060F6
+:10D63000787A0C2825D0797A14204143EC480818D0
+:10D6400040680899029040180002000A0390707A1E
+:10D650006946887402A8FFF78EFD0299039A091B98
+:10D66000121B09021202E34B090A120A0C98994292
+:10D6700007D8824205D80299069808180002000AC5
+:10D680003060F8790028C8D110E00421BAE704AA74
+:10D690000199F5F735FA6846007C002804D0019816
+:10D6A00001990068401C08602078B072687B1628D9
+:10D6B00006D0687B401C68730B9804F08EFD47E031
+:10D6C0000020F8E7F07F002804D0A320CAA1C00002
+:10D6D0000DF041FD0120F077CA490F9808742078B9
+:10D6E000022803D1C4A1C8480DF035FDC54E2079EC
+:10D6F00030726079707232460C323146A068F5F7AC
+:10D70000FFF90C2030560F2804DD1F3830733068C5
+:10D71000401C30600C22B256301DE1680190881820
+:10D72000C01C1F2802DA012001990BE003AA01990D
+:10D73000F5F7E6F96846007B002804D001980199C6
+:10D740000068401C08602078B072AE49012008755E
+:10D75000687B297B884224D07C7A0C2C23D0F5F777
+:10D760005EF914214C43A24961180A7C042A18D09E
+:10D770000A7C032A15D04B6889681B1A081A1B02F9
+:10D7800000029C4A1B0A000A102B0AD3114693423E
+:10D7900007D8884205D8687B297B884201D0F5F7F5
+:10D7A0008AF911B0F0BD687B297B8842F7D111B0AE
+:10D7B000F0BD10B50020F5F794F810BD10B50120AC
+:10D7C000F5F78FF810BD914800787047F1B50098D3
+:10D7D00002281ED08E4C607A0C2803D186A18D4879
+:10D7E0000DF0B9FC0026A6710125E572607A0321CF
+:10D7F00014227F4F5043C0190174F5F761F9009866
+:10D8000000280BD001282AD003287AD07AA1824898
+:10D8100045E07E480078F4F777FDF8BD7F48007F4B
+:10D82000002804D02B2074A140010DF094FC6571F8
+:10D830007A4D00202E60F5F767F8A968481C04D0DF
+:10D84000012300221846F5F795F8607A617A401CAA
+:10D85000C0B2142251437A5801219047F8BD0120EB
+:10D86000F5F752F8607900280DD06C488068401CAC
+:10D8700009D0607A617A401CC0B2142251437A58B0
+:10D8800006219047F8BD6548007F01280AD002288C
+:10D8900012D0032822D0042834D057A160480DF0BC
+:10D8A0005AFCF8BD2079002803D02671F5F70DF950
+:10D8B000E5705A480677F8BD207A002802D1F4F7BF
+:10D8C00083FD2572607A617A401CC0B214225143F4
+:10D8D0007A580021904751480677F8BD4F4F0123F1
+:10D8E000397B78680022411A1846F5F743F8207909
+:10D8F000002803D02671F5F7E8F8E57002203877A4
+:10D90000F8BD19E0454E217870680123411A0022C4
+:10D910001846F5F72FF8207A002802D1F4F754FDC5
+:10D920002572607A617A401CC0B2142251437A5841
+:10D93000002190473577F8BD607A617A401CC0B20B
+:10D94000142251437A5805219047F8BD10B5304C48
+:10D95000607A0C2803D128A132480DF0FCFB607AD4
+:10D96000617A401CC0B214225143214A525804210A
+:10D97000904710BDF0B583B00C200290F5F74FF83A
+:10D98000234C0090617A284801900C2920D0617ABC
+:10D990001420414316480918097C042918D0617ADB
+:10D9A000142251430818007C032879D0019900986B
+:10D9B0000B6849681B1A081A1B0200020D4A1B0A51
+:10D9C000000A102B6CD31146934269D8884267D85D
+:10D9D00012488068401C03D007A114480DF0BBFB1F
+:10D9E00000206071607A0C282AD121E0FCD0000070
+:10D9F00054110020FFFF3F007372635C72656D2E4F
+:10DA000063000000201100201E05000078000020A7
+:10DA10005C12002054050000A70500003C12002005
+:10DA20009B050000AE0500004C120020EA05000036
+:10DA30006078002804D0FE48C17841708178017078
+:10DA4000607A0C2815D0607A1421FA4A484380186D
+:10DA5000007C04280DD1607A0290607A01211423A1
+:10DA6000584380180174607A58438018807C607233
+:10DA7000A172F14D687B297BF04F884233D0F04E84
+:10DA8000287B142148438019007CC05D0128287B35
+:10DA900007D048438019007CC05D02282FD044E0A5
+:10DAA000FCE1142148438019807A01280AD0287BA0
+:10DAB0000221142250438019007CC155287B16286E
+:10DAC00008D009E0287B0021142250438019007CF3
+:10DAD000C1552AE0002001E0287B401C2873687BA8
+:10DAE000297B8842CCD1D74D287D00284DD0287C79
+:10DAF000C15D012928D0C05D022830D03BE0287BE1
+:10DB0000142148438019807A012803D0CEA1D1483E
+:10DB10000DF021FB297B00201422514389198872C2
+:10DB2000297B51438919097CC855287B1421484316
+:10DB30008219287B48438019017C0098FEF7F6FF84
+:10DB4000287B1628C8D1C5E7A97A012904D002216B
+:10DB5000C155002028750EE00021C1550BE0A87AC0
+:10DB6000012804D0C520B8A1C0000DF0F4FA0020AF
+:10DB7000A872297CC855287D002806D0297CB14A86
+:10DB80000098FEF7D3FF0020287502980C281ED0BD
+:10DB900014214843A7494018017C012917D10721C6
+:10DBA0000174AD4D287E16283CD0287EE97D401CAE
+:10DBB000884203D1A4A1A9480DF0CDFA297E02988C
+:10DBC0006854287E162831D0287E401C2876607A3A
+:10DBD0000C287DD0A07A00287BD00020A072617A2A
+:10DBE0001420414393480E189D49B56873680A464E
+:10DBF000F6687C32CB67966055609A4D697E002945
+:10DC000016D00226617A14228A4851430818407BB4
+:10DC100006281BD201007944097949188F440A1457
+:10DC200012100E0CE87D0028C4D0C7E70020CDE715
+:10DC30000426E7E700210FE0B4210DE073210BE09B
+:10DC4000322109E00A2107E0062105E0FF2086498C
+:10DC5000E0300DF080FA00212973687E022801D09F
+:10DC6000012810D12869009A4018821A1202120A5B
+:10DC7000422A08D93238032100026976000A286155
+:10DC80003220287308E0322906D2207A00280AD1EF
+:10DC9000F4F79AFB012005E0207A002803D0F4F77E
+:10DCA000BCFB00202072624910224878207009785D
+:10DCB000012901D0032906D101212171297B884244
+:10DCC00001D9421A1032A378002B00D0921C01E037
+:10DCD0008DE09BE02179002901D1002B5DD0944695
+:10DCE000624A00990092019A176852687F1A511A85
+:10DCF0003F0209023F0A090ABC451BD85B4A97420A
+:10DD000018D8009A914215D8297B884223D92B69CB
+:10DD1000421A9A1A1202120A101880190002000AF6
+:10DD20002A616860002914D0032028770006000EBD
+:10DD30003ED14CE000202071A070297B002925D025
+:10DD40002869401880190002000A686002202877BC
+:10DD50002EE00120E9E781420BD92A69511889197F
+:10DD60000902090A6960002801D00420DDE70220C9
+:10DD7000DBE7002B03D134A13D480DF0ECF9286915
+:10DD800080190002000A6860002004E029698919EE
+:10DD90000902090A6960287719E0287B00280FD05A
+:10DDA0002969081880190002000A68600220287793
+:10DDB00028690123811900221846F4F7DBFD09E0E8
+:10DDC000286980190002000A686000202877012075
+:10DDD000F4F79AFD607A1421484316490C22401842
+:10DDE0008256012300206968F4F7C4FD0EE001208B
+:10DDF000F4F78AFD0020F4F787FDF4F76BFD207A35
+:10DE0000002803D0F4F709FB00202072A078002836
+:10DE100004D0F4F75AFE0020E070A070607800286B
+:10DE200004D00348C178417081780170207921E0E5
+:10DE30007A00002054110020101100202F12002021
+:10DE4000500F0020201100207372635C72656D2EEC
+:10DE5000630000000C060000381100203A060000A4
+:10DE6000D01100203C120020FCD00000FFFF3F003A
+:10DE70008C060000002806D00020CF49E070097809
+:10DE8000002900D12071CD48017EC07D814203D0A0
+:10DE9000CB484078F4F738FA0120E07103B0F0BDC8
+:10DEA000F0B5C84C0746607A83B00C2803D1C6A1F0
+:10DEB000C8480DF050F9607A1421C74E48438019C4
+:10DEC000007C032804D06F20BFA100010DF043F9AE
+:10DED000C24DA868401C03D0BBA1C1480DF03BF95E
+:10DEE000607A1421484381190C20085600216A46A3
+:10DEF00000911171C01901AA6946F4F701FE6A4642
+:10DF0000042010560F2801DD012000E000200099B8
+:10DF10004018696840180102090AA9606079002860
+:10DF200004D0012300221846F4F724FD03B0F0BD0D
+:10DF300070B5AD4CAB4A0B1AA34214D3451AA54297
+:10DF400011D3934203D9101A43185B1C0BE095427E
+:10DF500004D9511A0818401C434204E0A349A448BC
+:10DF60000DF0F9F80023184670BD10B501460123E5
+:10DF700000220220F4F7FEFC10BD10B50220F4F7D9
+:10DF8000C3FC10BD10B5F4F74AFD10BDF0B58D4DC2
+:10DF90000446E87A83B0002803D18BA195480DF0A0
+:10DFA000DAF8642C4DD3944900200246091B8241C3
+:10DFB00047D39248417B007B814242D19048007D0B
+:10DFC00000283ED1687A1421834F4843834EC519F7
+:10DFD000306801AA00196946F4F792FD69460420E9
+:10DFE0000856002802DD0098401C0090A96800989F
+:10DFF0006B680A18D21A1202824B120A9A4220D86F
+:10E00000AA7C0C2A08D014235A43D2195268511AF8
+:10E010000902090A814214D3B068401C05D00120CE
+:10E02000F4F772FC0020C043B06030680019306023
+:10E03000A868009940180002000A7061012003B02E
+:10E04000F0BD002003B0F0BDF8B50646401EC5B2D5
+:10E050001420614968434418207C002803D15AA148
+:10E0600069480DF078F86548017B407B81420CD00F
+:10E07000664A14234B439B181B7CB3420CD01629D1
+:10E080000CD0491CC9B28142F3D15D48017D002901
+:10E0900064D0007CB04261D10020F8BD0021F1E7DE
+:10E0A000217C052905D0217C062902D0217C072965
+:10E0B00028D101212174C17D0023027E8A4221D012
+:10E0C0000246565CAE4201D1012301E0002B04D090
+:10E0D000162911D04E1C965D565416290ED0491C97
+:10E0E000167EC9B28E42ECD1002B0BD0117E0029D6
+:10E0F00006D0117E491E04E00026ECE70021EFE780
+:10E1000016211176617C00292AD06774C17D002315
+:10E11000027E8A4224D0425CAA4201D1012301E05E
+:10E12000002B04D0162912D04A1C825C42541629B6
+:10E130000FD0491C027EC9B28A42ECD1002B0FD00D
+:10E14000027E0146002A06D00A7E521E04E000220A
+:10E15000EBE70021EEE716220A7601E017480027D8
+:10E16000217C01299CD1617C002999D10120F8BD35
+:10E1700070B505461420184A0521684380180174BB
+:10E180000E4C207E162811D0207EE17D401C884256
+:10E1900003D116491E480CF0DEFF207E2554207E58
+:10E1A000162807D0207E401C207670BDE07D002818
+:10E1B000EFD0F2E70020F7E77A00002038110020C6
+:10E1C000780000205C1200207372635C72656D2E13
+:10E1D00063000000EF060000541100203C120020F4
+:10E1E000F1060000FF7F841E0020A107FCD0000084
+:10E1F0001307000032070000FF1FA10710110020C5
+:10E2000020110020FFFF3F006F070000500F00208B
+:10E210000702000010B509F063FC042803D009F0E0
+:10E220005FFC052803D106F0D1FE00280BD104F0D5
+:10E2300007F9032803D004F009F9032805D109F0F0
+:10E24000B0FD002801D0012010BD002010BDF0B5A8
+:10E2500085B00746002668460D4606726946384670
+:10E2600005F05CFA00287DD16846007800280BD0C4
+:10E2700009F009FDB84275D00022294638460AF057
+:10E28000CCFE00283ED120E006F077FCB842F2D068
+:10E2900000222946384608F01DF900287DD1019C4E
+:10E2A0009020005D2834002804D1607E002801D031
+:10E2B000012000E000200490204660300390807828
+:10E2C00006F08AFB002804D008E0019C2834607E18
+:10E2D000F1E7FF20FDA1DA300CF03DFF20462030B1
+:10E2E000417B00290FD0817B89070CD56E700121FD
+:10E2F0002970AE70AF80C17BA971218E2981618E9A
+:10E300006981467349E0039802A9807806F030FAE3
+:10E31000002804D1FF20EDA1EE300CF01CFF684670
+:10E32000007A002809D06E700D202870AF806846F2
+:10E33000007AE8800120A8702FE0049800282FD0F0
+:10E3400006F0B5FB00282BD068460078002806D1DF
+:10E3500001988030406A4188B94200D10670039824
+:10E36000807800E01CE006F0CAF8002803D1D7A1AD
+:10E37000DA480CF0F0FE6E700A202870AE70AF80A4
+:10E38000A07EA8716676684605F07EFA002804D063
+:10E39000D248CEA10E300CF0DEFE012005B0F0BD5B
+:10E3A0000020FBE77CB5CEA103C9CF4D002401912D
+:10E3B0000090AC7001F067FD2946EC7004204039F4
+:10E3C000088710204887C81DC84AF9304280047168
+:10E3D000C280E03844740C7084730475C0300477D4
+:10E3E0001D300522694604460CF02BFD28462146C7
+:10E3F000BC3008F0F7F97CBDF8B5BD4C0D46606047
+:10E40000217006F057F805F0D1F8FFF7CBFF207820
+:10E4100009F03AF9B4498431084681380F46064676
+:10E4200006F08CFC606808F0D8F8284604F06EFC12
+:10E430003946304609F057FC60680AF08AFE01F060
+:10E4400022FDA9480021C170F8BDFEB50E461D464B
+:10E45000144601A905F062F9002839D102988030EC
+:10E46000807A06F079F800280CD0684606F087F824
+:10E47000002806D0002C03D006F01DF8A04206D2DA
+:10E480000020FEBD91A19B480CF065FEF8E70098C6
+:10E4900005F0AAFB3146009805F0ABFBE2B2294635
+:10E4A000009805F063FD06F08FF8002804D191482C
+:10E4B00086A11E300CF04FFE68460079012807D176
+:10E4C00001A801F0E7FC8A48002180688030418281
+:10E4D0000120FEBD30B40179002904D0012907D004
+:10E4E00030BC00207047831D42880488022103E06D
+:10E4F00042880488831D0121204630BCA5E7FFB572
+:10E50000794C85B00E460746C0346088694608805D
+:10E51000154602A905F002F9002811D0002168462D
+:10E5200005F059F9002823D1684602A9008805F0B2
+:10E53000F5F8002804D06F4864A13C300CF00BFEC5
+:10E5400068460088388068460088608066480021F8
+:10E55000C23005F040F9002802D00020C04360809E
+:10E5600003988030807A06F037FA002803D007E05D
+:10E57000002009B0F0BD5F4854A156300CF0EBFD0F
+:10E5800004A806F03CFA0028F3D0049805F068FBD4
+:10E590003070022807D0012805D056484BA17230B0
+:10E5A0000CF0D9FDE4E70899049805F0F6FC288002
+:10E5B000002804D14F4845A165300CF0CCFD06F091
+:10E5C00045FA002804D1E92040A180000CF0C3FDE9
+:10E5D0000120CEE73EB50446831D02AA694601A884
+:10E5E000FFF78DFF002813D068468088208068469A
+:10E5F000008960800020607168460078012808D09A
+:10E60000022806D03B4831A192380CF0A4FD01202D
+:10E610003EBD2071FBE7FEB5040004D135482BA1B7
+:10E620007E380CF098FD304D0026203D687C002897
+:10E6300008D0667010202070A87CA070E87CE07084
+:10E640006E7430E0284F403F3878002808D02C22E4
+:10E65000B91C20460CF0F5FB0E2020703E7022E025
+:10E66000A87B002809D00120E070E87BA070287CFE
+:10E6700060700F202070AE7315E01B480221C63079
+:10E68000029005F0A8F8002871D1174FC037F8881C
+:10E690000190F888042808D0052831D02146FFF7DA
+:10E6A000D6FD002859D00120FEBD0021204606F0ED
+:10E6B00019FA0028F7D1287D00284ED06670132063
+:10E6C00020701C21A01C0CF019FC15E07372635C17
+:10E6D0006C6C5F6374726C2E630000000D020000AE
+:10E6E000FFFFFFFF1F000000AC120020FFFF000033
+:10E6F00080000020390300000220A0702E75D2E7B0
+:10E700000021204609F098FA002826D02078132806
+:10E71000C9D1A0783C28C6D1A088694604F07CFF06
+:10E72000002803D0FD49FE480CF015FD009880300C
+:10E73000807A05F0E4FE002804D1F948F749001D6D
+:10E740000CF009FD009804F09FFF0028ABD0F448BE
+:10E75000F24908300CF0FFFCA5E70221029805F011
+:10E760003AF8002803D1F9880198814291D100201C
+:10E77000FEBD50E710B508F011FF002804D0E848AE
+:10E78000E649BE300CF0E7FC07F01FFF06F09AFAEE
+:10E7900004F07AFA002804D07920E049C0000CF097
+:10E7A000DAFC0AF0CEFC002804D03D20DB49000151
+:10E7B0000CF0D1FC09F070FA002804D0F520D749FC
+:10E7C00080000CF0C8FCFFF7EDFD04F0ABFE002864
+:10E7D00004D0F720D14980000CF0BDFC05F01CFEF0
+:10E7E00001F051FBCF480021C17040380171012177
+:10E7F00041710222C270017010BD10B5C94C403C7D
+:10E800002078002804D00A210E2001F002FB10BD60
+:10E81000FFF700FD002801D00C2002E001F033FBDF
+:10E8200000202071012060710A21E170207010BD6C
+:10E8300070B5BC4C0646403C2078002804D03A21F4
+:10E840000E2001F0E6FA70BDFFF7E4FC002801D0CD
+:10E850000C2010E0B34DE87808280BD20001001915
+:10E8600010223146443001F0DEFAE878401CE870AE
+:10E87000002000E007202071012060713A21E17042
+:10E88000207070BD70B5A74C0646403C207800282B
+:10E8900004D00B210E2001F0BCFA70BD30780028A6
+:10E8A00003D0012801D0122015E09E4D8035287933
+:10E8B000082817D2FFF7AEFC002801D00C200AE090
+:10E8C000984833782979721C883001F098FB2879B0
+:10E8D000401C287100202071012060710B21E17023
+:10E8E000207070BD0720F6E710B58E4C403C2078B4
+:10E8F000002804D039210E2001F08BFA10BDFFF75B
+:10E9000089FC002801D00C2002E086490020C87054
+:10E910002071012060713921E170207010BD8148A3
+:10E9200010B540380178002904D00F210E2001F0E5
+:10E9300070FA10BD002101710E2181700F21C1708C
+:10E94000FF2181710021C9430181774949680A7813
+:10E9500082728A8882814988C18101214171017056
+:10E9600010BD704910B540390A78002A04D03C2106
+:10E970000E2001F04EFA10BD6A4A0088C032508065
+:10E980000120107100220A7148713C22CA7008707F
+:10E9900010BD10B5634C403C2078002804D02B21DA
+:10E9A0000E2001F036FA10BD0821A01DFDF7BCFBBA
+:10E9B00000202071012060712B21E170207010BDBA
+:10E9C00010B5584C403C2078002804D005210E207A
+:10E9D00001F01FFA10BD05F06EFDE08005F0C6FEE7
+:10E9E000207200202071012060710521E1702070EB
+:10E9F00010BD10B54B4C403C2178002904D031218A
+:10EA00000E2001F006FA10BD00214156042911D054
+:10EA100000290FD0081D0DD0001D0BD0001D09D0FE
+:10EA2000001D07D0001D05D00A3003D00A3001D0E8
+:10EA3000122003E0084601F033FB00202071312052
+:10EA4000E07001206071207010BD30B5354D044676
+:10EA5000403D28788DB0002805D02A210E2001F0F5
+:10EA6000D8F90DB030BD10222146684601F0DBF91F
+:10EA70001022A11804A801F0D6F9684603F00BFC97
+:10EA800010222C46A81D08A901F0CDF90020207104
+:10EA90000E20A0702A20E070012060712070E0E755
+:10EAA000F0B5204C85B0403C2078002804D03B21B4
+:10EAB0000E2001F0AEF971E40020A07119486946FA
+:10EAC000C0304088888002A904F028FE002805D0C4
+:10EAD000002101A804F07FFE002865D16846114D91
+:10EAE00081880180283D684602A9008804F016FE4E
+:10EAF000002803D009490D480CF02DFB039E04A902
+:10EB000037468837B878283605F04BFE002804D100
+:10EB100006480249401D0CF01EFB09E0CCE600004F
+:10EB2000FF020000AC12002080000020140500004D
+:10EB3000767EB87805F050FF002803D1FB49FC48E9
+:10EB40000CF009FB05F0B3FF0121484031460143B9
+:10EB50001FD06A461188A279FD2352001219118133
+:10EB6000A2794000515D4908490031435155A279CD
+:10EB70001940014351556A46107C002802D00420F8
+:10EB8000014301E0FB200140A0794155A079401CE0
+:10EB9000A0710021684604F01EFE002804D16846DA
+:10EBA0000188808881429ED10020207101206071FF
+:10EBB0003B21E17020707EE770B5DE4C0546207881
+:10EBC000002804D034210E2001F023F970BD08F094
+:10EBD00087FF052804D0284608F03FFD002000E00C
+:10EBE0000C202071012060713421E170207070BD13
+:10EBF00010B5D04C2078002804D00E21084601F032
+:10EC000008F910BD0622CC49A01D0CF01AF900200D
+:10EC10002071012060710E21E170207010BD70B56F
+:10EC2000C44C06462078251D002804D032210E2031
+:10EC300001F0EFF870BD3146002009F032F928707C
+:10EC400000280CD100213246084606F080F92870D1
+:10EC5000002804D106223146B7480CF0F2F8012012
+:10EC600060713221E170207070BD70B5B14C054605
+:10EC70002078002804D030210E2001F0CAF870BDA1
+:10EC800008F073FD002803D104F0DEFA00280DD04F
+:10EC9000287804F08AF8287806F0C0F9002020715E
+:10ECA000012060713021E170207070BD0C20F6E70A
+:10ECB000F8B5A04C06462078251D002804D0172161
+:10ECC0000E2001F0A6F8F8BD3146012009F0E9F860
+:10ECD0000127287000280FD13246012106F037F9AC
+:10ECE0002870002808D19348062231463C300CF0A9
+:10ECF000A8F890484030877067711720E07027703F
+:10ED0000F8BDFEB58B4C05462034A07B002804D00E
+:10ED100028210F2001F07DF8FEBDA8781A2824D004
+:10ED20000EDC03000CF038FB16333333333321335E
+:10ED300033333333333333333333333321212133D9
+:10ED40002A2824D00ADC1E3803000CF025FB0C20F6
+:10ED5000202020202020202020200E203A380300D0
+:10ED60000CF01AFB04150315031528887349884213
+:10ED70000DD81F21E173282121740120A073288858
+:10ED8000694604F0CBFC002803D0022014E01220D6
+:10ED900012E068460078019F00280FD0C637019E18
+:10EDA00000280DD0C736684601F05CF8002802D074
+:10EDB0003878002806D00C20E073FEBD9C37EEE7C3
+:10EDC0009D36F0E701203870A87830700020E0739D
+:10EDD000684601F05FF8FEBDF0B5564C0746207856
+:10EDE00085B0002804D025210E2001F012F862E63B
+:10EDF000388802A904F092FC4E4E00210836002803
+:10EE00000CD00220207131603171E1800E20A070A1
+:10EE10002520E0700120607120704CE6039D28469B
+:10EE20000A30483501900020A87505223046019926
+:10EE30000CF007F8A87D0028F5D13888E080E5E7D8
+:10EE4000FEB53C4C06462034A07B002804D010219F
+:10EE50000F2000F0DEFFFEBD1F20E07310202074A5
+:10EE60000127A7733088694604F058FC002810D1A8
+:10EE7000684600F0F7FF00280BD06846019D007837
+:10EE800028350028019806D0CA300178002909D118
+:10EE900004E0022007E08030406AF6E72035697B15
+:10EEA000002902D03A20E073FEBDA97B89070DD16D
+:10EEB0000621017068460078002804D10198318845
+:10EEC0008030406A4180684600F0E4FF0020E07333
+:10EED0006F73FEBD70B5174D04462878002804D026
+:10EEE00038210E2000F095FF70BD1F2028710120F1
+:10EEF00068713821E97028702078002808D001282E
+:10EF000006D0022804D0032802D01220287170BD38
+:10EF1000002606F051F8207807F061FC207808F010
+:10EF2000E6FF20780AF0ABFA2E7170BDCCE6000047
+:10EF30001F0500006C1200208C000020FF0E000056
+:10EF4000F8B5FE4D06462878002804D01D210E2075
+:10EF500000F05FFFF8BD1F202871012068711D219E
+:10EF6000E970287008F0BCFD0C27042857D005284C
+:10EF700055D0B0791224012801D000281DD1307855
+:10EF8000002801D0012818D1F079002801D00128EB
+:10EF900013D17088EA49021F30248A420DD2B28808
+:10EFA000121F8A4209D22887B0886887B079002466
+:10EFB000012804D000280CD016E02C71F8BDDF48E1
+:10EFC0004030807800282AD0DC4A3C3201210846B3
+:10EFD00002E0DC4A0021012005F0B9FF040003D063
+:10EFE000D949DA480CF0B7F8F079012801D00028A7
+:10EFF00002D105F0C8FF0446002C01D01F2011E00B
+:10F000003078012802D0002803D00AE00021022035
+:10F0100001E00021012005F0C6FF002801D02F717A
+:10F02000F8BD00202871F8BD70B5C44C21780029C6
+:10F0300004D01E210E2000F0ECFE76E71F21217186
+:10F04000012161711E22E270217002781221012AD1
+:10F0500001D0002A04D14078002803D0012801D033
+:10F06000217162E700260C25012A09D008F038FD3D
+:10F07000052803D008F042FA002806D0257154E78D
+:10F08000618F208F08F083FBF6E726714DE7F0B51E
+:10F09000AD490446143103C987B0A84D0591203508
+:10F0A0000490A87B002805D021210F2000F0B1FE9C
+:10F0B00007B0F0BD1F20E873212028740126AE732D
+:10F0C00022889F4B111F3020994243D261880F1F25
+:10F0D0009F42FAD291423DD8E2899D4B911F9942BD
+:10F0E000F3D2218A8F1F9F42EFD28A42F3D8628ADD
+:10F0F000FF23F4339A42EED8A28A954F13460A3B77
+:10F100003F1FBB42E1D2C9088A4223D9E18A228B40
+:10F110009142E0D821791220002902D0012919D189
+:10F1200002E061790029F9D1217B002901D0012970
+:10F13000F5D108F0D5FC05280BD008F0D1FC042847
+:10F1400007D0287D002804D105F017FD81498842A9
+:10F1500001D00C20BDE0684604F0AEFA002801D0D2
+:10F160000920B6E001220321009804F0E6FF009F89
+:10F17000042178880F3703903846FCF7D5FF3846CE
+:10F18000039905F0C2F874A0009F0068069003215F
+:10F1900006A81337FCF751FF002006A90A5C3A5471
+:10F1A000401CC0B20328F9D30098218A8180618A6B
+:10F1B000C180A18A01810146002720318F73CF735E
+:10F1C0006179002902D0012903D101E0C77600E06E
+:10F1D000C6760622A11D1C300BF033FE00980522D6
+:10F1E00004A90A300BF02DFE0098A0300673694682
+:10F1F0000F71012101A8FCF720FF6946087941073A
+:10F20000C206490F920F80068918C00F0818694678
+:10F210000871401D009B0928987601D20830987625
+:10F2200001220021184604F088FF00988A3005F07A
+:10F2300044F9002804D145484349FC300BF08BFFCA
+:10F24000207B002806D0012808D03F4943480BF016
+:10F2500082FF40E000213B4A012008E0374840306F
+:10F26000807800280FD0354A01213C32084605F04D
+:10F270006EFE00282FD000988030807A05F03FF98C
+:10F28000002816D01AE000988030807A05F037F90F
+:10F29000002804D131482C490D380BF05CFF009850
+:10F2A00004F0DAFA002800D153E72C48264909383F
+:10F2B00041E02A482449C01D0BF04DFF009804F09E
+:10F2C000CBFA002804D025481F490B300BF043FF30
+:10F2D0001F20E873ECE62079012801D0002803D133
+:10F2E00005F051FE00280CD10320009905F05BFECB
+:10F2F000002806D162882188009808F0F5F90028D6
+:10F3000007D000988030807A05F0F9F8002805D001
+:10F3100009E00098A0300770EF73C9E60F480A496A
+:10F3200031300BF018FF009804F096FA0028BBD09B
+:10F330000A48054935300BF00EFF0AE76C12002031
+:10F34000FD3F00008C000020CCE600000607000016
+:10F350007B0C0000FFFF0000112233001C0800009E
+:10F3600038B5F94C2078002804D022210E2000F076
+:10F3700050FD38BD1F202071012565712220E070ED
+:10F38000257008F0ADFB052802D00C20207138BD97
+:10F3900000202071684608F059FA0028F7D100983B
+:10F3A0008030807A05F0ABF8002803D1E749E848BF
+:10F3B0000BF0D1FE009804F04FFA002804D0E44886
+:10F3C000E249001D0BF0C7FEDF4820300575E1481B
+:10F3D0000078F2F799FF38BDF8B5DB4D04462035CB
+:10F3E000A87B002804D023210F2000F012FDF8BDD7
+:10F3F0001F20E873232028740120A8736288D64B4D
+:10F40000911F302099424CD2A1888E1F9E4248D233
+:10F410008A4246D8E288FF23F4339A4241D82289AF
+:10F42000CD4E13460A3B361FB3423AD2C9088A4230
+:10F4300037D96189A289914233D80026208869464C
+:10F4400004F05EF9022700280BD1009800F0F8FCC8
+:10F45000002806D000988030416A0A78002A06D138
+:10F4600001E0EF73F8BD826B1278002A01D03A20D8
+:10F4700017E005228A71416A0E81426AA188518192
+:10F48000426AE1889181426A2189D181406A018979
+:10F490004289914204D88179082901D8914202D346
+:10F4A0001220E873F8BD2188418000988030406ABE
+:10F4B0000770EE73F8BDFEB5A34C06462078002811
+:10F4C00004D024210E2000F0A4FCFEBD01256571AE
+:10F4D0002420E0702570304604F039FF002801D068
+:10F4E000002000E0122020710028EED1964F052266
+:10F4F000E03738463D7731461D300BF0A2FC002640
+:10F500003E77701E69460880684604F031F900288D
+:10F5100019D168460788684601A9008804F0F0F808
+:10F52000002804D08A4889498F300BF014FE0198D6
+:10F53000A0300573684604F01BF9002803D1684623
+:10F5400000888742E7D12671FEBD38B57E4C05465E
+:10F550002034A07B002804D026210F2000F059FC85
+:10F5600038BD1F20E073262020740120A073288856
+:10F57000694604F0C5F800280BD1009800F060FC43
+:10F58000002806D000988030416A0A78002A06D107
+:10F5900001E002200DE0806B0078002801D03A20C5
+:10F5A00007E007200870009829888030406A418071
+:10F5B0000020E07338BD10B5634C2078002804D0DB
+:10F5C00006210E2000F025FC10BD002020710E2029
+:10F5D000A0700620E0700821A01D0BF08FFCA1791F
+:10F5E00001200143A1716071207010BD38B5564CE7
+:10F5F00005462034A07B002804D02C210F2000F0E9
+:10F6000008FC38BD1F20E0732C2020740120A0735B
+:10F610002888694604F074F800280CD1009800F09E
+:10F620000FFC002807D00098014680314B6A1A78F9
+:10F63000002A06D101E0022025E0896B0978002923
+:10F6400001D03A201FE04030007F00281DD0082262
+:10F65000A91C181D0BF0F5FB00986A898030416ADF
+:10F660008A81406A294610220C310E300BF0E9FBEA
+:10F67000009803218030406A01700098298880300A
+:10F68000406A41800020E07338BD0C20FBE770B574
+:10F690002D4E044630780C25002804D018210E2069
+:10F6A00000F0B7FB41E402F0CBFE032865D002F086
+:10F6B000CDFE032861D06079002801D001282DD12A
+:10F6C000A079002801D0012828D1A07B002805D0EE
+:10F6D000012803D0022801D003281FD1607B002815
+:10F6E0001CD0C0081AD1628801208003824202D84F
+:10F6F0002188814203D9207901280FD119E020798E
+:10F70000002806D0012814D0022805D0032805D1EE
+:10F7100002E0202A0BD30CE0A0290AD22079042889
+:10F7200005D12088202802D36188884201D912257A
+:10F7300023E00548217920308175607900280DD0BB
+:10F7400001280FD019E000006C120020CCE6000068
+:10F750007F080000800000207B0C0000FA4A002196
+:10F76000204607E0F9488078002806D0F74A0121B2
+:10F77000121F204608F01BFB0546012035717071F1
+:10F780001821F170307058E410B5F04C403C2178ED
+:10F79000002904D01A210E2000F03BFB10BD017897
+:10F7A0001F2902D91220207106E000212171027860
+:10F7B000411C104608F09EFB012060711A21E17087
+:10F7C000207010BD10B5E14C403C2178002904D0D8
+:10F7D00020210E2000F01DFB10BD01781F2902D949
+:10F7E0001220207106E0002121710278411C104690
+:10F7F00008F06FFB012060712021E170207010BDC6
+:10F80000F8B5D24C403C2178002904D01B210E20B1
+:10F8100000F0FFFAF8BD012666710C212171007815
+:10F820000025012804D000285CD01220207188E037
+:10F8300002F006FE002835D102F008FE002831D182
+:10F8400008F021FAC24988422CD108F07AFA00283F
+:10F8500077D0684603F0C6FEBB4A00990C3A916027
+:10F86000002803D0BB49BC480BF075FC01220321E2
+:10F87000009804F008FC009808F0CDFB00988A304E
+:10F8800004F01BFE002804D1B348B24908300BF045
+:10F8900062FC009803F08CFA002851D0AE48AD49C4
+:10F8A0000C301CE002F0CCFD02284AD102F0CEFD63
+:10F8B000002846D1A5482038807D002841D0012865
+:10F8C0003FD004283DD008F03CFA002839D0002071
+:10F8D00003F06EFA002833D09F489E4924300BF085
+:10F8E0003AFC2DE002F0ACFD032804D002F0AEFD9E
+:10F8F000032820D025E002F0A6FD0090002003F0B0
+:10F900004FF900281DD1257100988030807A04F0CD
+:10F91000F6FD002804D190488E493E300BF01BFCC8
+:10F92000009803F0B1FE00280BD08B488949423083
+:10F930000BF011FC05E0002003F032F9002800D1A3
+:10F9400025711B20E0702670F8BD38B57F4C054648
+:10F95000403C2078002804D02D210E2000F059FAD8
+:10F9600038BD2888694603F057FE002801D00220E0
+:10F970000FE00098CA21095C002909D13321095CF4
+:10F980000F2901D0102903D1FC21095C00290BD0DB
+:10F990000C2020710E20A0702D20E0702888E080BF
+:10F9A00001206071207038BD1022A91CD8300BF0E6
+:10F9B00048FA00980421C03081720020E9E738B588
+:10F9C000624C0546403C2078002804D02E210E20B1
+:10F9D00000F01FFA38BD2888694603F01DFE002894
+:10F9E00001D002200CE000980146C030827A002A43
+:10F9F00005D12031C97C0F290DD010290BD00C2046
+:10FA000020710E20A0702E20E0702888E080012058
+:10FA10006071207038BD052181720020F0E77CB54F
+:10FA20004A4C0546403C2078002804D037210E205F
+:10FA300000F0EFF97CBD2888694603F06FFE0028CE
+:10FA400007D002202071012060713721E170207001
+:10FA50007CBD01987F22014628300272427200224A
+:10FA60008272A87822318870E878C8702879087185
+:10FA70002271E8E71CB5354C403C2178002904D0C0
+:10FA800013210E2000F0C5F91CBD0088694603F063
+:10FA900045FE002801D0022006E001982421095CDF
+:10FAA000801C012902D00C20207107E0002201995E
+:10FAB00022712831097A21720088E080012060716A
+:10FAC0001321E1700E21A17020701CBDF8B51F4CF0
+:10FAD0000546403C2078002804D035210E2000F057
+:10FAE00098F9F8BDA878002801D0012804D1A88889
+:10FAF000FF21F531884201D91220207128886946FA
+:10FB000003F08AFD0126002806D0022020716671CC
+:10FB10003520E0702670F8BD009800270246C030FE
+:10FB20000770AB8801464380104680300677AA787C
+:10FB3000012A00D000220A70407F002801D003F083
+:10FB400027FA2771E3E700008C000020AC120020A8
+:10FB5000FFFF0000CCE600002D0A0000F8B5D44EEF
+:10FB600004463078002804D03D210E2000F051F9E1
+:10FB7000F8BD2088694603F04FFD002801D002201F
+:10FB800027E0009F6488FD883A896800B988401C96
+:10FB9000844217D3C7484143800050430BF0BAF961
+:10FBA000401EFF2180B2F531884200D908468442C8
+:10FBB00000D22046691C401C0BF0ACF96D1C684358
+:10FBC000401E85B2E820C05D002800D17D84F5800C
+:10FBD00000203071012070713D21F1703070F8BD4E
+:10FBE00070B5B34C05462078002804D033210E2090
+:10FBF00000F00FF956E502F023FC002801D00C209C
+:10FC000018E02978002911D00A290FD014290DD025
+:10FC10001E290BD0282909D0322907D04B2905D01D
+:10FC2000642903D0FF2901D0122003E0284603F005
+:10FC30004BF900202071012060713321E1702070A8
+:10FC400030E570B59A4C05462078002804D03E2156
+:10FC50000E2000F0DEF825E502F0F2FB002803D1CB
+:10FC600002F0F4FB002801D00C2003E0287808F013
+:10FC70004DF900202071012060713E21E17020705B
+:10FC800010E510B5017801240B000BF085FB3FBF98
+:10FC9000BF21BFBF4C94BFBFBF2427BFBF464F612A
+:10FCA000BFBF59BFBFBF2B97BF9B9FBF797DBFA36E
+:10FCB0008185888C6590BF5DBF555275A7ABBF37F6
+:10FCC0002F33BB6DAFBF71423F3B4969B3B7C00033
+:10FCD000FEF750FD9BE0FEF790FD98E0801CFEF7DC
+:10FCE000D1FD94E0801CFEF7E3FF90E0801CFEF75E
+:10FCF00080FE8CE0801CFEF792FF88E0801CFEF7FF
+:10FD0000B4FF84E0801CFEF793FD80E0FEF7ECFD7D
+:10FD10007DE0801CFFF7DEF879E0FEF769FF76E012
+:10FD2000FEF7BEFE73E0FEF74BFE70E0FEF7F7FD58
+:10FD30006DE0FEF72EFE6AE0801CFEF786FE66E0B0
+:10FD4000801CFFF797FE62E0801CFEF7DAFF5EE0A2
+:10FD5000801CFFF775F85AE0801CFFF73DF856E06D
+:10FD6000801CFEF7FEFD52E0801CFEF725FF4EE0F2
+:10FD7000801CFFF754FE4AE0801CFFF737FC46E08A
+:10FD8000801CFFF7DDF842E0801CFFF74DF93EE0F4
+:10FD9000801CFFF77CF93AE0FFF7E2FA37E0801CBD
+:10FDA000FFF71AFB33E0801CFFF785FB2FE0801C78
+:10FDB000FFF7CBFB2BE0FFF7FEFB28E0801CFFF7F3
+:10FDC00066FC24E0801CFFF7DFFC20E0801CFFF7CE
+:10FDD00017FD1CE0801CFFF7F5FC18E0801CFFF706
+:10FDE000B4FD14E0801CFFF7EAFD10E0801CFFF773
+:10FDF0006DFE0CE0801CFFF7B1FE08E0801CFFF7F1
+:10FE000020FF04E0801CFFF7EBFE00E0002420460A
+:10FE100010BD274A2032537C002B03D19074D1743B
+:10FE200001205074704730B5134606E0CC18203CD2
+:10FE3000D51AE47F5B1E4455DBB2002BF6D130BDF2
+:10FE4000017800290CD14121095C002908D18030BA
+:10FE5000017C002904D0007C042801D001207047D7
+:10FE60000020704701784068002903D001780029FC
+:10FE700005D100E0E4E740304078002801D00020C0
+:10FE80007047012070470A4900208031886740315F
+:10FE90000871704710B50178012908D14068803099
+:10FEA000417F002903D00021417703F071F810BD94
+:10FEB0006C120020C409000070B5FC4D00246C7069
+:10FEC0002C70AC616C72AC720120E872F84844701E
+:10FED000C473AC62F7482C6302F05FF9002804D0C9
+:10FEE000FF20F5A14F300BF036F92C7770BDF8B537
+:10FEF000F54902250D60F5490026CE630127CF6341
+:10FF0000F349C96A09070DD4F24AD36AF2494B6230
+:10FF1000136B8B62536BCB62936B0B63D26BCB0512
+:10FF20001A434A63ED4C002823D0012825D0FF2036
+:10FF3000E1A1A2300BF00FF9E948A063FF200430E3
+:10FF40006063276303202061E64996204860D74913
+:10FF50001C2008560B22D243811A904237D011DC64
+:10FF60001C313AD00A2938D0142934D0182911D19B
+:10FF70002FE0DD486061DD4802E0DD486061DD487A
+:10FF8000A061D9E708301FD004281BD0082817D05B
+:10FF90000C2812D0FF20D8A176300BF0DCF8DB491A
+:10FFA000D9488860DB48DA494160DB490160DB48B9
+:10FFB0000560DB4910204860F8BD0420E060EEE7F2
+:10FFC000E660ECE7FC2000E0F820E060E7E7F420E2
+:10FFD000FBE7F020F9E7EC20F7E7D820F5E710B5CC
+:10FFE0000C460146CF480BF0B2F9B048047210BD80
+:10FFF000AF4840787047AD4A517010707047F8B5FF
+:020000040001F9
+:1000000004460D4650791179000208436900091928
+:100010000884501C01460E78012730464E7836027F
+:1000200030438E78C9783604304309060843117886
+:1000300000020843A9006050284608303E4686402A
+:10004000002B0CD0012B04D0FF209BA1E9300BF03A
+:1000500082F8206B3043AF4038432063F8BD206BFB
+:10006000B043F8E770B50D460446082904D9FF20CF
+:1000700091A1FA300BF06FF80022002D0CD9AA489C
+:100080009100635809180B6053001B191B8C0B62FD
+:10009000521CD2B2AA42F3D3206BA449086070BDAF
+:1000A00010B504460B22D2430C308C49944223D025
+:1000B00008DC1C3026D00A2824D0142820D0182888
+:1000C00009D11BE02046083014D0042810D008289D
+:1000D0000BD00C2807D0FF2087A176300BF03BF81F
+:1000E0007248047710BD042000E00020C860F7E7E4
+:1000F000FC20FBE7F820F9E7F420F7E7F020F5E72C
+:10010000EC20F3E7D820F1E76948007B704773499A
+:10011000C2784A6202461378184653781B02184385
+:100120009378D2781B041843120610430002C8616A
+:100130007047252808D0262808D0272808D0410055
+:100140000A2807D8091D06E0022105E01A2103E06C
+:10015000502101E0891DC9B2604A9160614948613E
+:10016000704752498861704770B5002816D0022246
+:100170004E4C6F4BA27203201860644D6248686059
+:1001800000200126207500290AD001290FD002295C
+:100190001DD049A167480AF0DEFF70BD0122E7E7E4
+:1001A0006548012A01D0466070BD066070BD3F48B9
+:1001B000012A006B05D001214905084320636960CD
+:1001C00070BD0121090508432063696070BDA06905
+:1001D000002804D1492038A1C0000AF0BCFFA16961
+:1001E000A06A4018554988604A4855498160554978
+:1001F000C1600120216BC0030143216368602C486A
+:10020000C67370BDF8B54A4801688F084449BF00FD
+:100210004A68D206D60F10228A60002404603B4848
+:10022000394981600C2069460870474D2C6142496C
+:10023000012008610BE000BF00BF00BF00BF00BF8E
+:1002400000BF00BF00BF69460878401E08706846BE
+:100250000078002802D028690028ECD06846007891
+:10026000002804D14D2024A1C0000AF074FF2C61A5
+:100270000E48012144728472C1722D480760002E1D
+:1002800002D0274910204860F8BD01460A78104680
+:100290004A78120210438A78C9781204104309067A
+:1002A000084300020D49000AC86370477413002018
+:1002B00094130020A81300207372635C68616C5F64
+:1002C0007263732E6300000080E100E0C01F0040F5
+:1002D00080000010C0000010001700400015004012
+:1002E0005B060000401500400601020025000302E5
+:1002F000050103001F0003027372635C68616C5F99
+:100300007263732E630000000040000400F501409A
+:100310004080004080F501401011004080E200E084
+:1003200000130040761300200016004040160040E5
+:1003300000120040550200000010004040850040BF
+:10034000488100401010004000110040FB4902208D
+:100350000860FB4908607047FA490220086070474E
+:10036000F9490870704710B5F84801F01EFF0028E1
+:1003700003D0F749F7480AF0EEFE10BD10B5F34878
+:1003800001F02BFF10BDF4494860704770B5F34C85
+:100390000546A06AA84203D3ED49F1480AF0DBFE06
+:1003A00001202073EF49002025614860EE48456038
+:1003B0000120216B800501432163EC49486070BD39
+:1003C000E64802210173C6210161E64A002151601D
+:1003D000816AE54AC63151600121026B89050A43F1
+:1003E0000263E248416070470121E048890581606D
+:1003F000DA48026B8A430021026301737047DC48CC
+:1004000001214160C160D74900204860D649486059
+:10041000D24988627047D74940200862D6490A68A5
+:1004200002430A607047D44801684022914301604A
+:10043000D049002008627047CF48016810229143DC
+:100440000160CE49012088617047CD490020C86114
+:10045000C94801681022114301607047C849CA6940
+:10046000012A01D000207047C24A92685206520EFB
+:10047000524202700020C8610120704770B50C0024
+:10048000054604D1D920B24980000AF064FEE00795
+:1004900005D0012C03D0AE49BA480AF05CFE002D0D
+:1004A0000DD00221AD4801294172C472B24808D072
+:1004B00002290BD0A649B4480AF04DFE70BD0121B7
+:1004C000F0E7016804221143016070BD0168082251
+:1004D0001143016070BDF8B5A04C0025E27A910788
+:1004E00001D5410713D4D306A849002B05DA4B7B6D
+:1004F000002B02D08B7B002B09D0130702D50B7881
+:10050000002B04D1520703D54978002900D10125D9
+:10051000677A002201239849002F1BD00226304021
+:10052000284348D0084601688E089949B6004D68AE
+:10053000ED06ED0F10278F60002101608B4A954872
+:1005400090600C206A4610708D4F39618B490120F4
+:10055000086114E0854D8F48A86008688008800015
+:100560000860A272E372F8BD00BF00BF00BF00BF09
+:1005700000BF00BF00BF00BF1078401E1070107891
+:10058000002802D038690028EED01078002804D165
+:100590004D208149C0000AF0DEFD00203861607204
+:1005A000A0720120E07274480660002DDBD078480C
+:1005B00010214160F8BD012F06D0022F0CD06449F4
+:1005C00076480AF0C8FDF8BD08680425A84308600D
+:1005D0006272E372A372F8BD08680825A843086038
+:1005E0006272E372A672F8BD5C4908757047F8B58F
+:1005F000664D5A49EC7B086B002C58D001245B4AAD
+:10060000E4039460A04308635B480768604C1021D2
+:10061000A16000210160001490600C206A461070F7
+:10062000574C21615548012606610AE000BF00BF12
+:1006300000BF00BF00BF00BF00BF00BF1078401E5A
+:1006400010701078002802D020690028EED01078B1
+:10065000002804D14D205049C0000AF07CFD002044
+:10066000E060206160606061A061434807603F49CD
+:1006700000144860464910204860384CA07A012890
+:100680000FD0022810D0444945480AF064FD0020EC
+:10069000E873207D022803D1424801688907FCD510
+:1006A000F8BD36480660F2E734484660EFE72F4A67
+:1006B000906000200863087B2A4E002802D07068F2
+:1006C000012809D000222E4C2069012806D00023E1
+:1006D000887A012804D006E00122F4E74023F7E7F6
+:1006E000E768012F04D000271F43012802D004E04F
+:1006F0002027F9E76368012B05D000233B432A4FED
+:10070000022802D007E01023F8E73968012902D156
+:10071000E168012904D000211943022802D007E032
+:100720000821F9E73B68002B02D1E368012B3DD09B
+:1007300000230B4302283BD03EE0000080E100E0B4
+:1007400080E200E000E100E092000020A813002019
+:10075000B8020100A202000000150040741300203E
+:10076000B3020000408100404085004000F5014098
+:100770000080004040150040001200400010004082
+:1007800000110040690300007E0300009413002064
+:100790000013004000400004F8020100CF030000F5
+:1007A0005E03000000E200E0001400400423C0E704
+:1007B000002A01D0022100E000211943022807D1BC
+:1007C0006068012804D17068012801D0012700E089
+:1007D000002790480F4301680906090E02D061699D
+:1007E000012900D00021297300680006000E02D004
+:1007F000A069012800D0002068738748006A00289B
+:1008000003D000F0DCF9012800D00020A8730020FC
+:10081000E060206160606061A06180494860804E56
+:100820008049307548683C4670620968B1620B4681
+:10083000B17A022909D17178002906D07A4A526822
+:1008400012780A40317891430ED000212970774FF9
+:10085000E10710D03978032908D0022906D002F028
+:10086000D1FC0121B06A20E00121EFE707F022F975
+:100870000121B06A27E0A0060ED53878032806D0FB
+:10088000022804D00221184602F0CBFC0FE002211E
+:10089000184607F010F90AE0A00708D538780328B1
+:1008A0000FD002280DD00021184602F0BAFC5E4895
+:1008B00041680622B01C09310AF096FA002805D0DA
+:1008C0000DE00021184607F0F6F8F0E75648317AB7
+:1008D00040680078C009814201D1012000E0002079
+:1008E00068702046FFF7F7FD387800280DD0012802
+:1008F0001ED002282FD003284AD04D494D480AF077
+:100900002AFCB07A022856D075E0A00701D507F07E
+:10091000C6FC200702D5012007F0FDFC600702D5C8
+:10092000002007F0F8FCA006EBD507F059FCE8E73B
+:10093000A00701D508F0E8FF200702D5012008F044
+:100940004DFE600702D5002008F048FEA006D8D56D
+:1009500008F098FDD5E7A007BF25002802DA2C4053
+:1009600004F022FF200703D52C40012004F05DFB9A
+:10097000600703D52C40002004F057FBA00602D5E9
+:100980002C4004F061FE6006BBD504F04AFBB8E7DA
+:10099000A00701D506F0F0F8200702D5012005F0E8
+:1009A000B1FF600702D5002005F0ACFFA006A8D576
+:1009B00005F01CFFA5E7307B00281CD0174900225A
+:1009C0004A60022820D0012803D019491A480AF0A9
+:1009D000C2FBB16A3069884203D8154917480AF04A
+:1009E000BAFB1048316941600120316B8005014339
+:1009F000316313494860307D012800D050E611482A
+:100A000001688907FCD5F8BD3169B06A411805480D
+:100A10004160E9E740160040401500404081004039
+:100A20007413002040850040001500409200002013
+:100A3000B8020100FD0400001205000013050000CB
+:100A400000F5014000E200E02E48002101704170F5
+:100A5000704770B5064614460D460120F0F7A2FC1B
+:100A600028490120284B08709E60DC601D6170BD24
+:100A7000F8B504460120F0F795FC224901200870E2
+:100A800021494C60214900264E600321204D090672
+:100A9000A960204F002C0AD0012C03D01EA14120B8
+:100AA0000AF059FB3E60032000066860F8BD38601C
+:100AB00001200006F9E710B51248017800290ED090
+:100AC0000321134A0906916010494A680021002A4F
+:100AD00003D0154A1268427000E041700170002096
+:100AE000F0F760FC10BD07480178002907D00748DF
+:100AF0004068002802D00C480068C0B270474078B7
+:100B0000704700009300002000F5004000F1004015
+:100B100000F5014000F200407372635C68616C5F35
+:100B200063636D2E6300000000F400403B48002129
+:100B30000170417010218170704770B506461446EF
+:100B40000D460220F0F72EFC01203449344A08708B
+:100B5000E41E14619660556070BD10B50220F0F778
+:100B600021FC2E49012008702E48002101604160BF
+:100B7000816001202C49C005486010BD10B5274890
+:100B80000178002917D00121274AC905916025491C
+:100B90000B680022002B05D04B68002B02D089681F
+:100BA000002902D04270102103E0012141701F4949
+:100BB0000968817002700020F0F7F4FB10BD17483F
+:100BC0000178002912D01748016800290AD001686D
+:100BD000002905D04168002902D08068002803D090
+:100BE000002070470220704701207047407870470E
+:100BF0000A48017800290FD00A480168002905D069
+:100C00004168002902D08068002801D01020704778
+:100C100006480068C0B27047807870479500002091
+:100C200000F5004000F1004000F5014000F40040F4
+:100C3000FFB593B0044600201D9E049015981C9D9E
+:100C40001027082806D0E06901F014F8002809D020
+:100C50003770CCE028880921384328801F98022764
+:100C6000017016E0E169012088710521E269C9027D
+:100C70009180E1698872E169F9480881E1690020A1
+:100C80008873288820210843288011211F98042771
+:100C900001701F980225801C0390307810900A2064
+:100CA0003070204618301190F5F7A1FC00206FE05D
+:100CB0001598102809D1022D07D06846828A049918
+:100CC0000398401A8270110AC1706846C08A16994A
+:100CD000884203D9E349097A149106E0884204D195
+:100CE0001099002901D0317021E003990870000AA1
+:100CF00048701E980088401BC01B83B2FF20C01B99
+:100D0000984200D203460398149AC0190CA9009285
+:100D1000019002912020015D6846C08A0022F5F70B
+:100D2000DBFC3070002806D0C0B2832862D0684651
+:100D3000C08A208345E00F98002805D0C948006884
+:100D400000790A2830D33CE06846008EC119C9B248
+:100D50000491022D0FD01F99049A4978914203D132
+:100D60006A46128C824209D0BE480491006801781C
+:100D7000032909D027E008461F994870B948006840
+:100D80000178042906D008E000790A281BD2012046
+:100D90000F9009E06946C98A818003990498081870
+:100DA00003900498281885B205AA14991198F5F7AC
+:100DB00021FC002805D11E980088401BB84200DBAA
+:100DC00076E7022D0ED01598102807D1049A0399C2
+:100DD0006846808A891A8870000AC8701E98058043
+:100DE000002030709F4800680078032802D000205F
+:100DF00017B0F0BD0220FBE7F8B50446406B0026B3
+:100E0000134600282BD0491F8DB2618F2A46083225
+:100E1000278F8A18BA4221D89A7840185F78110231
+:100E200039430170090A41701A79DF781102394398
+:100E30008170090AC1700571290A41712A46591D3C
+:100E4000801D09F0FEFF608FAD1D401980B26087E4
+:100E5000626B002110180170417000E009263046D5
+:100E6000F8BD30B50B88048F9C4212D9446BE01852
+:100E70004478057824022C430BD044790579240268
+:100E80002C436404640CA41D1B190B80106000200B
+:100E900030BD822030BDF7B588B000256846058298
+:100EA00005275DE00398417802780E0216434179E8
+:100EB000027908021043000452D40A9801230680E4
+:100EC00005A802905B02002200970195304609991F
+:100ED000F5F702FC04004AD16846018A01830398B1
+:100EE0004179027909021143437802781C021443C4
+:100EF000B4421ED10A041CD44B0401215B0C8903AB
+:100F000000950B4301970295C17880780A0202434D
+:100F100020460999F5F7FCF9040011D103994879A5
+:100F20000A79000210430122D20310430871000A1B
+:100F3000487103AA06A90898FFF793FF0400CED0D2
+:100F400003990095019702954878097800020843B3
+:100F500069468B8A00220999F5F7DAF9822C06D1C5
+:100F600003AA04A90898FFF77CFF04009AD06846FA
+:100F7000058209E003984179027909021143490485
+:100F8000490C0171090A417103AA04A90898FFF7E5
+:100F900068FF0028EED0822C02D020460BB0F0BDB6
+:100FA0000020FBE730B50446406B002597B00028D1
+:100FB0000DD00B2268460270228F0281606B039174
+:100FC000019000216846F2F72AFB684605706563C8
+:100FD0006587258717B030BDF8B50F460546696BA4
+:100FE0000020069E144600290FD0012B0DD1324659
+:100FF00039462846FFF74FFF002806D1002C04D0C1
+:1010000032463946284600F044FEF8BD00220280F0
+:10101000C262831D0263C36142634287028720303C
+:101020000170704710B50022D24302800420FBF704
+:10103000E4FA10BD10B596B00446FFF7B3FF208E5A
+:10104000002808D0012069460870E06A019000215C
+:101050006846F2F7E4FA0020E062206316B010BDA3
+:1010600001280000AC1300200146098800200A076F
+:1010700000D501200A06120F01D002221043CA0532
+:1010800001D5042210438A0501D5102210434905D9
+:1010900001D5202108437047FFB5A9B00600329D55
+:1010A000359C2B981F46229016D0007841060FD40D
+:1010B0008106890E1E2909D021884A05520E0BD1BE
+:1010C0003A88172A08D3FE4A914205D0C10906D0B2
+:1010D0008006800E122802D003202DB0F0BD2046DD
+:1010E0002C302690F7492A980872002018AA0390FD
+:1010F00010726A46107404AA0A60339A4A6020AAE1
+:10110000908090812298007801908106681C1C9044
+:10111000701F1D902B98890EC21C249222462032EB
+:101120001B92083A401C02920B000AF035F91FFD91
+:10113000FD11FD1FFD8EFDFCFDFBFDFAFDF9FDFC23
+:10114000FDF8FDFDFDF7FDF6FDFDFDFDFDF5FD00E6
+:10115000032E76D102E018A9087219E30320287043
+:101160001C9917220A7000224A70CFE2052EF0D196
+:101170004178027808021043208320A98880249AAD
+:101180005178127809021143618300287ED0884289
+:101190007CD800202072E080401E60840298F5F721
+:1011A00026FA05202870A81C0190022000901BAA96
+:1011B0002A990298F5F71EFA002868D118A8807CB1
+:1011C000012803D002206870102002E0012068701E
+:1011D00002202490002225A91CA8F1F7AAFD0028CE
+:1011E0002BD120A8007D2499814226D13A880099EC
+:1011F000801C511A814220DB10A8C18D019801701A
+:10120000090A417001991CA8891C01910099019A51
+:10121000891C009125A9F1F78CFD20A8007D01997A
+:101220001BAA091801910099081880B200902A9908
+:101230000298F5F7DFF90028CCD00098022826D0D4
+:1012400064E272E018A9087261E2072E6DD341785A
+:101250000346027808021043208320A98880249A3C
+:101260005178127809021143618300280ED0884218
+:101270000CD8012020725879197900020843E080C7
+:1012800000202073E06900F0F5FC01E098E0A9E09F
+:1012900000280ED1E169012088710521E269C902A7
+:1012A0009180E1698872E16987480881E1690020DD
+:1012B0008873F01F60842298C01D60620298F5F761
+:1012C00096F907202870681C0090012001900020EA
+:1012D00010A9C8852FE00198012814D0E069807911
+:1012E000012830D000981E38417F007F0902014359
+:1012F00000980170090A41700098801C00900198C4
+:10130000801C80B2019010A8C18D00980170090A5C
+:1013100041700098801C09E00AE296E13BE1DFE0C1
+:1013200004E29BE077E036E016E2AFE0009001983F
+:10133000801C80B201901BAA2A990298F5F75AF9ED
+:10134000002803D007E010A8818DD1E739880198E3
+:10135000081A0428BFDA0198012843D0E06980798F
+:10136000012804D010A8818D5548814206D110A8CB
+:10137000818D00980170090A417009E000981E38BB
+:10138000417F027F0802009910430870000A4870EC
+:101390000198801CBAE1072E01D0152E76D1417834
+:1013A000027808021043208320A98880249A51786B
+:1013B0001278090211436183002801D0884201D9C3
+:1013C00001203FE7012020720020E0802073052EDD
+:1013D0000AD01D982299E269C0B2491DF1F783FC39
+:1013E000002801D00A202DE70020C04360841AA8FD
+:1013F000019023A922980297039500910078002379
+:101400008206920E20462A99FFF712FC0390208B49
+:1014100020A988807BE1032EC0D1402220A98A81A7
+:101420004178027808021043208320A988802A99F5
+:101430001EAB1C9A02930192009139880022491E2A
+:101440008BB21B990978F5F747F918A9087200289B
+:1014500033D10B20287010A8008F3FE0052E9DD1BE
+:10146000802220A98A8141780278080210432083D3
+:10147000249984464A78097812020A43628420A992
+:1014800088801248824202D30720DBE6AFE03F208B
+:101490008002024362842A981FAB1C990293019137
+:1014A00000903888401E83B21B9801786046F5F79B
+:1014B00013F918A9087200280CD08328AAD107E0D4
+:1014C000FFFF0000AC130020012800000102000013
+:1014D0000220B8E00D20287010A8808F401C15E174
+:1014E00001990C22C9095143C91CB14204D9019880
+:1014F00040067CD5002009E14278037810021843A9
+:1015000020AA9080844622980078400609D50520BC
+:101510006A46107422980078C00905D00020107423
+:101520001DE106206A46107424981F902A9A0090A4
+:101530000023701A029383B21E9001921B9800221E
+:1015400001786046F4F7E4FE18A9087200226946A3
+:101550000A74832801D10220039022980078400663
+:101560000DD52088C00506D520A9208B8988884202
+:1015700001D100206062002018A90872C6E0FF2196
+:10158000013120A88181808820831E9860841F9863
+:1015900060621320B8E0052E29D341780278080252
+:1015A000104320A98880218F002902D0FE4A914251
+:1015B00006D10A216A4611740121C943218702E03C
+:1015C00007216A46117422992A9A491D01920091B5
+:1015D00001221D990023D203029311438BB2249957
+:1015E0004A78097812020A431B99097800E0C9E099
+:1015F000F4F78EFE18A90872002269460A740122C7
+:10160000520220A98A81832808D0002809D0218F7E
+:10161000E54881427ED10020208778E088882083B9
+:101620004DE7606B002808D031462046229AFFF72C
+:10163000E3FB18A90872002869D12B463A463046C8
+:10164000229900F056FB039061E02298022E407828
+:1016500001907DD1002801D0012879D10820694668
+:1016600008740198087521A800901B980022017841
+:101670002046019BFFF7B0FC6946002248758A7539
+:10168000002802D10198012809D0208F002806D017
+:10169000002008740120800220A988810EE004A89F
+:1016A0003399F1F7BCFF03900020694608740120CC
+:1016B000800220A988810398022807D0BB480068CF
+:1016C0008079002805D018A908722BE001982083A2
+:1016D0001DE00398002803D0812018A9087240E07B
+:1016E00021A800901B98012201782046019BFFF75A
+:1016F00073FC18A9087220463499FFF753FC18A907
+:10170000087A002803D11920287001203880684603
+:10171000007C00E03CE0002804D004A83399F1F7F5
+:101720007EFF0390039800282ED01AE0062012E5D1
+:101730002078000713D5012E11D1092168460174C4
+:10174000A188818204203499FAF757FF082100E02C
+:1017500005E020A88181CDE60198400612D503203E
+:10176000039020A9208889890843208020A988899E
+:101770004005400E04D026992B9808602698868054
+:101780000398AAE40420E6E418A8007A00280ED002
+:101790000120287022980078687020A88088A8709E
+:1017A000000AE87018A8007A28710520388020A95E
+:1017B0002088898988432080E2E7FFB50746A1B0E9
+:1017C00000201C903A7801209040794A7C681040B3
+:1017D00010AA1087744B22885B1C9A4203D0002801
+:1017E00004D0100702D5012025B0F0BD249E0020B2
+:1017F000307023980025028810A8028518A8057566
+:101800006A4B68461972057404A8186020462C308B
+:101810001B902A985860249E94463878721C0521A3
+:10182000039201282DD0022808D003287DD13078DA
+:10183000800980011D303070B889A0803878022876
+:1018400004D13078800980011B303070F01C1FAA51
+:1018500001900292009110A8008D0022C01E83B258
+:101860002020015DB889F4F737FF0028DED1039806
+:10187000B9890170090A417010A9888FC01C0885B8
+:1018800028E1787B18AA10753A7B012A02D0022A37
+:10189000CCD1FCE022887F231B011A4010AB1A87B1
+:1018A000802A4AD006DC102A10D0202A0ED0402AE6
+:1018B0000AD124E0FF3A013A65D0FF3A013A79D0E3
+:1018C000FF3AFF3A022A76D00525A2E02078C0062A
+:1018D00001D5082000E010201C9004206A461074F6
+:1018E000002090821AA81DAA1EAB039601920290B6
+:1018F00000933B8A20461C9AFFF79AF984E0228BDA
+:101900003B8A9646934268D10A221C92002839D11C
+:10191000039801906046401E1FAA83B202922020C5
+:101920000091015D0022704600E0BAE0F4F7D4FEB9
+:10193000014618A801750B201AE0228B3B8A9646B7
+:1019400093424AD10C221C92002862D10398019044
+:1019500060461FAA401E0292009183B22020015DC2
+:10196000628C7046F4F7B8FE014618A801750D2088
+:10197000307010A8818F491C0185042168460174CC
+:10198000218B818245E0238B3A8A9C469A4224D15E
+:1019900012221C9200283CD1606A002813D0002239
+:1019A0006B4607C3638C07E0FEFF0000AC1300200A
+:1019B00009F800000DE04BE02020015D6046F4F7DF
+:1019C000A7FC18A9087513203070012010A90885FC
+:1019D0001FE0398A228B914201D00425B6E01621FE
+:1019E0001C91002815D11B98818802682046FFF7BA
+:1019F00003FA18A9087500280BD11B983346016813
+:101A000080881AAA00F075F9054602281BD0042D1B
+:101A100019D01B988088002811D06846007C0028C7
+:101A200004D004A82A99F1F7FAFD05460120694679
+:101A300008741B981B990068059000208880002D71
+:101A400048D0052D2ED06846007C032878D07DE054
+:101A500018211C91002806D0388A20832046B968B6
+:101A6000FFF7A0FAD5E72046183000902020015D4E
+:101A7000237E01222046FFF7AFFA18A90875002837
+:101A8000ECD119203070012010A90885E6E72088E4
+:101A900001214902084010A90887FF38FF380228B1
+:101AA00006D0052510A92088098F884320804DE0A5
+:101AB000208F9849884290D116201C9038690028C0
+:101AC00005D06063B88A20870020608702E000208C
+:101AD000C043208710A8008F7F21090102468A4356
+:101AE0000DD0782300220420B968FAF7DFFC38789B
+:101AF000A07010A92088098F0843208002E0218867
+:101B0000814321806846007C002805D082484168D6
+:101B100004A8F1F784FD054618A8007D002815D01B
+:101B20001C98707001203070208BB070000AF0702B
+:101B300018A8007D3071052110A8018506E0FFE797
+:101B40007548416804A8F1F76AFD05467248017AB4
+:101B500020884005400E22D11B98808800281ED086
+:101B6000239A0026138810AA1385249A2A9B6F466D
+:101B70004CC71B9A039412681AABFFF78DFA0546FF
+:101B800002280CD00120694608741B982A99006825
+:101B9000059004A8F1F743FD05461B98868010A820
+:101BA000018D2398018028461EE600B597B00428D1
+:101BB00007D102206A461070019100216846F1F7B2
+:101BC0002EFD17B000BD10B5534C037800222168DC
+:101BD000012B02D0022B42D126E00B78002B01D042
+:101BE000042B03D10A7122680321117021688388B4
+:101BF0000A79D200921D8B5221680A79D2000832EC
+:101C00008918C2880A80216803890A79D2000A32B9
+:101C10008B52428920680179C9000C3142522168F7
+:101C20000879401C08711EE00A7482888A80216845
+:101C3000C288CA8022680189118122684189518144
+:101C4000C1682068C1606168F1F7E9FC01460228BB
+:101C500007D02068007C002802D1002903D0812011
+:101C600010BD832010BD002010BD406B002800D0A7
+:101C7000012070478178012909D100880521C90216
+:101C8000884202D0491C884201D1002070470520BB
+:101C90007047F7B586B00024684615460F46848124
+:101CA00005261AE004984178027809021143298038
+:101CB000811D019602940091417902790B02134330
+:101CC000C178827809020A43417800780902084302
+:101CD0003946F4F71DFB002806D104AA03A906988B
+:101CE000FFF7BFF80028DDD0822800D1002009B01E
+:101CF000F0BD10B51488844201D2052010BD172410
+:101D00001C701080421E581C491C09F09AF80020D3
+:101D100010BD0000FEFF0000AC13002030B50346EC
+:101D2000002002460DE09C5C2546303D0A2D02D382
+:101D30000020C04330BD0A25684330382018521CAB
+:101D4000D2B28A42EFD330BD70B50D46144608E0DA
+:101D50000A2109F0DFF82A193031203A641ED177C0
+:101D6000E4B2002CF4D170BD10B5002310E0040AD9
+:101D700000020443A0B2CC5C44402006000F604047
+:101D80000407240C44402006C00C60405B1C9BB23E
+:101D90009342ECD310BD000010B572B600F0DCF831
+:101DA00000280BD0EFF77CFAFAF7E1FD08F097FB7B
+:101DB0006E490020C86288626D49086062B60020E2
+:101DC00010BDF3B5002501200007C06A81B0C043F3
+:101DD0000006000E04D167480068401C00D10125B0
+:101DE00072B600F0B9F8002802D062B60820FEBD35
+:101DF000EFF7ACF9EFF758FA5F4B604E00211A6825
+:101E0000CA40D2071FD00246CA40D20718D14AB2F0
+:101E1000002A07DA1407240F083CA408A400A41918
+:101E2000E46904E09408564FA400E419246892077A
+:101E3000D20ED4402206920F012A04D0032A02D0E7
+:101E400062B65048FEBD491C2029D8D30198030032
+:101E500009F0A2FA142123232323232323230B0D88
+:101E60000F11131F1517191B1D2E002416E0012436
+:101E700014E0022412E0032410E004240EE00824FD
+:101E80000CE009240AE00A2408E00B2406E00C24F4
+:101E900004E0052402E0072400E00624F0690121A3
+:101EA0000002000AC9070843F061002D04D009E0D0
+:101EB00062B601200003FEBD2C4D3348E862EFF707
+:101EC000F3F9A8622A49314808603149029808604C
+:101ED000EFF7EAF9214608F0E9FAFAF70CFD08F005
+:101EE000EFFC08F065FB0198EFF7A8F9040062B673
+:101EF00003D0FFF751FF2046FEBD0020FEBD10B508
+:101F0000044600F029F8002800D0012020700020AD
+:101F100010BD204908600020704710B50C461028FD
+:101F200008D011280BD012280CD013280ED0012075
+:101F3000086010BD03CC083CFFF743FF0AE0FFF741
+:101F40002BFF07E02068FFF7DAFF03E01149206864
+:101F500008600020206010BD05480C4900688842D8
+:101F600001D10120704700207047000000050040AB
+:101F7000640000200010001000E100E000ED00E02F
+:101F800000E400E00110000000220000BEBAFECA1A
+:101F9000980000200400002010B520380C460300F3
+:101FA00009F0FAF933A6AAAEB2B8BCC0C5E0DBE4CA
+:101FB0001B1F23272C31373C41474D5054585C6040
+:101FC0006D71656974787C8084888C9094989C9FEE
+:101FD000A2CACFE9F0F3D3D7F800206800F0DDF80B
+:101FE000D6E0206800F0E1F8D2E0206800F0F5F8D3
+:101FF000CEE0207840B208F0C9F8C9E0207840B2BD
+:1020000008F0E7F8C4E02078616840B208F0FAF818
+:10201000BEE0207840B208F00AF9B9E0207840B27A
+:1020200008F015F9B4E02078217940B208F020F9E1
+:10203000AEE02078616840B208F04AF9A8E008F004
+:1020400056F9A5E0206808F05AF9A1E0207808F0D8
+:102050006FF99DE02068FAF738F899E02068FAF700
+:1020600038F895E021792068FAF73AF890E020688E
+:1020700007F0D8FF8CE0206807F0D9FF88E02078CF
+:1020800007F0D9FF84E007F0E3FF81E0207807F054
+:10209000E5FF7DE0207807F0F7FF79E0206808F0A1
+:1020A00010F875E0206808F012F871E0206808F078
+:1020B00014F86DE0206808F015F869E0206808F071
+:1020C00017F865E0206808F019F861E0206808F06A
+:1020D0001AF85DE00846EFF751F859E0F0F787F994
+:1020E00056E0F0F7B4F953E02068F0F7BCF94FE0A0
+:1020F000206800F0E1F84BE0206800F0E9F847E0E4
+:10210000206800F0F0F843E02078A268616800F0F1
+:10211000F5F83DE0207800F006F939E0207800F08D
+:1021200017F935E02078616800F027F930E0207871
+:10213000616800F03AF92BE02179207808F008FA7C
+:1021400026E0206800F06BF822E02068FAF7FEFA3B
+:102150001EE02068FAF7E2FA1AE007CC0C3C08F01F
+:10216000F1FA15E0206808F044FB11E003CC083CCC
+:1021700008F06FFB0CE0206808F065FD08E009E05E
+:1021800003E0FFE708F077FD02E0206808F0AEFD0D
+:10219000206010BD0120086010BD002101700846BC
+:1021A00070470146002008707047EFF31081C9079F
+:1021B000C90F72B60278012A01D0012200E0002284
+:1021C00001230370002900D162B6002A01D000204B
+:1021D0007047012040037047E7E7EFF31081C9071C
+:1021E000C90F72B600220270002900D162B6002029
+:1021F0007047F2E710B52848FFF7CFFF002803D05B
+:1022000026A11D2008F0A7FF2348401CFFF7C5FFAB
+:10221000002803D021A1212008F09DFF10BDF1B5B9
+:10222000224D6F6801261C48FFF7BFFF1A4C00289B
+:1022300003D10026601CFFF7D0FF1D4A1D49012075
+:10224000506000BF00BF00BF00BF00BF00230B6095
+:102250004B60009B6B60106000BF00BF00BF00BF01
+:1022600000BF0868002802D148680028F9D04868F3
+:102270000028E4D1002E04D06F60601CFFF795FFAA
+:1022800007E0601CFFF791FF0028D3D10248FFF759
+:10229000A4FF0020F8BDC2E79C0000207372635CBD
+:1022A000736F635F6563622E6300000000E50040AA
+:1022B00000E0004000E100405A495B4B0A685B497E
+:1022C0009A42096801D18904890C01600020704795
+:1022D0005449554B0A6855499A4201D18004800CF3
+:1022E0004860002070474F494F4B0A684F499A4257
+:1022F00001D18004800C88600020704730B5494BC4
+:10230000494D1C684A4BAC4202D0102802D203E06F
+:102310000E2801D3184630BDC30044481818016187
+:102320004261002030BD3F493F4B0A684049491C8B
+:102330009A4202D0042802D203E0022801D30846C0
+:1023400070473C4A0121C00080180160002070479E
+:102350003449354B0A683649491C9A4202D0042850
+:1023600002D203E0022801D308467047314A012116
+:10237000C000801841600020704770B5294A2C4B7E
+:1023800014682D4E284D82005B1C9219AC4203D07C
+:10239000042803D2116006E0022801D3184670BD5C
+:1023A0008804800C1060002070BD70B51D4A204B61
+:1023B0001468214E1C4D82005B1C9219AC4203D064
+:1023C000042803D2106806E0022801D3184670BD25
+:1023D00010688004800C0860002070BD10B5134A9E
+:1023E000164890600E200021C3009B1819615961A6
+:1023F000401C1028F8D300200F4A05E0022803D320
+:1024000083009B18196005E083009B181C68A404D6
+:10241000A40C1C60401C0428F0D310BD03490748DD
+:102420008860704764000020BEBAFECA00F5014013
+:102430000820000000F0014000F8014000C0FFFF4C
+:10244000FE48C07E7047FE4840687047FD48C07E29
+:102450007047FFB5F94E85B0706A346805686068EA
+:102460000190306A0390298D0798401A80B202903B
+:102470000898002804D0274638372046483002E024
+:10248000371D2846A0300090032038710598002899
+:102490001FD001287ED0022863D003287BD0EAA178
+:1024A000ED4808F058FE0898002806D0387903282F
+:1024B00003D0E5A1E94808F04EFEA16A7069FAF779
+:1024C000B0FDB860216A606A814265D900990860F0
+:1024D00034E1306A002803D1DBA1E14808F03BFE7B
+:1024E000288BE0494843421806980021002804D070
+:1024F0005043DD4908F00EFD411CA1610191AA88FD
+:10250000D848002142430698002804D05043D649B9
+:1025100008F000FD411CE161306AD24A801CA062D3
+:10252000298BD04B5143019A891AD04A891809182E
+:10253000A162AA7D01985A4340008018FF301930EB
+:1025400020626062306A081AC949FF38153888422B
+:10255000A9D2C84988427DD2BBA1C74808F0FBFD7B
+:102560008BE0288BBF4AE16850430A180698002187
+:10257000002804D05043BC4908F0CCFC411CA161A8
+:10258000AA88B848002142430698002808D0504342
+:10259000B54902E03EE073E0CEE008F0BBFC411C30
+:1025A000E161306A002803D1A7A1B44808F0D3FD47
+:1025B000A620405BAB4A0028288BE16821D050431D
+:1025C0000818A169401AA0622169A068A54A484379
+:1025D000A1694018A97D400051434018FF301730D1
+:1025E0002062A888E1695043411AA5480818606232
+:1025F000A06A316A401A9E49FF38553888423CD358
+:1026000051E750430818A169401A3168D638496823
+:102610004018D8E7284680300190C08C002802D0AE
+:10262000306A002803D188A1964808F094FDA88854
+:102630008C49E3694843C01AA06201999C46CA8C40
+:102640002169A368521A4B43A16959186346534341
+:10265000C91800E011E0AA7D824B49005A4389184D
+:10266000FF3117312162864941186162316A401A8F
+:102670007F49FF3855388842C2D20120387112E7AD
+:102680000898002803D03420005D00287ED1A88857
+:1026900074494843E169401A02994843A0622846B8
+:1026A00080300490C08C0028019825D0002803D0E9
+:1026B00065A1754808F04FFD04986A4AC18C0298DC
+:1026C0000818E16948434000FF3017302062A888AD
+:1026D0005043411A6A48081860626C4840680028F4
+:1026E00019D0A26A03990120511A614AFF3955395C
+:1026F000914285D23871D6E6002802D0039800288E
+:1027000003D151A1624808F026FD0198A16AD6388C
+:102710000818A062D0E7FAF7F2F97269014610468C
+:10272000FBF706FCA16A081A5149FF385038884265
+:10273000A5D2012009B0F0BD00980160009855496C
+:1027400000684018F86028468030028A0799511ABC
+:1027500009B2002904DD0599022901D0032100E016
+:10276000002179710E99002915D0028F002A1ED000
+:10277000418F4187A0352B7F491C4B4393420AD29E
+:102780007979491E002906DD012100E00CE079710C
+:10279000418F491C4187089838700898002808D054
+:1027A0003420005D002804D0022009B0F0BD0021D3
+:1027B000DFE708980121484020346075307FF27EC1
+:1027C0003946B37E9A4202D0FAF710FE04E00020A8
+:1027D000F076B07630607062002009B0F0BDF0B5E0
+:1027E0002A4F83B038680568416A2E460C68203647
+:1027F000717D00290AD0698E228D914206D1407ADE
+:10280000002803D110A1244808F0A5FCFAF777F9B5
+:102810001E4F39684A6901461046FBF789FB3F683D
+:102820000028796A096807D089880E4A51433A68B6
+:10283000D269891A08F06EFB698E2FE0B813002068
+:10284000B8000020E01300207372635C6C6C5F6C56
+:102850006D2E73302E630000310500003A05000034
+:10286000B7040000E204000040420F0033040000FF
+:102870005C0800001D030000D4040000DC0400001C
+:1028800094FBFFFFF50400001B050000A8000020DA
+:1028900014050000FF0B000021060000228D131814
+:1028A000994202DB491C698602E0401C10186886C8
+:1028B000B07D002806D19421688E095B884201D141
+:1028C000401C6886388BFB4E401C388320464030C5
+:1028D0000190C1888088081A218D401E401887B257
+:1028E000C03418E03068F449406A002300794000A1
+:1028F000085A009323795B00C95A081881B2287DD1
+:102900000023FFF7A6FD00280FD001280FD0EB49C8
+:10291000EB4808F020FC6A8EB81A00B20028E1DA11
+:1029200001980821817005F0BDFF03B0F0BD688EED
+:10293000401C6886EFE770B5DE4D09292B686A6890
+:102940007BD20C007C4424792419A7440463869626
+:1029500083A5A575A20000201062D17E042956D25D
+:102960000B007B441B79DB189F4451510147516A8E
+:102970000C68116808701168486010682030407D4C
+:10298000002808D1FAF7BBF869680968096CFBF7F9
+:10299000CFFA002817DC6868228D0168498E9142C1
+:1029A00005D123468033998A8A1ADA8204E0891A8B
+:1029B000962211530168498E21850268C16811640D
+:1029C000C168416111E068680168098E228D8B1A27
+:1029D00022468032D3820168098E218501680B6C02
+:1029E000C3600B6C4361886C1062204606F0C8FB24
+:1029F000002821D0B3A1B74829E0D068506105F084
+:102A000088FA002818D0EF20AEA180001FE0ADA109
+:102A1000B1481CE0D07E042817D20100794409791E
+:102A200049188F441212010B06F0E6FC002803D06F
+:102A3000A4A1AA4808F08FFB70BD2DE005F09FFB14
+:102A40000028F9D09FA1A64801E09EA1A54808F062
+:102A500082FB70BDFDF7CBFD70BDD87E022806D08D
+:102A6000D87E032806D0FF2096A1AB300EE0FFF7FA
+:102A7000B6FE70BD00F013FC70BDD87E0228F6D003
+:102A8000D87E0328F6D0FF208EA1B83008F063FB73
+:102A9000F0E7FAF719F870BDFF208AA1C630D6E733
+:102AA000F3B50126834C904D81B00F46092945D2DC
+:102AB00008007844007900188744042D38382D40E8
+:102AC000403838000121884800F0D0FB3946019891
+:102AD000FFF731FFE87E022826D160680468406A6B
+:102AE0000768F9F7EAFFB988804A5143E269891A11
+:102AF000D639E162B72803D283200001081A02E028
+:102B0000081A7B494018E0627A48E16A814200D89D
+:102B10000846E06205E00198FFF70DFFE87E022815
+:102B200002D128682030067503B0F0BD25600198F9
+:102B3000FFF701FF0020206003B0F0BDFF2061A17E
+:102B4000623008F008FB03B0F0BD70B506460C46D5
+:102B500009291FD208007844007900188744040D21
+:102B600011110D1A1A1111000121634800F07EFBAA
+:102B700021463046FFF7DFFE70BD3046FFF7DBFE33
+:102B800070BD4C4D5C4828603046FFF7D4FE0020F5
+:102B9000286070BDFF204BA1883008F0DCFA70BDC2
+:102BA000F0B5514985B0CA7E0026424C032A03D0B5
+:102BB0002831CA7E032A64D100252160002824D050
+:102BC00001280ED03FA14D4808F0C5FA2068002E1C
+:102BD00005604562256054D049484560002005B035
+:102BE000F0BD0320887600E020BF2068C17E002968
+:102BF00003D0C17E827E9142F6D0C17E002902D0F0
+:102C000000268576E2E70126FBE700260327084633
+:102C10008F76C97E032903D0C07E00282DD02DE0F9
+:102C2000007F002803D127A1364808F094FA2068D5
+:102C3000067F684607714771F9F761FF0290FF2030
+:102C4000F530039001216846017069463046FAF775
+:102C5000CDFB2068007FFBF7F7F900280BD0206838
+:102C6000007FF9F731FF20680577C5768576056026
+:102C70000126456202E020BFEBE701262068857649
+:102C8000A4E70C2005B0F0BD10B5174800F04DFBCF
+:102C9000194800F04AFB1C49002008751849487083
+:102CA00011494861144A506188769076014948601C
+:102CB000086010BDA800002034B4010048280100BD
+:102CC0005B0600007372635C6C6C5F6C6D2E73301E
+:102CD0002E630000B6030000C3030000D60300000B
+:102CE000DB030000E2030000B8130020E204000050
+:102CF00087F8FFFFEC060000E01300201E03000031
+:102D0000B80000207E02000008140020F8B5FF4E35
+:102D100005463068002401270004810FFC48006844
+:102D2000800F814204D0FF20FA49D03008F013FA16
+:102D30003068F94E0004810F30680006800F814230
+:102D400004D0FF20F349D13008F005FAF348C069F8
+:102D50003168800F0904890F884204D0FF20ED49B3
+:102D6000D23008F0F8F9EE480570EE4DEC76AC760E
+:102D7000ED4EF476B476ED48077104606C627462CF
+:102D80002C60EB4F346028467C6000F0CEFA304671
+:102D900000F0CBFAE74804757C706C617461AC7626
+:102DA000B476E54844600460F8BDE04908717047B6
+:102DB000F8B5DC490546CA7EDB48DF4C002A02D163
+:102DC000C27E002A03D0C97E022907D009E0DB4871
+:102DD0002160F9F725FE216808770AE0C17E002905
+:102DE00001D00C20F8BD2060D548F9F719FE216804
+:102DF0000877CF48456021680860D2484862284675
+:102E00000121BC30F9F790F9A035287F8007800FA9
+:102E1000401C28772068007F002803D1BD49CA489C
+:102E200008F099F9F9F749FEC849884200D20846E6
+:102E3000C749401886B221680320C87604F084FF91
+:102E40002168086104F0A8FF01270025002826D08A
+:102E500004F0A2FF21684A6A106008680121077027
+:102E60006846F9F7EAF868460078BA49000208F0BF
+:102E700051F80F46F9F743FEF119FAF7D2F8216835
+:102E8000C86022680320107250721571107FD37EC3
+:102E9000111D967EB3420ED0FAF7A8FA0FE0F9F7AB
+:102EA0002EFE3146FAF7BDF82168C8600868057043
+:102EB00008684770E5E7D576957615605562206815
+:102EC000058300202560F8BD7047F8B5954EF17E6A
+:102ED000002903D19449C97E002901D00C20F8BDF6
+:102EE0000221F176914F934D77623560002438606E
+:102EF0002C7500943979C0304A00974900798A5A74
+:102F00004000085A2346101881B222462046FFF797
+:102F1000A0FA002803D07F49904808F01CF92C61E2
+:102F20000120AC6028756C862C868D4884753968C4
+:102F3000088D401E088534830020F8BD10B57E48FA
+:102F400001244068817E03290CD00168497800295A
+:102F500006D0006A8349884202D9002405F03CF972
+:102F6000204610BD0024FBE77348406802681178D2
+:102F7000491C1170016A0068C26A914204D8007D40
+:102F8000012801D0012070470020704700207047C1
+:102F9000F8B5694D63482860416A00270C680068ED
+:102FA000342126460F548036B17F002927D1007D79
+:102FB000032824D1F9F7A3FD29684A690146104680
+:102FC000FAF7B6FF00281ADD2D68674B6A6A296890
+:102FD000126892880091C9695A43511A07F09AFF02
+:102FE000218D401C4218009953480A862968B28AEC
+:102FF0000B8ED21A12B2002A03DC0760F8BD2F60D4
+:10300000F8BD012220318A7521464031CA8889885D
+:10301000514F511A228D491E89188EB20546C0346F
+:1030200019E0496A09794900795A00220092028E12
+:103030002379007D5B00FB5A591889B20123FFF701
+:1030400008FA00280ED001280FD002280AD03149F2
+:10305000464808F080F829680868028EB21A12B251
+:10306000002ADEDA00202860F8BD28680068018E9A
+:10307000491C0186EFE770B52F4900244D680628EA
+:1030800076D202007A441279921897441820020EE0
+:10309000240D002000F08FF9EC76AC762C60002136
+:1030A00008466C6200F0E2F870BD1D480D680078BB
+:1030B000EFF72AF9EC76AC762C606C6270BD0120DB
+:1030C00000F079F90021084600F0D0F870BD2968B9
+:1030D0000320087570BD686A29680068CA698A603B
+:1030E0008188214A51432A68D1600146C0310A8A49
+:1030F00002838A7B82754A8A82808A8AC280C98AD0
+:10310000018129680220087570BD31E000E400E00B
+:1031100008E400E0C42C010018E400E000ED00E049
+:10312000A0000020B8130020E0130020B000002011
+:10313000B800002008140020A8000020A12A0100E7
+:103140004B2B0100A4000020C9020000F60500007E
+:10315000BB0200001027000034B40100520300003D
+:1031600028140020D9821300E204000007060000A2
+:10317000DD49DE4807F0EFFF70BD70B500280BD0C9
+:103180000024DB4D01280ED002282FD0EF20D64995
+:10319000C00007F0E0FF70BD00F06BF900210846A9
+:1031A00000F064F870BD686801684C70C47684767D
+:1031B0000460D04E446201220021706800F063FF79
+:1031C00071680846C0318C72CC72FFF77EFE002811
+:1031D00003D0C549C84807F0BEFFF9F7DBFBC74875
+:1031E0006C600078EFF790F86C6070BD00F041F90A
+:1031F0006868C4768476046000214462084600F062
+:1032000035F870BDBA494968CA7E022A08D10A68F1
+:103210001378002B04D150600968CA6A1018C8627C
+:10322000704710B5B24A002952680BD0012906D068
+:10323000022906D0AC49B24807F08DFF10BD801EB0
+:1032400000E0401F106210BD08B50020C043694671
+:103250000880AC48C07E002801D0002008BD084688
+:1032600000F0F6F90028F9D0012008BD70B5A04C97
+:1032700005466268002908D0002A04D0FF209A4938
+:103280000D3007F068FF656070BD002A04D1FF2093
+:103290009549133007F05FFF0020606070BD38B5BE
+:1032A000934C20680168497801291FD001216846A4
+:1032B000F8F7C3FE684600789349000207F02AFE3B
+:1032C0002068426AC06812685118F9F7AAFE21689E
+:1032D000C8608C4822680321824202D0108B0A28E1
+:1032E00010D2108B401C108351720DE07D21C068FC
+:1032F000C900F9F796FE2168C86004F025FD216831
+:103300000861E6E702205072117200231371107FEA
+:10331000D47E111D957EAC4202D0FAF767F838BD15
+:10332000D37693761360536238BDF8B5704C05467A
+:103330001F27EE7E042E2DD230007844007900182D
+:103340008744312801237148854203D0664970487B
+:1033500007F001FF02202560A87600E020BF216869
+:10336000C87E002803D0CA7E887E8242F6D0CA7EFC
+:10337000002A04D000228A760C27226010E0002266
+:103380008A760A604A6222600DE00120FFF708FC9D
+:10339000074603E054495F4807F0DDFE002F02D0E6
+:1033A000E87EB042C5D1E87E002803D04E495A4895
+:1033B00007F0D1FEF8BDF8B54D4D01286A68516A95
+:1033C0000C6846D10879554940000B5A1068077DB2
+:1033D0000126032F06D0027D022A13D0007D01288A
+:1033E00024D036E00027076110688760942000969B
+:1033F000025BC420005D4000085AC01881B23B4601
+:1034000003201EE022468032D78C07610096C4203C
+:10341000005D928A4000085AC01881B20023022041
+:10342000FFF717F8696809680E750CE0942000969C
+:10343000025BC420005D4000085AC01881B200231E
+:103440000120FFF706F8002803D02749344807F089
+:1034500082FEF9F79FFA29480078EEF755FF696870
+:10346000002008830B68228D5A86096820318875F0
+:10347000F8BDF8B51E4D002168680C46006842781A
+:10348000002A01D0447027E00078002809D00121EB
+:103490006846F8F7F7FD684600781B49000207F018
+:1034A00039FD6868426AC06812685118F9F7B9FDB9
+:1034B0006A68D060147103205072107FD37E111D92
+:1034C000967EB34202D0F9F791FF03E0D47694766A
+:1034D0001460546268680483F9F75CFA074800785E
+:1034E000EEF712FFF8BD0000C42C010056070000E3
+:1034F000A8000020B800002003070000A000002062
+:103500009D070000E013002010270000B8130020E2
+:1035100007020000130200001902000034B4010089
+:10352000BC060000F8B50024E948FEF73EFE00287E
+:1035300025D1E84FC02026464643F51901462846C6
+:1035400007F0DEFC0120B8556C80E34900200870CC
+:10355000E24A4A8080356962E149641C0870A962C8
+:10356000E049E4B208704A80A963032CE2D3D8484A
+:10357000FEF733FED648FEF718FE002801D00C20D7
+:10358000F8BDFF211931D84807F0BAFCD64801210F
+:1035900001704480D5490020087208750877D44925
+:1035A0008872CB48FEF719FE0020F8BD10B5C84858
+:1035B000FEF7F3FD002803D0CEA1282007F0CBFDB5
+:1035C000C348FEF7EAFD002803D0CAA12D2007F06A
+:1035D000C2FDFFF7A7FF002803D0C6A1332007F0E4
+:1035E000BAFD10BD10B50446B948FEF7DEFD00284F
+:1035F00001D00C2010BDBC490878002807D000205D
+:103600000870B3482160FEF7E8FD002010BDB04807
+:10361000FEF7E3FD1F2010BD70B505460C46AC4813
+:10362000FEF7C3FD002801D00C2070BDAE4A5088C3
+:10363000A84202D11078002804D0A548FEF7CDFD9D
+:10364000122070BDA2482260FEF7C7FD002070BDA9
+:1036500010B504469E48FEF7A8FD002801D00C20B6
+:1036600010BDA1480178002907D00020C043208068
+:103670009748FEF7B2FD122010BD40882080944884
+:10368000FEF7ABFD002010BD10B504469048FEF7D4
+:103690008CFD002801D00C2010BD2078002804D01B
+:1036A0008B48FEF79AFD0C2010BD01202070884841
+:1036B000FEF793FD002010BD10B504468448FEF7C8
+:1036C00074FD002801D00C2010BD824A0021C020CA
+:1036D0004843105C00280AD0C023002059435054AE
+:1036E000881820607A48FEF778FD002010BD491C3C
+:1036F000C9B20329EBD37648FEF76FFD1F2010BD3A
+:10370000032805D2C0225043724A135C002B01D01B
+:1037100012207047801808600020704710B5002202
+:103720000C46032809D2C02148436A490B5C002B90
+:1037300014D122704018606018E003280ED164484C
+:10374000FEF733FD002809D167484188032902D1DB
+:103750000178002904D05E48FEF73FFD122010BD1D
+:1037600060605B48FEF739FD01202070002010BD2D
+:1037700010B504465648FEF718FD002801D00C206D
+:1037800010BD2088534A032804D2C0214843105C4E
+:10379000002801D00020208000202188491C89B207
+:1037A0002180032900D300212180C0235943515C8B
+:1037B00000290BD0401CC0B20328EED30020C04328
+:1037C00020804348FEF709FD122010BD4048FEF757
+:1037D00004FD002010BD70B505460E463C48FEF7BE
+:1037E000E4FC002801D00C2070BD2888341D03287B
+:1037F00004D303D0A04201D3002028800020361D2E
+:103800001DD0394B33492A88521C92B22A80A242D9
+:1038100000D300222A80042A02D3A24217D301E057
+:10382000032A05D0C02672438A5C002A0FD002E02A
+:103830001A78002A0BD0401CC0B2A042E3D300206B
+:10384000C04328802248FEF7C8FC122070BD2048E3
+:10385000FEF7C3FC002070BD10B504461C48FEF7FF
+:10386000A4FC002801D00C2010BD2078002804D032
+:103870001748FEF7B2FC0C2010BD01202070144840
+:10388000FEF7ABFC002010BD10B504461048FEF753
+:103890008CFC002801D00C2010BD217801200029CB
+:1038A00002D0012905D008E061680A78002A09D011
+:1038B00003E061680A78002A04D00548FEF78DFC11
+:1038C0000C2010BD08700248FEF787FC002010BDD8
+:1038D000C00000205814002098160020FFFF0000B0
+:1038E000C1000020C6160020D8160020B8170020FE
+:1038F000D81700207372635C6C6C5F64622E630087
+:1039000010B5282107F0FAFA10BD70B50546007809
+:103910000A0700090001120F1043287007290ED270
+:10392000080078440079001887440305030503075D
+:103930000300062408E00C2406E0222404E000240E
+:10394000F8A1572007F007FC687880098001204320
+:10395000687070BD00780007000F704710B5C01C7C
+:1039600007F0F5FC10BD0A4610B5C11C104607F063
+:10397000EEFC10BD10B5093007F0E9FC10BD02786F
+:10398000BF23C9071A40490E0A43027070470078E6
+:103990004006C00F704702785206520EC9010A4312
+:1039A0000270704770B50C460546C11C20460930B0
+:1039B00007F0CDFC20784006400E2070297849069B
+:1039C000C90FC9010843207070BD70B515460E4679
+:1039D00004461F2A03D9D3A1A82007F0BCFB204628
+:1039E0002A463146093007F02CFA6078AD1D80096F
+:1039F0008001A906890E0843607070BD70B5054648
+:103A000040780E468406A40E062C03D2C5A1B82029
+:103A100007F0A1FBA41FE4B21F2C00D91F242946E4
+:103A200022460931304607F00CFA204670BD70B5C9
+:103A300015460E4604461F2A03D9BAA1CC2007F02A
+:103A40008AFB20462A463146093007F0FAF96078A9
+:103A5000AD1D80098001A906890E0843607070BD04
+:103A600070B5044640780E468506AD0E062D03D28D
+:103A7000ACA1DD2007F06FFBAD1FEDB21F2D03D908
+:103A8000A8A1E12007F067FB21462A46093130460C
+:103A900007F0D7F9284670BD0A78C2734A780274D5
+:103AA0008A784274C978817470470A78C2744A78F7
+:103AB00002758978417570474176090A81767047A9
+:103AC000C176090A017770474177090A8177704703
+:103AD000C175090A017670478175704720300279F7
+:103AE000C90652095201C90E0A43027170472030BB
+:103AF0000279D206D20E49010A430271704710B50D
+:103B00001F3007F019FC10BD417800788906890E36
+:103B10000007000F06D0012808D0022809D0062887
+:103B200010D10AE0891F1F290AD90BE00C2907D000
+:103B300008E0891F1F2903D904E0891F1F2901D824
+:103B400001207047002070474178007889060007FF
+:103B5000890E000F042805D1062903D3252901D891
+:103B6000012070470020704770B401780907090FE1
+:103B700003292ED0052931D1411C827E0C46437E7B
+:103B800011021943037FC27D1D02037EC67E1B0204
+:103B90001343827D407835438006800E22281DD154
+:103BA00006291BD31920C001814217D8FF26F436FD
+:103BB000B54213D8002A11D0082A0FD88A420DD254
+:103BC0008B420BD8617F227F09021143814208D9C1
+:103BD00004E040788006800E0C2802D070BC0020E3
+:103BE000704770BC0120704710B5222107F086F99C
+:103BF00010BD10B502788B07920892009B0F1A43F4
+:103C000002704278520952014270012908D00229FB
+:103C100006D0032905D0FF2042A1E83007F09BFA27
+:103C200010BD01210A43427010BD10B502788B0708
+:103C3000920892009B0F1A43027042785209520177
+:103C40004270012907D0022905D0032904D035A1EB
+:103C5000384807F080FA10BD01210A43427010BDB8
+:103C600000788007800F70470278EF23C9071A4059
+:103C7000C90E0A43027070474178C078C906C90E60
+:103C80000E2835D202007A44127992189744060918
+:103C90000C0F1215181B1E2124272A2D0C2929D0A0
+:103CA0002AE0082926D027E0022923D024E017297A
+:103CB00020D021E00D291DD01EE001291AD01BE0E3
+:103CC000012917D018E0022914D015E0092911D0D4
+:103CD00012E009290ED00FE001290BD00CE00129D8
+:103CE00008D009E0062905D006E0022902D003E049
+:103CF0001B2901D8012070470020704770B5054688
+:103D0000C1700E2926D20800784400790018874433
+:103D100006131517191B1B151D1D1B1B1F150C2426
+:103D20001DE000007372635C756C5F7064752E63D8
+:103D30000000000001020000082410E002240EE050
+:103D400017240CE00D240AE0012408E0092406E011
+:103D5000062404E000249A499A4807F0FCF96878A0
+:103D6000400940012043687070BDC0787047C17140
+:103D7000090A01727047017AC2790802104370473C
+:103D80004172090A81727047817A427A08021043AF
+:103D90007047C172090A01737047017BC27A080239
+:103DA000104370474171090A8171704781794279E6
+:103DB00008021043704701717047007970474173E2
+:103DC000090A81737047817B427B08021043704768
+:103DD00070B4017AC37909021943431C857A1C46E1
+:103DE000467A2B023343657926792C023443C21C70
+:103DF000754E00798D1FB54215D8FF25F435AB42BD
+:103E000011D800280FD008280DD888420BD28C4238
+:103E100009D8507A117A00020843B11D884202D8AD
+:103E200070BC0120704770BC0020704710B5001DA9
+:103E300007F082FA10BD0A4610B5011D104607F0C2
+:103E40007BFA10BD4172090A81727047817A427A09
+:103E5000080210437047017170470079704710B530
+:103E6000001D07F081FA10BD0A4610B5011D10466D
+:103E700007F07AFA10BD0A780273497841737047E7
+:103E8000027B0A70407B4870704710B50E3007F017
+:103E90006BFA10BD0A46014610B50E31104607F008
+:103EA00063FA10BD0A7882754A78C2758A780276FC
+:103EB000C97841767047827D0A70C27D4A70027E61
+:103EC0008A70407EC870704710B5001D07F04CFA2C
+:103ED00010BD0A4610B5011D104607F045FA10BD89
+:103EE0000A7802734A7842738A788273C978C173F8
+:103EF0007047027B0A70427B4A70827B8A70C07B6B
+:103F0000C8707047017170474171090A817170472B
+:103F1000C171090A0172704700797047817942794D
+:103F2000080210437047017AC279080210437047B3
+:103F300001717047007970470171704710B5001D1D
+:103F400007F012FA10BD0A4610B5011D104607F021
+:103F50000BFA10BD10B5001D07F006FA10BD0A4699
+:103F600010B5011D104607F0FFF910BD70B51546DC
+:103F70000E4604461B2A03D91149144807F0EBF8F2
+:103F80002A463146E01C06F05CFF6078E9064009ED
+:103F90004001C90E0843607070BD70B50546407899
+:103FA0000E46C406E40E1B2C03D90549084807F049
+:103FB000D2F82246E91C304606F043FF204670BD89
+:103FC000243D0100A10200007A0C0000F103000072
+:103FD000FD03000070B504460020A083208C1E461F
+:103FE00048431546114606F0A3FF2084F0002946F9
+:103FF00006F090FF401C80B20146192269439202EC
+:10400000E083914201DD401EE0837D2029460002CD
+:1040100006F080FF401CA08470BD70B50A7BD206FC
+:10402000D20E0A73002282758B181B7ADC075B089C
+:10403000DD07E40FED0F2C195B08DD07ED0F2C19E0
+:104040005B08DD07ED0F2C195B08DD07ED0F2D195F
+:104050005C08E307DB0F5B196508EC07E40FE41865
+:104060006B081B1984186374847D521CE318D2B248
+:104070008375052AD8D3D8B2252803D9E1A18A208F
+:1040800007F069F870BD70B504460B462546264614
+:10409000214600202835C0368031032B0AD0002B62
+:1040A0003AD0012B41D0022B03D1A11C2846FFF7A7
+:1040B000B4FF70BD2880A871E871E8722873687336
+:1040C000A873A870E870287168716876A8832B4679
+:1040D00068842033987128859872E8752876E8738B
+:1040E0002874D872187398731A752884FF22603563
+:1040F000AA709875088248828882C882088348839B
+:104100004877C884A4221055088748872421085579
+:1041100060843070B07170BDC8848877A1882389AD
+:104120000A462846FFF756FFBFE7C884F38A728A1B
+:10413000A1882846FFF74EFF70BD70B504460346C0
+:1041400028348033054603290AD0002933D00129B9
+:1041500038D0022903D1A91C2046FFF75EFF70BDAD
+:1041600000202080A071E071E07220736073A07362
+:10417000A070E070207160716076A0832146608439
+:104180002031887120858872E0752076E073207474
+:10419000C872087388730A752084FF226034A27085
+:1041A00088751883987618742421586148551877B3
+:1041B000A035287370BDA9882B890A462046FFF7D1
+:1041C00009FFC8E7586AA988C38942892046FFF7D2
+:1041D00001FF70BD70B5867D0D460446002E01D0EE
+:1041E000252E01D9122070BD002A18D0287EE17D2D
+:1041F00050430818252106F08DFEE1750846CA08CF
+:104200004907490F834BAA18595C127A914308D089
+:10421000314606F07FFE491CCAB200200AE00020A9
+:1042200070BD2076002070BD002803D02118097CC5
+:10423000511ACAB22118497C91423AD32918097AF5
+:10424000C943CB07DB17D21A521E1206120E35D005
+:104250008B07DB17D21A521E1206120E32D04B07F2
+:10426000DB17D21A521E1206120E30D00B07DB17C4
+:10427000D21A521E1206120E2ED0CB06DB17D21AFD
+:10428000521E1206120E2CD08B06DB17D21A521EAB
+:104290001206120E2AD04B06DB17D21A521E120635
+:1042A000120E28D00906C917511A491E0A06120E05
+:1042B00026D0401C0528B7DB1F2070BDC00020762B
+:1042C000002070BDC000401C2076002070BDC000E2
+:1042D000801C2076002070BDC000C01C207600200D
+:1042E00070BDC000001D2076002070BDC000401DC4
+:1042F0002076002070BDC000801D2076002070BD9B
+:10430000C000C01D2076002070BD70B50D4604466B
+:10431000072904D9FF203BA15D3006F01CFFE0789F
+:10432000502108406907490F88300843E070A078A1
+:10433000A72108401830A07060785E210840203026
+:1043400060702078BC2108404030207070BD017939
+:10435000490901D000207047002230B41146445C66
+:10436000491CE3076408E507DB0FED0FEB18640851
+:10437000E507ED0FEB186408E507ED0FEB1864088F
+:10438000E507ED0FEB186408E507ED0FEB1864087F
+:10439000E507ED0FA407EB18E40FE318D218D2B22B
+:1043A0000529DCDB002A02D030BC0120704730BC7C
+:1043B0000020704738B505460C466846FCF74EF8B5
+:1043C00000281ED069460020085620720921615637
+:1043D0000022411A00D549422035EB788B420FDC90
+:1043E000FF2B0DD0A17A491CC9B2A1722B79994239
+:1043F00002D8617A7F2903D160720020A072012265
+:10440000104638BD7372635C6C6C5F7574696C2E9A
+:104410006300000044B40100F8B50024F74EFF200B
+:10442000B470F0702546F64F06E0042D04D3FF204B
+:10443000F4A1AB3006F08FFEFF212846A03148439F
+:10444000FF213331C0194A1C0C540146FF3114546A
+:1044500021310C754C75F178A94202D1B470FF215D
+:10446000F170FF219D314A1C6D1C0C54EDB21454A7
+:10447000042DDAD30020FF21A0314143C919FF31B7
+:1044800081318C77401CC0B20428F4D3E048FFF798
+:10449000ABFB0021DE48FFF7E7FB0121DC48FFF71B
+:1044A000A8FBDC49FF20087048708870C87008714C
+:1044B0004871F8BDB0E71B20704710B4D04A002106
+:1044C000FF23A0334B439B18FF3381339B7F002B8B
+:1044D00004D0491CC9B20429F2D30DE004290BD23F
+:1044E000FF23A0334B439A180124FF328132947783
+:1044F0000170204610BC704710BC0020704730B4DB
+:104500000025042825D2FF220146A0325143BC4A8F
+:1045100089180B46FF3381339A7F002A19D0FF2474
+:104520003334621C655455541A46603A15755575F6
+:10453000B24AD478844202D19570FF20D070FF2017
+:104540009D304554FF319E310D709D7730BC012068
+:10455000704730BC0020704704280ED2FF2201466D
+:10456000A0325143A64A8918FF318131897F002941
+:1045700003D0A8494871012070470020704710B44B
+:10458000A449FF224979A03251439D4A82B089183B
+:104590000A46FF322132937C6C462370D27C227112
+:1045A000237822795A40802A0AD022782223520680
+:1045B000520E5A435118016002B010BC01207047DE
+:1045C00002B010BC002070479248FF214079A03112
+:1045D00048438B4981B041180846FF303330FF31E2
+:1045E0002131CA7C69460A7003780922097859404A
+:1045F00080290ED0037869460B7009784906490E68
+:10460000491C914208D26A461178491CC9B21170FE
+:1046100009E0002001B0704769460978090601D514
+:10462000002100E080210170012001B070470428C2
+:104630000ED2FF220146A0325143714A8918FF3140
+:104640008131897F002903D07249087101207047A8
+:104650000020704710B46F49FF220979A0325143FE
+:10466000674A82B089180A46FF322132947C6B4631
+:104670001C71D27C1A701C781A7994420AD01A786C
+:1046800022235206520E5A435118016002B010BC48
+:104690000120704702B010BC0020704738B55D485B
+:1046A0000179FF20A0304143554808180146FF31E9
+:1046B00021318A7C6C4622700922FF303430037825
+:1046C0002478A34223D004786B461C701B785B06C9
+:1046D0005B0E5B1C934205D26B461A78521CD2B219
+:1046E0001A7006E06A461278120601D5002200E030
+:1046F00080220270087D401C0875087D497D884233
+:1047000003D140A1444806F026FD012038BD002019
+:1047100038BD4048FF210079A0314843384940184E
+:10472000FF302130C17C807C814201D10120704763
+:10473000002070473748FF210079A03148433049B5
+:104740004018FF302130817CC27C092013464B4049
+:10475000802B0AD049065206490E520E914201D3CF
+:10476000881A01E0511A401AC0B2704709207047F8
+:104770000022042813D2FF23A0335843204BC01833
+:10478000FF239F331B5C002B09D0FF300A702130C0
+:10479000027D437DD31A0B704275012070470020C3
+:1047A0007047042811D2FF22A0325043144A8018C7
+:1047B000FF229F32125C002A07D0FF302130027D99
+:1047C000407D101A08700120704700207047104982
+:1047D0000160704704280ED2FF220146A0325143E7
+:1047E000074A8918FF318131897F002903D009499F
+:1047F000087001207047002070470000101800204A
+:10480000141800207372635C646D5F712E63000086
+:10481000901E0020C70000205A020000AC49CA7850
+:10482000FF2A03D000210160084670478A78A94911
+:10483000012A02D001600120704700207047A6487D
+:104840000178012907D001210170A4480178A0480E
+:10485000C170012070470020704704280ED2FF224B
+:104860000146A03251439E4A8918FF318131897F28
+:10487000002903D0994948700120704700207047F3
+:104880009349964BCA785B789A4206D18A78203948
+:10489000002A02D0016001207047002070478C4838
+:1048A0008E4AC1785278914209D1FF21C170801C93
+:1048B0000178002903D000210170012070470020F9
+:1048C00070478348854AC1785278914204D18078F4
+:1048D000002801D0002070470120704704280ED224
+:1048E000FF220146A03251437D4A8918FF318131B0
+:1048F000897F002903D07949C870012070470020C2
+:10490000704710B47549FF22C978A0325143744AE8
+:1049100082B089180A46FF328132147F6B461C70C0
+:10492000527F1A711C781A79FF3162403731802A20
+:104930000AD01A7822235206520E5A4351180160A7
+:1049400002B010BC0120704702B010BC00207047BC
+:104950006248FF21C078A0314843614981B04118C5
+:104960000846FF309D30FF3181314A7F69460A7029
+:10497000037803220978594080290ED003786946CC
+:104980000B7009784906490E491C914208D26A46C3
+:104990001178491CC9B2117009E0002001B07047BC
+:1049A00069460978090601D5002100E080210170DF
+:1049B000012001B070474948FF21C078A031484329
+:1049C00047494018FF308130417F007F814201D14B
+:1049D000012070470020704704280ED2FF220146B4
+:1049E000A03251433E4A8918FF318131897F002925
+:1049F00003D03A498870012070470020704710B4F6
+:104A00003649FF228978A0325143354A82B089184D
+:104A10000A46FF328132147F6B461C71527F1A7036
+:104A20001A781B79FF3137319A420BD06A461278D7
+:104A300022235206520E5A435118016002B010BC94
+:104A40000120704702B010BC002070472348FF21AE
+:104A50008078A0314843224981B04018FF219D3120
+:104A6000095C6B4619700321FF309E3002781B7879
+:104A70009A4219D003786A46137012785206520E81
+:104A8000521C8A4205D26A461178491CC9B211707B
+:104A900006E069460978090601D5002100E0802179
+:104AA0000170012001B07047002001B070470B4831
+:104AB000FF218078A031484309494018FF308130F8
+:104AC000417F007F814201D1012070470020704763
+:104AD00010180020F017002012180020C700002036
+:104AE00014180020F8B5FD4F0A46044600207978D6
+:104AF000FB4D0646002902D0012909D00FE0F949F3
+:104B0000497A00290BD0002A08D10120787005E0ED
+:104B1000A97F002903D0002A00D17E700120797876
+:104B20002B23594349198B7F034311D0002A22D1EB
+:104B30002A22A01C1F3106F084F966700420207020
+:104B40000120A07078782B2148434019867712E025
+:104B50002878012801D00020F8BD002A0BD166700A
+:104B6000132020701C22A91CA01C06F06AF9A67153
+:104B70002E70DD48C6770120F8BDD948017800299C
+:104B800001D080887047D9487047F8B5D44E0746A1
+:104B9000B07F00282DD13846FEF7DCFE002101252C
+:104BA000D34C072824D202007A44127992189744F1
+:104BB0000305081F1F1F0A00217006E025702172DF
+:104BC00008E0032000E002202070CA493846FEF7C2
+:104BD00015FF20723846FEF7DAFE6070C649384687
+:104BE000FEF7C1FEBD4CC54F20787F2807D101E0FC
+:104BF0002172F8BDFF20C2A1543006F0ACFA207833
+:104C000038707F202070B577032002F0E7FEF8BDF2
+:104C100010B5002002F072FE002812D0FBF79CFBBA
+:104C200000210120FBF7A0FABA48FBF7ACFBAE4C21
+:104C3000A06AFBF7ABFB2079032805D0022803D03C
+:104C400006E000F0F3FD10BD01210020FBF716FC8B
+:104C5000FBF7FBFBB04C6078002803D0FBF77DFF2F
+:104C6000FBF7D9FB0320E07010BD70B59E4900280A
+:104C7000CA8D08D0FF2A0DD25004000CC885FF2829
+:104C800008D9FF2005E0012A04D95008C88501D1C0
+:104C90000120C88591484268012A01D0002A01D12B
+:104CA0000D224260D24317239B4C5A43637B3B2522
+:104CB000DB436B43D2184260C98D900C06F02AF991
+:104CC000617370BDF8B5944CE078022804D0E078A8
+:104CD000012801D00C20F8BD0020814A05462B2177
+:104CE000414389188D77401CC0B20228F7D3157054
+:104CF0006078002804D0FBF796FBFBF73FFF657058
+:104D0000794845778577C5778449257001228A7768
+:104D10000571A570CA760A774A77714E0146324608
+:104D2000736F7432B46FF66FD7688B60CC600E61AE
+:104D30004F6112698A6105770020F8BD10B5764A87
+:104D40000023D3701371684B596318630120D0702E
+:104D5000FFF7B8FF002803D069A1714806F0FBF9FE
+:104D600010BDF1B582B00C2001906B480090C07866
+:104D7000012806D00098C078022802D00C2003B089
+:104D8000F0BDFBF7F0FA0020FBF7B1F8564C207F9E
+:104D9000002837D0524920460F4682687437C368CE
+:104DA000056946694A678B67CD67FE60806938612F
+:104DB00000266677A677594DE87E002805D1287F22
+:104DC000002802D1687F00281AD0009800780028B7
+:104DD00016D02079032802D0022805D008E005214A
+:104DE000504800F040FD03E003214E4800F03BFD39
+:104DF000A97E3846FBF7F3F80020019026770CE0F7
+:104E0000267703E00098C078022804D00098C07884
+:104E1000022828D00AE0002001900098C0780128DC
+:104E200004D10099087300980221C170606B017869
+:104E3000002903D00178001DFBF714F9206B0178DD
+:104E4000002906D0384A401CFBF777FE0099012064
+:104E500048700298A0623548FBF717FAFBF78EFA04
+:104E6000019803B0F0BD00990120C8700C2003B078
+:104E7000F0BD70B5FBF777FA274CE078022803D035
+:104E8000FBF77CFA0C2070BD012017496073C885C0
+:104E90000220FBF765FA2648FBF739F9254E002575
+:104EA000A0780321401C06F035F8A170885D012828
+:104EB00044D06D1CEDB2032DF2D3FFF7A9FE20798B
+:104EC000002809D0012807D002283DD003283BD074
+:104ED0000BA1194806F03FF9002070BDD00000205A
+:104EE000B41E0020F41E0020341F0020FFFF00002D
+:104EF000D41E0020DD1E0020D61E0020FC1E002037
+:104F00007372635C6C6C5F64645F7363616E2E6369
+:104F1000000000006C1F0020541F0020141F002000
+:104F200051030000941F00206F1F00204CB40100AB
+:104F300052B401002F1F0020EA030000C8B2FC4950
+:104F4000085CFBF7F6F8B8E7EEF762F8C4E770B56F
+:104F5000F84C0125A577E37F002B01D03A2070BDE6
+:104F60000026002802D1A07B884209D1A173667770
+:104F70001146F14806F0EBF96577F04805702577A2
+:104F8000A677002070BD024600200123E949002ACF
+:104F900003D0012A03D0122070478B7400E088747C
+:104FA0000B774A767047E34A032800D151611076A7
+:104FB0000120107700207047E049012803D0032822
+:104FC00001D0002000E0012008717047D948017F1E
+:104FD000002903D0407E002803D170474079002883
+:104FE000FBD00120704710B5FBF709FAFBF7FCF97D
+:104FF000FBF708F9FBF7AAF9D04C6078002805D038
+:10500000FBF711FAFBF7BAFD002060700120207356
+:105010000220E070FBF7B2F9002010BDC7494871CB
+:10502000704710B500F002FC10BDF0B5C44EC34D82
+:1050300083B0002810D0C348FEF766FD002804D1D5
+:10504000C048FEF781FD002806D0BA4C207903281D
+:105050000DD1A07F00280AD0E87805286BD2010086
+:105060007944097949188F44666666F7F600E8784E
+:1050700005287AD201007944097949188F44757559
+:105080007502EE00AF48FEF765FCAD498870AE488A
+:105090000190807F002803D1FBF736F8002800D06C
+:1050A000012000906878002813D00526761EF6B2FD
+:1050B000FBF785FD0746022805D1002EF6D1A3494E
+:1050C000A34806F048F80098002810D1012F0ED010
+:1050D00000909B4F9F4EB878072871D20100794409
+:1050E000097949188F446DFE056C6C6C280001200D
+:1050F000EEE76878002803D0FBF795F9FBF73EFD53
+:105100008F48FBF7ABF9002801D17F203870FBF7FF
+:1051100093F9009800280AD02079012801D00228AC
+:1051200005D1FBF76FF88748FFF72FFD37E2FBF754
+:1051300069F8FFF76DFD34E26878002803D0FBF7CB
+:1051400072F9FBF71BFD7E48FBF788F9002801D1B7
+:105150007F203870FBF770F90098002879D020790B
+:10516000022803D001287AD047E221E27548FFF7F0
+:105170000CFD012002F0C2FB00286ED07649714878
+:10518000FEF710FC7448FBF7FEF8607F00280ED095
+:105190006848019902898A824289CA828089088383
+:1051A00031466D48FEF7DAFB00206077A0770121D9
+:1051B0000846FBF763F9FBF703F90520E870F0E117
+:1051C0005BE16878002803D0FBF72DF9FBF7D6FCEC
+:1051D0005B48FBF743F9002801D17F203870FBF7CB
+:1051E0002BF90098002834D02079022808D0012813
+:1051F00035D0032837D05549584805F0ACFFD0E1E9
+:105200005048FFF7C2FC012002F078FB002824D0B0
+:1052100051494C48FEF7C6FB4F48FBF7B4F8607F96
+:1052200000280ED04348019902898A824289CA82A5
+:105230008089088331464848FEF790FB002060775C
+:10524000A07701210846FBF719F9FBF7B9F805200B
+:1052500001E10EE103E0BFE1ADE1B3E022E1394855
+:10526000FFF793FC9BE137482168C2780B7F9A4295
+:105270001DD102794B7F9A4219D142798B7F9A4294
+:1052800015D18279CB7F9A4211D10A462032C37957
+:105290001778BB420BD1037A5278934207D100783A
+:1052A000CA7E4006C00F904201D1012000E00020DC
+:1052B0006279012A30D0002800D138E7022002F0BC
+:1052C0001DFB00287ED0012002F088FB22491D48EA
+:1052D000FEF768FB2068018B1F48FEF7F9FB20688A
+:1052E000817D00E03CE01C48FEF7F6FB1A48FBF726
+:1052F0004AF8607F002866D00E48019902898A82A8
+:105300004289CA828089088331461348FEF726FB0A
+:1053100000206077A0779BE00028CFD109481C319E
+:10532000FEF721FB0748FEF732FB2168C876C5E788
+:105330004FB40100341F00203C1F0020541F0020E8
+:10534000D00000206C1F0020141F0020004F01001F
+:10535000D4040000281F0020941F0020CC0500006A
+:105360006878002803D0FBF75EF8FBF707FCF948E4
+:10537000FBF774F8002801D17F203870FBF75CF848
+:105380000098002875D0FAF733FE002871D02079F4
+:105390000328F14804D0FFF7F8FBFAF733FFFEE0EB
+:1053A0002168C2780B7F9A4220D102794B7F9A42C2
+:1053B0001CD142798B7F9A4218D18279CB7F9A4255
+:1053C00014D101E056E043E00A462032C379177851
+:1053D000BB420BD1037A5278934207D10078CA7E40
+:1053E0004006C00F904201D1012000E00020627908
+:1053F000012A32D0002800D199E6022002F07EFA7C
+:10540000002837D0012002F0E9FAD449D248FEF74B
+:10541000C9FA2068018BD148FEF75AFB2068817DCC
+:10542000CE48FEF759FBCD48FAF7ADFF607F002864
+:105430000ED0CB4901980A8982824A89C282898921
+:1054400001833146C548FEF789FA00206077A077CE
+:105450000120E0770620E870A3E00028CDD1BE4807
+:105460001C31FEF780FABC48FEF791FA2168C87635
+:10547000C3E7C2E000F0DAF993E06878002803D0CF
+:10548000FAF7D1FFFBF77AFBB248FAF7E7FF0028FB
+:1054900001D17F203870FAF7CFFFFAF7B3FEFFF79C
+:1054A000B7FB7EE0AC48FEF755FAB070AA48AB49AE
+:1054B000C3784A7A93421CD103798A7A934218D1ED
+:1054C0004379CA7A934214D183790A7B934210D1EB
+:1054D000C3794A7B93420CD1037A8A7B934208D1E9
+:1054E000007809784006C00FC909884201D101241B
+:1054F00000E00024FAF786FEB07804283ED1002CA4
+:105500003CD09448FAF7AAFF002801D17F203070E0
+:10551000FAF792FF287B002802D00020FFF7A5FBB6
+:105520000120904C28738C4F607A002837D10420DA
+:10553000E0723846FEF72BFA002801D0012800D18E
+:10554000207389493846FEF70EFA88493846FEF737
+:1055500087FAE0741F2801D91F20E0743078844F47
+:105560007F2804D1FF208349543005F0F4FD3078C2
+:1055700038707F2030700120607210E07548FAF7B3
+:105580006DFF002801D17F203070FAF755FF287B8E
+:10559000002802D10120FFF768FB00202873FFF7E5
+:1055A00037FBE87802283DD0E87804282DD127E0A1
+:1055B0007049714821E66878002803D0FAF733FF74
+:1055C000FBF7DCFA6348FAF749FF002801D17F2096
+:1055D0003070FAF731FF10E05E48FAF73FFF00281D
+:1055E00001D17F203070FAF727FF287B002802D1F5
+:1055F0000120FFF73AFB00202873FAF703FECEE7FD
+:1056000037205C49400105F0A6FD2879002809D023
+:1056100001280ED0022807D0032810D0554957483A
+:1056200005F099FD03B0F0BDE878032807D003B07A
+:10563000F0BDE878062802D0E8780528F7D10120E7
+:10564000FAF7D2FF03B0F0BD70B54D4CE0780728F3
+:105650005FD201007944097949188F445A5A5A5A3D
+:105660005A030B003C48FAF78EFEFAF7EEFE0420D0
+:10567000E07053E0FAF7C3FEFAF7B6FEFAF7C2FDA0
+:10568000FAF764FE012626730220E070FAF776FE30
+:105690003C4D2878002803D036493B4805F05BFD97
+:1056A0000020A8702E4800684188A980C17EE97159
+:1056B000818B2981C18B6981018CA9818188E982D3
+:1056C000C188298300896883607928772F48304909
+:1056D000807EA8732F4805F03AFE6078002803D03A
+:1056E000FBF76DFA012808D0687F40084000687712
+:1056F0002E70022002F072F910E0687F3043687764
+:10570000FBF776FA697F4000C907C90F0143697743
+:10571000EEE775201749000105F01DFDE07802282D
+:1057200016D0E078032806D0E078042803D0114989
+:10573000194805F010FD2079002809D0012807D06C
+:1057400002282DD003282BD00A49144805F003FD68
+:1057500070BD0000D00000206C1F0020941F0020AE
+:10576000341F0020F41E0020011F0020081F00200D
+:10577000271F0020004F01009E060000F5060000D4
+:10578000541F0020B41E002029070000141F002011
+:10579000281F0020C31E00205607000062070000DB
+:1057A0000120FAF721FF70BD10B55C4CE0780528A8
+:1057B00020D201007944097949188F441B1B1B1919
+:1057C00002005748FAF74AFE002802D154497F20C8
+:1057D0000870FAF731FE207B002802D10120FFF784
+:1057E00044FA00202073FAF70DFDFFF711FA01E0EB
+:1057F00000F01CF8E078022813D0E078032803D0EA
+:105800004849494805F0A7FC2079002809D001281B
+:1058100007D0022806D0032804D04249434805F0A7
+:105820009AFC10BD0120FAF7DFFE10BD10B5FAF7A3
+:10583000E6FDFAF7D9FDFAF7E5FCFAF787FD374CF4
+:105840006078002805D0FAF7EEFDFBF797F9002005
+:105850006070012020730220E070FAF78FFD0020B5
+:1058600002F0BCF810BD70B5314C054626466036D6
+:105870007434032943D0052940D1FEF741F80521AE
+:105880002846FEF742F8B17E2846FEF778F8214612
+:105890002846FEF763F8274C284621680F31FEF7AB
+:1058A000FBF8216828461331FEF7FFF82068817D58
+:1058B0002846FEF711F92068018B2846FEF708F903
+:1058C000206881882846FEF7F7F82068C1882846B6
+:1058D000FEF7F6F8206801892846FEF7F5F82168FA
+:1058E00028460A31FEF70BF92068817E2846FEF72C
+:1058F000F5F80A4841792846FEF7F9F870BDFDF73A
+:10590000FFFF03212846FEF700F8B17E2846FEF788
+:1059100036F821462846FEF721F870BD541F0020B6
+:10592000D0000020004F010099070000A5070000EB
+:10593000B41E0020341F0020F8B5FEF7FBFE04461D
+:10594000FEF7BFFFF74E0546F0682030407B002889
+:1059500026D0012867D0022869D0032871D0FF2003
+:10596000F1A1793005F0F7FB3069F7220178114099
+:105970000170F2682032937BDB071B0F1943FB2376
+:1059800019400170D37BDB075B0F19430170577B14
+:10599000EF23022F60D0012F63D0032F65D06AE080
+:1059A000E548FEF76DFF002827D030690090F168C8
+:1059B000088DC9884018801D87B20098FEF7D5F978
+:1059C000012805D00098FEF7D0F9002808D00FE094
+:1059D000F06839468030C7850098FEF733FA07E053
+:1059E000F06839468030406A87800098FEF7E7F912
+:1059F000F168032020314873B6E7CF48FEF72AFE4E
+:105A0000002804D0F0685321095C002907D0CA4857
+:105A1000FEF7DDFEF168012020314873A4E7022182
+:105A200020304173A0E7C448FEF7D1FE9CE7C2488E
+:105A3000FEF710FE002897D1FF20BBA16B3008E0D5
+:105A4000FFE7BD48FEF71CFF00288DD1FF20B6A15F
+:105A5000733005F080FB87E7012C08D8002D06D0B5
+:105A600009E06D1E2C4302D105E0002C03D0194043
+:105A70001023194300E019400170D17D002915D091
+:105A8000517B012912D0AD48FAF77DFCAC480121C9
+:105A90000176F268116E526E42610161A749326966
+:105AA000FAF7D7FF0020FAF7E3FF03E0FAF76BFC01
+:105AB000FBF701F801210846FAF7E0FC03203070FB
+:105AC000F8BD08282FD203007B441B79DB189F44C4
+:105AD00003060B0E11152528002926D023E00229E4
+:105AE00023D0032921D01EE007291ED01BE008295E
+:105AF0001BD018E00A390B2917D914E00D2914D04E
+:105B00000C2912D0002A04D00D290CD315290CD948
+:105B100009E0112907D3152907D904E0092904D080
+:105B200001E0012901D0002070470120704730B505
+:105B3000054683B08048FEF771FE002803D17AA1A4
+:105B4000804805F008FB774C2069FEF74DF80321EB
+:105B50002069FEF76AF82069EF2201781140017090
+:105B60002946FEF7CBF80D2D76D22800784400792F
+:105B7000001887441F1606448080840E7280848437
+:105B800060006848C16800698031497FFEF763F9A9
+:105B900075E06448C16800698031497AFEF7CCF944
+:105BA0006DE06048C16800698031896A491CFEF770
+:105BB0003DF964E05B4CE0688030406A817920699F
+:105BC000FEF7F9F8E0688030406A01892069FEF745
+:105BD000E9F8E0688030406A41892069FEF7C7F83B
+:105BE000E0688030406A81892069FEF7C9F8E06882
+:105BF0008030406AC1892069FEF7CBF83FE0494C0C
+:105C0000E0688030416A2069091DFEF728F9E068E4
+:105C10008030416A20690C31FEF72DF9E068803050
+:105C2000416A20691E31FEF730F9E1682069803150
+:105C3000FEF738F923E03B4CA06901782069FEF7B4
+:105C400061F9A06981882069FEF75EF9A069418841
+:105C50002069FEF75DF912E00DE000200090694632
+:105C60000190087801210843694608702D480069B1
+:105C7000FEF764F903E02CA1334805F06CFAFEF757
+:105C8000DEFD002803D128A1304805F064FA0C2D70
+:105C90000ED0072D0ED0012D0AD0002D08D0022DD8
+:105CA00006D020480021C068403041810121817325
+:105CB00003B030BD1B480021C0684030018203B0F2
+:105CC00030BDF0B5174C8DB02079C0077ED060791B
+:105CD00000287BD16069C0780E2878D20100794411
+:105CE000097949188F44737306733D5DE25C73FD57
+:105CF0007334FCA5E06854210A5C2030417D01200A
+:105D0000FFF7DFFE00284BD16069FEF7A6F8E168D7
+:105D10009E22505402223520425400204031887483
+:105D20008873EFE1D80000207372635C6C6C5F6D68
+:105D300061737465722E6300E8000020E21F00208A
+:105D40000820002083060000C7060000CD060000E2
+:105D5000E0682030C17C0A297ED10021C1750D2167
+:105D60001DE0E0683321095C0E2975D1A421095892
+:105D700040884988814203D0FAA1FE4805F0EBF93A
+:105D8000E0688030416A60692631FEF7A2F8E16878
+:105D900060698431FEF7ADF8E06811212030C174EC
+:105DA000B0E1E1683320405C112855D180318C4648
+:105DB0004B6AF14810260022082168440E33B51AB8
+:105DC000ED18203DEF7F4770AD7F01E0A2E17AE161
+:105DD0008570801C491E921C0029F0D161464B6AD7
+:105DE00003A810260022082103301E33B51AED182F
+:105DF000203DEF7F4770AD7F8570801C491E921C4F
+:105E00000029F3D16846FCF746FA08AD8DCDE1686C
+:105E100000260E664E660D4670318DC10126203576
+:105E2000EE75D64E8DC6D64805F09EFA1320E8745E
+:105E300068E1E0683321095C112901D00E293AD1CB
+:105E40004030007D002836D16069FEF773F8E168C4
+:105E50000B460A46803300E02DE0187200254031E1
+:105E6000CD748D73586A51884088884203D0BDA193
+:105E7000C44805F070F9E06801468030426A157048
+:105E8000826B1378002B03D0D920B6A1800033E0B9
+:105E90004B88D380836B027A1A71826B1572836B85
+:105EA0000B221A70806B4988418008E1E068332139
+:105EB000095C152902D00220607123E1014600250A
+:105EC0004031CD748D73A42109584088498881429E
+:105ED00003D0A4A1AC4805F03EF9E068014601E01A
+:105EE0002CE094E080314A6A15708A6B1378002B9D
+:105EF00005D071209BA1C00005F02DF9DFE003461D
+:105F000040331E7D002E0BD01D754388D3808A6BD5
+:105F100015718B6B0C221A70896B40884880CEE01B
+:105F20004388D3808A6B15718B6B01221A728B6B3D
+:105F30000B221A70896B40884880C0E0E0685421C9
+:105F40000A5C2030017D0020FFF7BBFD00280DD149
+:105F5000E06854210A5C2030C17C0720FFF7B1FDC6
+:105F6000002803D16079012108436071607900281D
+:105F70004CD1E0684030807D800715D46069FDF722
+:105F8000CBFFE1684031C8756069FDF7C7FFE16884
+:105F9000403108836069FDF7C6FFE16802224031A5
+:105FA0004883887D10438875E068014640318A7DCA
+:105FB000D20716D10A7D2030017D0020FFF781FD38
+:105FC000002803D167A1714805F0C5F8E0680121F8
+:105FD000342211540623A02213544030817400212E
+:105FE0000182E06801462031CA7C012A03D10022E7
+:105FF000CA744E210A54A421095840884A88824212
+:1060000004D1087806287DD1002008707AE0E06885
+:1060100054210A5C2030C17C0620FFF752FD002885
+:1060200003D160790121084360716079002869D14A
+:1060300069466069FDF793FF68460078C107C90F9C
+:106040006846017004D0E06801214030017703E028
+:10605000E068002140300177E06800254E210D54B2
+:10606000A421095840884988814203D03DA148486D
+:1060700005F071F8E06802468030416A0D70816B6E
+:106080000B78002B04D037A1424805F064F816E0E5
+:106090005388CB80816B6B460D71816B1B880B81A4
+:1060A0006B465B884B816B469B888B816B46DB889C
+:1060B000CB81836B06211970806B51884180E06829
+:1060C0002030C5741EE0E06854210A5C2030017D58
+:1060D0000020FFF7F6FC002803D160790121084376
+:1060E0006071607900280DD16069FDF73EFEE168BE
+:1060F0008922505405223420425400204031088225
+:1061000001208874E2680023916ED06E491C5841CA
+:106110009166D0660DB0F0BDF8B5FAF770F9FAF7F0
+:1061200063F9FAF76FF8FAF711F9FAF7C4FCFAF71E
+:1061300025F9194CE06820300079012801D1FAF7DF
+:106140007BF9E068012502462032917D002908D1C3
+:10615000E178CB0701D1890703D59575012101F0BD
+:10616000F9FB1BE07372635C6C6C5F6D617374654B
+:10617000722E630021030000FFFFFFFF08200020B4
+:10618000212000205F03000083030000C303000000
+:10619000F1030000F6030000D8000020E07900269B
+:1061A00000284FD100F06DFDF848FEF737FB0028BE
+:1061B00048D06079002845D1E06854210A5C20303D
+:1061C000417D0120FFF77DFC00283BD1E0680246BD
+:1061D0008032117F002901D0022051E00346203394
+:1061E000D97C05292AD0E927FF000C292DD00D29BB
+:1061F00029D0132943D01B7D012B4BD0052B42D036
+:10620000526A1378002B61D0528843889A425DD13C
+:106210004030027D0020FFF754FC00287FD0E0686A
+:10622000A42109580978891E062978D20A007A44DF
+:106230001279921897443A3C7373658CD449D548C7
+:1062400004F089FFB6E00B201AE0F5F71AFF0C28DE
+:106250007DD3E06808218030406A1E30F5F712FFD8
+:10626000002806D0E06804218030F5F70BFF0028F5
+:1062700003D1C749384604F06EFF032000E0062032
+:10628000FFF755FC96E00720FFF751FCE06820304F
+:1062900006758FE00C20FFF74AFCE06801464030AD
+:1062A000827D2A43827520310E7583E000200BE049
+:1062B0002030C17D00290AD0007E002803D1B449D6
+:1062C000B54804F048FF0A20FFF731FC27E0F5F756
+:1062D000D8FE0C2823D3E06808218030406A1E30A5
+:1062E000F5F7D0FE002806D0E06804218030F5F7ED
+:1062F000C9FE002803D1A649384604F02CFF03202C
+:10630000E2E74030807D800709D10C20FFF70FFCC9
+:10631000E068403046818573817D294381759B48C3
+:10632000FEF77CFA002845D0E06854210A5C203052
+:10633000C17C0020FFF7C5FB00283BD0E168AC2002
+:10634000405C002836D0E0690078002802D031E0B7
+:106350000820B9E7088D0A282CD905220A31206ABD
+:1063600004F042FD002822D0E0688030816A08787D
+:1063700000280CD00522491C206A04F035FD0028B5
+:1063800018D1E0688030806A0078002806D1E06883
+:10639000216A8030806A401C04F0CEFFE0688030C3
+:1063A000806A0178491C01700120FFF7C0FBE0689A
+:1063B000A0300673E078C007E06802D040308680E5
+:1063C00003E040308188491C8180E0689C21095CA1
+:1063D000002908D154210A5C2030417D0120FFF7BB
+:1063E00070FB002804D0E06840300189491C01811D
+:1063F000E0793D21002804D0E0684030817045708C
+:106400005AE0207A02280AD001280AD060790028B0
+:106410001AD0420701D4C2060AD51E21ECE7162184
+:10642000EAE7E0689E21095C40308170457043E0F6
+:106430000207E1D4C10705D1800703D45449574866
+:1064400004F089FE2A21D7E7E06802464032917BBA
+:10645000002905D05389591C518191898B4213D24F
+:10646000917C002905D0118A4B1C13829389994293
+:106470000AD21789D3889F4203D39C21095C002943
+:1064800002D191898F4203D322209070557013E07E
+:106490003621095C0029918805D0994209D308204A
+:1064A0009070557008E0062903D33E209070557017
+:1064B00002E05178002908D0E06801462031CE740E
+:1064C0000E758E752570022101E02570002101F006
+:1064D00041FAF8BDF8B50C4616466946FDF710F9C5
+:1064E000002801D00020F8BD009800250246803029
+:1064F000816B0B78072B1CD0A71C0C2B29D00B2BE6
+:1065000034D0062B4CD01146A031087C0028EAD0AC
+:10651000657012202070087C002808D0A2320D740B
+:10652000108A6080508AA080087C0028F7D1012062
+:10653000F8BD002EFBD1657007212170816B0A2206
+:10654000A01C091D04F07DFC00988030806B057054
+:10655000EDE7002EEBD165700C212170816B8A88EC
+:106560006280C988A180806B0570E0E7002EDED1D3
+:1065700065700B212170816B8A883A80CA887A8085
+:106580000989B980806B0570D1E70000E800002020
+:1065900064610100BE0500007905000032020000C0
+:1065A000002EC4D1657006212170816B8A883A80E3
+:1065B000CA887A800A89BA804A89FA808A893A81A7
+:1065C000CA897A81806B0570B1E7FE48007801289E
+:1065D00001D00C2070470020704770B5F94C05467B
+:1065E0002078002803D0F849F84804F0B4FD0020D2
+:1065F000A5616072012020702078012803D0F24943
+:10660000F34804F0A8FD70BDF8B5EE4C21780129DF
+:1066100001D00C20F8BDE0608030807AFEF707F8EA
+:1066200000283AD0E0688030807AFEF757F90028D9
+:1066300033D0E0688030807AFEF7CCF800282CD088
+:10664000E0688030807AFEF708F9002825D0F9F755
+:106650008AFE0026E6710120F9F749FCE068014650
+:1066600040318A7B002A03D04A898B899A4211D211
+:106670008A7C002A03D00A8A8B899A420AD20B8923
+:10668000CA88934206D236231B5C8988002B06D029
+:10669000914206D30120A0703BE01220F8BD0629EC
+:1066A000F8D2A6701330F9F7F0FDE0680F30F9F773
+:1066B0002EFD0320F9F754FEE06805462030017EE8
+:1066C000002902D1C07D002809D0294670318EC929
+:1066D000C0488EC02946C048803104F045FE98204D
+:1066E000405BA91C401C82B228462830FDF772FD91
+:1066F000002803D0B449B94804F02DFDE0684030CB
+:106700000078F9F716FDF9F727FE01210020F9F7C7
+:106710002BFDE67026716671A6712672022020702C
+:10672000E06880300683F9F729FE0020F8BD10B537
+:10673000F9F719FEA34C2078022803D0F9F71EFEC2
+:106740000C2010BDA078002802D0FFF7E5FC17E070
+:10675000F9F736FEFFF7F0F8E068203000790128FD
+:1067600001D1F9F772FE607A002809D0012809D01A
+:10677000022805D0032805D09349994804F0EBFC82
+:10678000002010BDECF744FCFAE770B505468030F8
+:10679000018B2C46491C01834034A188491CA180EF
+:1067A000A17B002902D06189491C6181A17C00295B
+:1067B00002D0218A491C2182007F002807D1352080
+:1067C000415D227D0120FFF77CF9002802D020895D
+:1067D000401C2081284600F0EBF9002070BD79496B
+:1067E00048727047774A1162D0617047F8B5754CAE
+:1067F0002078032803D074497A4804F0ACFCE1689F
+:1068000004272031887A0025002803D08D72207952
+:1068100038432071206901260278D2439207002A6A
+:106820001FD1CA7A002A1CD1CE72217902221143CB
+:106830002171FDF79AFA062802D00B2811D10AE03F
+:10684000E06801462030C27C132A0AD100228A6601
+:10685000CA66067605E0E0682030C17C0D2900D1CB
+:1068600005762079400704D5E0682030407D022875
+:1068700005D06079002802D1A079002802D0FFF766
+:106880004BFC2AE05848FEF73CF8002801D0657020
+:1068900002E0667055486061E0682030007E0028A4
+:1068A00011D05348F9F76FFD4A480576E268916EBA
+:1068B000D26E426101614E4A6169FAF7CAF801205D
+:1068C000FAF7D6F804E06069F9F75DFDFAF7F3F836
+:1068D00002210020F9F7D2FD2770207801280CD082
+:1068E000607A002809D0012807D0022806D00328A2
+:1068F00004D035493F4804F02EFCF8BD0120F9F7DB
+:1069000073FEF8BDF8B52F4C05462078042803D057
+:106910002D49394804F01FFC002D71D0FAF7E3F837
+:106920000125002812D1E0682030017E00290DD019
+:1069300061694A78D20609D00978C07B0907C90F76
+:10694000814203D1E571FFF7E7FBACE0E06820305E
+:106950000079012811D1F9F76FFDE168881C283111
+:10696000FDF728FD002808D0E068B22142880A52CD
+:106970003121095CA030017505746069002600783A
+:106980004007C10FE0682030827B914255D0407BA8
+:10699000002852D002280FD1FDF780FE002803D135
+:1069A0000949164804F0D7FBE2680023106E516EC7
+:1069B000401C594151661066E06820304673C17A28
+:1069C00001291EE0D800002064610100EF070000EB
+:1069D000FB07000008200020212000203A080000CA
+:1069E0007A080000AF080000EC000020C01F002063
+:1069F000E21F0020F3080000FB080000FD05000076
+:106A0000B1E014D1C6722079082108432071FDF746
+:106A100046FF002803D1FE49FE4804F09CFBE268D3
+:106A20000023106E516E401C594151661066E0689B
+:106A30002030817B012948D08573606901788C46BC
+:106A40000907CF0FE1680A462031CB7B9F420CD16A
+:106A50006746BF07BF0F012F4FD0022F4DD0032F26
+:106A600035D06079042108436071E0782843E070F4
+:106A700020690078C00604D460690078C00600D49C
+:106A800061E720790028FBD160780028F8D100F078
+:106A900056FF0028F4D060790028F1D1A0790028B1
+:106AA000EED1FEF749FF207801280DD0607A00284A
+:106AB0000AD001285CD0022806D0032858D095209F
+:106AC000D349000104F047FBF8BD8673B5E7FDF735
+:106AD000D3F800280CD0E068203085722179294352
+:106AE0002171C17B012901D1C673BEE7C573BCE723
+:106AF0006079102108436071B7E74078C7062CD051
+:106B00006378002BB1D1C006C00E1B28F0D84032EC
+:106B1000127DC97C0520FEF7D4FF002804D0A0799F
+:106B200008210843A071A0E7E07804210843E07041
+:106B3000FDF70EFF002803D1B549B74804F00BFB61
+:106B4000E0680023816EC26E491C5A41C2668166AC
+:106B50002030C17B0129C9D1C6E7012B01D0CD73FB
+:106B600083E7CE7381E7E07802210843E070EAE62C
+:106B70000120F9F739FDF8BD10B5A84800780428C0
+:106B800003D0A349A64804F0E6FAFFF7C5FA10BD02
+:106B900036210A5C40308188091D002A04D0C08853
+:106BA000814203D3012070470629FBD200207047A1
+:106BB000F8B5054606462036F07C2C460027803482
+:106BC000072820D1288DE18D401C884258D1A16A28
+:106BD00028460A30491C04F0AFFB01220221284656
+:106BE000FDF7ABFAF77401215E204155A06A0078E9
+:106BF000002804D1A1208649800004F0ACFAA16AE3
+:106C00000878401E0870F07C082839D1616A288D08
+:106C10008988401C884233D1A06B0178002904D0B8
+:106C20007B49804804F097FA15E06988C180606A62
+:106C3000A16B40890881606AA16B80894881606A84
+:106C4000A16BC0898881A06B0771A16B07200870B8
+:106C5000A16B68884880012211462846FDF76DFA2D
+:106C60000321284600F076FE606A698840888842E1
+:106C700003D067496C4804F06EFA606A0770F774D5
+:106C8000F8BDF8B5654C6079002875D120790126EA
+:106C900040070025002815DAE0682030C07C022873
+:106CA00002D0052807D102E05949604801E058495F
+:106CB0005F4804F050FAE0682030417D022901D19C
+:106CC00026724575207908278007002840DA607908
+:106CD00000283DD12069C0780D2875D20100794483
+:106CE000097949188F4449350681FCFCBB1722FC01
+:106CF0005B71CA00E06854210A5C2030417D0120AC
+:106D0000FEF7DFFE002823D1E0680321352211546D
+:106D100040308573E2E0E06854210A5C2030017D58
+:106D20000020FEF7CEFE002870D1DDE0E06854219F
+:106D30000A5C2030C17C0020FEF7C3FE002803D18E
+:106D400033493C4804F007FAE06809212030C17457
+:106D5000CAE0E06854210A5C2030C17C0020FEF7C4
+:106D6000B0FE002803D12A49334804F0F4F9E06862
+:106D700007212030C174B7E0FBE0E06854210A5CD1
+:106D80002030C17C0020FEF79CFE002803D1204962
+:106D90002A4804F0E0F9E0682030C774A4E0E06815
+:106DA00054210A5C2030C17C0020FEF78AFE0028B6
+:106DB00003D11749224804F0CEF9E06853210E545C
+:106DC0000A212030C1748FE08AE0E0682030C07C66
+:106DD0000D2803D00E491B4804F0BDF9E06854218A
+:106DE0000E540C212030C1747EE0E06854210A5C0E
+:106DF0002030C17C0020FEF764FE002828D1E06826
+:106E00004030007D002823D101491DE064E00000EE
+:106E1000646101000E06000057060000D800002043
+:106E20005809000091020000A50200006A04000059
+:106E30006E040000AC040000B1040000B6040000C1
+:106E4000BB040000C20400009920C00004F083F9D4
+:106E5000E06853210E540E212030C17444E0E068F4
+:106E60002030C07C132804D04D204349000104F099
+:106E700072F9E06815212030C17435E0E068A42182
+:106E8000095843884A889A421CD10978062919D1A1
+:106E900054210A5C2030C17C0020FEF712FE00283D
+:106EA00003D13549354804F056F9E06801464031D0
+:106EB0008A7D920702D42030C67403E08D7380303F
+:106EC000406A0570E06854210A5C2030017D002092
+:106ED000FEF7F7FD002807D0E0684030857403E036
+:106EE0002549274804F037F9207900070AD5607949
+:106EF000002807D1E0682030417D032902D102211A
+:106F000021724575FEF7DDFEA07900072ED5E068F9
+:106F100054210A5C2030C17C0520FEF7D2FD0028F8
+:106F20000BD0607938436071E0688030816B0878FD
+:106F30000B2800D10020087018E0E07804210843F5
+:106F4000E070FDF705FD002803D10B490D4804F062
+:106F500002F9E0680023816EC26E491C5A41C26684
+:106F600081662030C17B012904D0C673E068FFF739
+:106F70001FFEF8BDC573F9E764610100DC04000081
+:106F8000F6040000EA020000F7B582B00646039856
+:106F900017468188FE48FE4A41430398039D008BB3
+:106FA00000245043009080352A7C002A0CD0F948F8
+:106FB000012A40683CD0022A1FD0032A38D0F6A10B
+:106FC000F94804F0C8F84BE0002F04D17D20F2A16D
+:106FD000C00004F0C0F8EF4C6068002803D1EEA1B7
+:106FE000F24804F0B8F86068A168001D0918F04A7A
+:106FF000009880180C18012018E0791E084303D16E
+:10700000E5A1EC4804F0A7F8EB48016800980C18DB
+:10701000002F0AD0DF484168E8480818A04204D988
+:107020008120DDA1C00004F096F80320287415E04B
+:107030000C46002F12D0D74F002806D178780028B0
+:1070400003D0D5A1DE4804F086F8DC48796808183A
+:10705000A04203D9D0A1DB4804F07DF8002C03D175
+:10706000CDA1D94804F077F821466869F5F7D9FF32
+:10707000686100203070012434716869B060039841
+:10708000FFF786FD002801D0747104E0287C0128F8
+:1070900005D003207071CD48F06005B0F0BD02202E
+:1070A000F8E7F0B5054687B00F46012000F01BFD5C
+:1070B000C4B20B2000F017FDC0B2844204D0FF2000
+:1070C000B5A14D3004F047F8012000F00CFDC4B22A
+:1070D000182000F008FDC0B2844204D0FF20AEA109
+:1070E0004E3004F038F83846B94F6C1E6900CD199F
+:1070F0000026403D09287DD20100794409794918CC
+:107100008F44044150504CE9E9E9A0000B2C04DB0A
+:10711000FF20B0A1213004F01EF8E88F6946FCF78B
+:10712000EFFA002804D0FF209BA1563004F013F89A
+:107130000B2C04DBFF20A7A1213004F00CF80099F0
+:10714000E88F4988884204D0FF2093A1583004F08A
+:1071500002F800988030007C002804D1FF208EA126
+:10716000593003F0F8FF8B484660467086600098FF
+:10717000FFF74AFA002804D0FF2087A1603003F00F
+:10718000EAFF07B0F0BDFFF7D2FA0028F9D0FF20E0
+:1071900081A1663003F0DFFF07B0F0BDF9F727FAF1
+:1071A00007B0F0BD0420C04300F09DFCC6B219201A
+:1071B00000F099FCC0B2864204D0FF2076A1723064
+:1071C00003F0C9FF0B2C04DBFF2082A1213003F068
+:1071D000C2FFE88F6946FCF793FA002804D0FF202D
+:1071E0006DA1763003F0B7FF0B2C06DBFF2079A1F1
+:1071F000213000E06FE003F0AEFF0099E88F49888E
+:10720000884204D0FF2064A1783003F0A4FF0098E6
+:10721000FFF7BBFA002804D0FF205FA17B3003F00A
+:107220009AFF009C0022214602A8FFF7ADFE8034A1
+:10723000A07E02A9F6F7DAF80099088D401C0885AF
+:1072400007B0F0BD0B2C04DBFF2062A1213003F05E
+:1072500082FFE88F6946FCF753FA002804D0FF202C
+:107260004DA1863003F077FF0B2C04DBFF2059A1E2
+:10727000213003F070FF0099E88F4988884204D0DC
+:10728000FF2045A1883003F066FF00988030007C25
+:10729000042804D0FF2040A1893003F05CFF009C4B
+:1072A00080342674A57E4F4F681E0B2804DBFF2018
+:1072B00048A1273003F04FFF4548690008184038BF
+:1072C000C787A07EF5F700FC4748A6760078EBF765
+:1072D0001BF807B0F0BDFF202FA193304FE770B52A
+:1072E000424C0646E08B0025401C80B2E0832378A8
+:1072F0000A46002B09D021464968042B0BD0052BE8
+:1073000017D03D2024A1000102E0ED2022A1800041
+:1073100003F021FF14E00A2801D3022000E003203B
+:107320007071002A0BD00320226900F0F5FB05469E
+:1073300006E002207071002A01D02D4D00E00D46BC
+:1073400029462069F5F76DFE002120613170012189
+:107350003171B060A068FF303130F06070BDF0B5C1
+:10736000074685B00E46012000F0BDFBC4B20B20DD
+:1073700000F0B9FBC0B2844204D0FF2006A19E30C9
+:1073800003F0E9FE012000F0AEFBC4B2182031E0AA
+:10739000E2040000302000207372635C6C6C5F6C50
+:1073A0006D2E6D302E6300001C040000E903000008
+:1073B0005504000003040000000100205F040000E9
+:1073C00016040000170400001F040000F60400006B
+:1073D0005C2000207372635C6C6C5F6C6D2E6D3092
+:1073E0002E630000FFFF0000FC0000203C20002076
+:1073F000B80B000000F077FBC0B2844204D0FF203D
+:10740000FD499F3003F0A7FE00250120FB4C092E0B
+:1074100070D231007944097949188F44041A3737FA
+:10742000336B6B18520060732073607800280ED1A4
+:10743000F348456085602573A068C338FDF791FC6B
+:10744000002804D0FF20EC49B33003F084FE05B0DF
+:10745000F0BD6178002909D0207B002801D1FDF71B
+:10746000C2FD6573F5F796FA05B0F0BDA073FDF7A0
+:1074700000FD0028F8D0FF20DF49C73003F06BFE85
+:1074800005B0F0BDF9F7B3F805B0F0BD0420C04376
+:1074900000F029FBC4B2192000F025FBC0B28442E1
+:1074A00004D0FF20D449D53003F055FE012200213D
+:1074B0006846FFF714FF69463846F5F797FF05B0B1
+:1074C000F0BD2078052804D0FF20CB49E13003F03F
+:1074D00042FE207F002804D1FF20C749E23003F09C
+:1074E0003AFE25772570207DF5F7EEFA257505B073
+:1074F000F0BDFFE7FF20C049ED30A6E7F0B5BF4C77
+:1075000087B020780026042805D02078052802D0EE
+:107510000C2007B0F0BD01276770607B00250028B4
+:1075200027D072B6607B002808D0A07B002805D049
+:10753000FDF759FD6573A573F5F72CFA62B6207D4A
+:10754000F6F782FD002827D0207F002808D0257775
+:107550002078052803D0A849AA4803F0FCFD0C2692
+:1075600065702570207DF5F7AFFA2575304607B0B8
+:10757000F0BD207D00900320694608734873F5F73D
+:10758000BEFA04900020C043694605900F7202A91C
+:107590000098F5F72BFFD2E720BFD0E7F0B597486A
+:1075A00083B00078002801D0FFF7A8FF944F012096
+:1075B0003870FF26944D2D36002405E00B2C03D3A4
+:1075C0009249304603F0C7FD204601A9FCF798F820
+:1075D000002838D101988030007C002833D00B2C53
+:1075E00003D38A49304603F0B6FD2046AC422ED084
+:1075F0006946FCF785F8002803D08449844803F0E5
+:10760000AAFD00988030807EF6F71EFD002822D06B
+:107610000098002180300174847E0C2C04D3FF205C
+:107620007A49273003F097FD7A48610008184038FE
+:10763000C58700988030807EF5F746FA00990020D3
+:1076400080318876B8E7641CE4B2032CB6D30020FE
+:10765000387003B0F0BD20BFD3E710B500786E4C92
+:1076600000280FD001280CD068496C4803F073FD46
+:10767000A0686B49884203D364496A4803F06BFDF4
+:1076800010BD6948A060F3E710B55D4900220A709B
+:10769000614C207059480270427002770273427345
+:1076A0008273826102752030574B0380052143802D
+:1076B0008380001D491EFAD1100004D0002A04D096
+:1076C0005948A06005E0A26003E05049534803F028
+:1076D00042FDA0685249884203D34C49514803F007
+:1076E0003AFDFFF75BFF10BD70B5444C0E462178A4
+:1076F00084B01546002902D00C2004B070BDA061F2
+:107700008030007C002803D03B49484803F023FD2B
+:107710004748464345434748ED1C30186660A5601E
+:10772000854200D82846A0603549002088600521A0
+:10773000217060702077E0833F48F5F771F920757C
+:10774000002803D12C493D4803F005FDF5F7D7F992
+:107750002061002201216846FFF7C1FD207D6946B6
+:10776000F5F744FE002004B070BD08B50020C0430A
+:107770006946088021480078002801D0002008BD13
+:107780000846FBF7F5FF0028F9D0012008BD10B529
+:107790001A4C84B02278002A02D00C2004B010BD0C
+:1077A000234A51435043C91C224AA160606080189B
+:1077B000814200D80846A06000206070042121703A
+:1077C000E0831D48F5F72CF92075002803D10A49FC
+:1077D0001B4803F0C0FCF5F792F91A49F5F721FCB4
+:1077E0002061002201216846FFF779FD207D69466E
+:1077F000F5F7FCFD002027E0987301003C200020F5
+:107800003020002076020000FFFF0000D47301004A
+:10781000190300005C200020FC000020510500003E
+:107820006A1800005A050000C40900008B0200001D
+:1078300071020000B3FBFFFF5F73010097020000BD
+:10784000C6020000B80B000004B010BD10B5E14C3A
+:10785000A1690160FFF752FE0021A16110BD70B562
+:10786000DC4C84B02078052802D00C2004B070BD18
+:10787000A069002803D1D849D84803F06CFCA0695E
+:107880008030007C002803D0D349D54803F063FC46
+:10789000A0698030807E002803D0CF49D14803F012
+:1078A0005AFCD148F5F7BCF8A1699A225054054614
+:1078B0004E88401E0B2804DBFF20C749273003F009
+:1078C0004AFCCA49680040184038C687A069803021
+:1078D000807E002803D1C049C54803F03CFC01224A
+:1078E0006846A169FFF750FBA06969468030807E39
+:1078F000F5F77CFD0020A06104B070BD10B5BD4956
+:107900004C68983400280ED001280FD0022811D0DE
+:107910003520B949000103F01EFCAE488068A04242
+:107920000BD9012010BDFF347934F6E7B120800077
+:107930002418F2E7FF346134EFE7002010BDAD48B2
+:107940004178002902D10078002801D0002070473A
+:107950000120704770B504460422A84E803484B0DC
+:1079600000290DD0012923D0022907D0032921D0D5
+:10797000A149A34803F0EFFB04B070BD227410E0EE
+:1079800005469C4800780028F8D12946012268461F
+:10799000FFF7FAFAA07E6946F5F728FD288D401C0E
+:1079A0002885F4F7F7FF3078EAF7AEFC04B070BD35
+:1079B000032010E08188934A5143934A1160616A21
+:1079C0000A8902838A7982754A8982808A89C2807B
+:1079D000C98901810220207404B070BDF0B5874EC2
+:1079E0000146307800257B4C85B0002908D001295C
+:1079F00016D0022942D0032958D07F49834839E064
+:107A0000E583EAF781FC6078002849D1002211461D
+:107A10006846FFF764FC207D6946F5F7E7FC3FE028
+:107A2000744F20697968774B401879494218A069EA
+:107A300081884088594300F06FF8B1680546884254
+:107A400005D2A1696F4A88884243551903E06D4900
+:107A500003F060FAA1690883A06905218175008B94
+:107A600068494843281A6B49B860884204D32520E6
+:107A70005949400103F06FFB05B0F0BDE583EAF71B
+:107A800043FC01202077A0692169803041610574A1
+:107A9000FFF7E5FE002803D04F495F4803F05BFB8A
+:107AA000F4F778FF6573A57305B0F0BDEAF72CFC19
+:107AB00005B0F0BD704710B54E4A00290ED001291F
+:107AC00006D0022906D04C49544803F044FB10BDAF
+:107AD000401E03E05178491C5170001F506010BDDA
+:107AE0003C48007870478107C90E00280BDA000770
+:107AF000000F083880084A4A80008018C069C840D2
+:107B00000006800F70478008464A80008018006891
+:107B1000C8400006800F7047F7B582B00D46064694
+:107B2000414F002406E00B2C04D3FF202A492D30BE
+:107B300003F011FB204601A9FBF7E2FD00280ED15E
+:107B400001988030007C002809D00B2C04D3FF2042
+:107B500021492D3003F0FFFABC4204D006E0641C3A
+:107B6000E4B2032CDFD3002005B0F0BD6946204607
+:107B7000FBF7C6FD002803D017492C4803F0EBFAA9
+:107B8000A64204D1DD201449800003F0E4FA28481D
+:107B9000341B44430098803041690498F6F7C8F9D3
+:107BA000041908D5281B66422946401E03F0C0F977
+:107BB0006843841B05E02946204603F0B9F9684371
+:107BC000241AAC4203D904491A4803F0C4FA2046E7
+:107BD00005B0F0BD3C200020D4730100E702000096
+:107BE000E9020000EB020000A37001005C2000200D
+:107BF000EE0200003020002098730100FC000020FD
+:107C0000ED040000E204000000010020190500005E
+:107C10004E0600006A180000B3040000360500009C
+:107C200000ED00E000E400E0FFFF00007103000051
+:107C3000770800008903000070B5F84E0446B0795B
+:107C40000025012805D0F64E307A01280CD00020FE
+:107C500070BD002915D1657014202070F149A01C59
+:107C600003F082FBB5710CE000290AD16570132086
+:107C700020701C22EC49A01C03F0E3F80120A07145
+:107C80003572012070BDE648007A002802D0E7482E
+:107C9000808D7047E6487047F8B5E64801780029BE
+:107CA00002D00C263046F8BD0026E04D34462E7535
+:107CB0006E75EE752E76AE75DF496E734E73D84FC6
+:107CC0007F217E718170687E002804D0F8F7ABFBBD
+:107CD000F8F754FF6C763C72D848FBF711FED84891
+:107CE000FBF70EFEDEE770B5D24A00251570CC4ECC
+:107CF000D44B35711966D8651078002805D0FF205F
+:107D0000D1A17A3003F027FA70BDC84C257565758E
+:107D1000E5752576A575C8486573457375717F202F
+:107D20009070607E002804D0F8F77DFBF8F726FFFE
+:107D300065763572C148FBF7E3FDC148FBF7E0FD0E
+:107D400070BDBA48007D704710B5B849C87B897BC3
+:107D500042078307D20FDB0FC007D218C00F1018DD
+:107D60004000052911D20A007A44127992189744EA
+:107D7000090509020700B849085A10BDB74810BDE7
+:107D8000B74900E0B749085A10BDFF20AEA19A30AC
+:107D900003F0E1F9002010BDA448B349008A48432C
+:107DA00070479F488079002800D001207047F8B5BF
+:107DB00006469E4C407BE07330790027A073012873
+:107DC00025D0308820829648B37B83719D4DA7488B
+:107DD0002970114603F0BBFAB0796873F11DA4480D
+:107DE00003F0B5FA607B0126002800D06675924842
+:107DF000407B002800D0A675A07B05284DD201004D
+:107E00007944097949188F440409262B09002782EF
+:107E1000D9E700218948FBF778FD25E00121874853
+:107E2000FBF773FDE91D8548FBF7A4FD687B00287F
+:107E300007D001280AD0FF2083A1E83003F08BF996
+:107E400012E000217D48FBF7A6FD0DE001217B48F3
+:107E5000FBF7A1FD08E006217848FBF756FD03E09B
+:107E600002217648FBF751FDE7752776691C7348B8
+:107E7000FBF774FD29787148FBF781FD04217048F8
+:107E8000FBF743FD691C6E48FBF768FD29786C48D9
+:107E9000FBF775FD26750020F8BDFF206AA1F230C2
+:107EA000CCE770B5614C012525765D4A127A002A2F
+:107EB00001D03A2070BD634A13780022834205D175
+:107EC000E2756A4803F043FAE57500E02276002087
+:107ED00070BD70B50446554D0020A8752246654812
+:107EE00002F0AFFF544844730120A87570BD4C499F
+:107EF0000871704710B54D4C0022627560730246E0
+:107F00005D4802F09EFF0120607510BD4449487134
+:107F10007047F8B5474D287800282CD1434C207D78
+:107F2000002828D0F8F71FFA0026A674E6746E70B1
+:107F30003046F8F715FA0020F7F7D9FF4F48F8F761
+:107F4000E6F84F48F8F7A1F9F8F73AFAE07B01278D
+:107F5000C107002902D0A17CC9070ED0810712D524
+:107F6000A17C89070FD42620F8F7E3F8A07C022132
+:107F70000843A07413E00C20F8BD2520F8F7D9F8C9
+:107F8000A07C38430AE0400709D5A07C400706D40E
+:107F90002720F8F7CEF8A07C04210843A074F8F756
+:107FA000DBF901210020F8F7DFF80F210520F8F7B1
+:107FB00022F8244D2978681CF8F711F8A07B0128D5
+:107FC0000AD0042808D0607D002805D0627B2A49A9
+:107FD0001A48FBF7FAFC6675A07D002806D0164803
+:107FE0002449427B9830FBF722FDA675286E017864
+:107FF000002903D00178001DF8F734F8E86D017806
+:10800000002904D01F4A401CF8F797FD6776F8F75F
+:10801000B5F90020F8BD074948607047F4200020FA
+:10802000D4200020FB200020DE200020B4200020EF
+:10803000FFFF000008010020942000200421002000
+:108040002C210020742000207372635C6C6C5F61D3
+:1080500064762E630000000066B401009A89130064
+:108060006EB401005EB401007102000075200020B2
+:108070007B20002082200020A220002059B4010093
+:1080800056B4010057210020F8B50126FE4C0546E4
+:10809000002824D0E07B2146C207897C002A01D039
+:1080A000CA070BD082070FD58A070DD42620F8F710
+:1080B00040F8A07C02210843A07410E02520F8F7C6
+:1080C00038F8A07C3043F7E7400708D5480706D4C6
+:1080D0002720F8F72EF8A07C04210843A074E07C48
+:1080E00000280AD0A07B012804D14B20E7490001D9
+:1080F00003F031F800F0BDFAF8BD002D0CD00221DC
+:108100000020F8F731F8E2480079032801D001286F
+:1081100002D10220F8F768FAE07D002700280AD093
+:10812000DC4DDD48691CFBF719FC691CDB48FBF7DB
+:1081300015FCE7752776D848F8F725F9A07B0528C0
+:108140000CD201007944097949188F440202020BCC
+:10815000020001210846F8F791F903E0CB49D04825
+:1081600002F0F9FFE07BA17C884303D1A07B0128CA
+:1081700003D0E674CB480670F8BDA774FAE710B5D3
+:10818000F8F7F1F8C7480078002816D1BE48007DFE
+:10819000002812D00020FFF777FFBD4800790028A3
+:1081A00009D0012815D0022805D0032811D0B749DD
+:1081B000BD4802F0D0FF002010BDF8F720F9F8F715
+:1081C00013F9F8F71FF8F8F7C1F8F8F7D7F80C200B
+:1081D00010BDEAF71DFFEEE7B24901204870704775
+:1081E000F8B50024FAF7AAFE002822D0FF202D308F
+:1081F000F7F7B7FFAB4D2878A54F01281CD0022810
+:1082000001D0032831D0CF20A049800002F0A3FF85
+:10821000287800280CD03879002809D0012807D008
+:10822000022835D0032833D09849A04802F093FFA4
+:10823000F8BD00F01EFAF8BD934EB07B032814D0B1
+:10824000707E002803D0F8F788FCF8F7E4F8984827
+:10825000F8F799F8B07B012812D0042810D0B8792B
+:10826000012806D0032804D004E00120FFF70CFF0A
+:10827000CEE7102421460E2001430020F8F7FEF837
+:108280007879012801D1F8F7E0F802202870BFE7DB
+:1082900028780228CFD10120F8F7A6F9F8BD70B5EB
+:1082A0007B48804C4079012808D18248F8F7D6F8FD
+:1082B000002801D17F20A070F8F7BEF8724D687ECB
+:1082C000002803D0F8F7AFF8F8F758FCFAF736FEB5
+:1082D00000280BD02078022804D0DD206B498000D4
+:1082E00002F039FFA87B012803D006E000F0C1F9B5
+:1082F00070BD99208000F7F734FF0120FFF7C4FE1E
+:1083000020780028F4D020780128F1D05F496A480D
+:1083100002F021FF70BDF0B5044689B00020069040
+:108320000190F7F7F1FE03905E480078022803D031
+:108330005649624802F00FFF554D6879012809D16E
+:108340005C48F8F78BF8002802D156497F208870E6
+:10835000F8F772F85648FBF7FDFA4B4E0746002C2B
+:108360006FD05348FBF700FC00286AD0F7F740FEB7
+:10837000002866D0707E00280AD00524641EE4B26E
+:10838000F8F71DFC022811D0012800D00020019030
+:10839000474A4B4CD01C0290062F52D238007844EA
+:1083A000007900188744B4B4B409B44E002CE5D168
+:1083B00044A1484802F0CFFEE8E7B07B012840D056
+:1083C00004283ED001990398084304D1A8790028D5
+:1083D00001D0022835D1687901281AD1A079002866
+:1083E00017D10120A07110784006C00FE0713A4803
+:1083F000029902F0ACFF2B4C384FA0787F2804D1B3
+:10840000532030A1000102F0A6FEA07838707F2032
+:10841000A0702248F7F7B7FF22480321017028799E
+:10842000002877D0012808D0022873D0032804D070
+:1084300024A12B4802F08FFE6CE00120F8F7D4F85D
+:1084400068E065E01348D178C07981424AD111488B
+:108450001179037A994245D15179437A994241D1B0
+:108460009179837A99423DD1D179C37A994239D1B0
+:10847000117A037B994235D11178407B4906C90FA7
+:1084800081422FD101212EE0B4200020488001003C
+:10849000D420002074200020042100202C21002062
+:1084A000DE04000008010020D1020000510300009A
+:1084B000542100200A01002083030000C1030000B2
+:1084C000F42000207372635C6C6C5F6164762E63D1
+:1084D00000000000AB030000FC200020022100206F
+:1084E000090400000021B07B012801D0042801D13B
+:1084F00000290AD100280BD101990398084304D11F
+:10850000A879002801D0012802D1307E00281FD090
+:1085100001200690707E002803D0F7F784FFF8F75B
+:108520002DFB0698002802D00120FFF7ADFD73480F
+:10853000017800290AD00178012907D000780328A2
+:1085400004D049206E49000102F005FE09B0F0BDDB
+:108550006A486C4F4068397BC173797B0174B97B81
+:108560004174F97B8174684909784906C90FC1765D
+:108570001C30029902F0EBFE6048397C4068C174FF
+:10858000797C0175B97C4175F91E897D81750299E7
+:108590004A7D0B7D110219430183F91E8A7E4B7EB1
+:1085A00012021A438280029A537E177E1A023A43BD
+:1085B000C2808A7F4B7F11021943018153490A30DF
+:1085C00002F0BAFE52480179CA064C49D20E4968F7
+:1085D0008A7600794009C0310871287A002803D0D2
+:1085E00047494C4802F0B7FD0020A87243484B4968
+:1085F00047687888B085F87EE873B88B2882F88B56
+:108600006882388CA88244480078A875444802F0F3
+:108610009EFEB888F087F888208038896080C0374F
+:10862000387920710198002860790BD00121084326
+:108630006071F8F7DDFA61794000C907C90F01439D
+:10864000617102E0400840006071012028722B4CEB
+:1086500000202070F7F7D3FEF7F7C6FEF7F7D2FD3C
+:10866000F7F774FEF7F78AFE01206168FAF785FDD7
+:1086700050E7F8B5F7F7C3FEF7F7B6FEF7F7C2FD18
+:10868000F7F764FE274E0027707E002804D0F7F726
+:10869000CAFEF8F773FA7776184D2F70F7F76EFE6B
+:1086A000B07B012804D000210846FAF766FDF8BD2A
+:1086B00000210220FAF761FD1B4C207A002803D02C
+:1086C0000F491A4802F047FD68780028EFD0124899
+:1086D000417BE1730078A0751549164802F037FE1A
+:1086E0000E490F4802F033FE3C20A07268684088B3
+:1086F000B085012020726F70F8BD000008010020D5
+:10870000C48401005721002054210020732100203F
+:10871000742100203D0400007420002075200020FA
+:10872000EB200020B4200020D42000204F020000C5
+:108730007B200020E4200020F8B5FBF7FBFF044677
+:10874000FCF7BFF8FE4E054670692030407B0028DC
+:1087500026D0012844D0022846D003284DD0FF203F
+:10876000F8A19C3002F0F7FCB069F72201781140C3
+:10877000017072692032937BDB071B0F1943FB23C7
+:1087800019400170D37BDB075B0F19430170577BE6
+:10879000EF23022F3CD0012F3FD0032F41D046E0E2
+:1087A000EC48FCF76DF8002804D0716903202031F3
+:1087B0004873D9E7E748FBF74DFF002804D07069FC
+:1087C0005321095C002907D0E248FCF700F87169E1
+:1087D000012020314873C7E7022120304173C3E7ED
+:1087E000DC48FBF7F4FFBFE7DA48FBF733FF00286C
+:1087F000BAD1FF20D3A18E3007E0D648FCF740F86D
+:108800000028B1D1FF20CFA1963002F0A4FCABE745
+:10881000012C08D8002D06D009E06D1E2C4302D192
+:1088200005E0002C03D019401023194300E0194043
+:108830000170D17D002915D0517B012912D0C64885
+:10884000F7F7A1FDC548002101767269116E526EDD
+:1088500042610161C049B269F8F7FBF80020F8F7FE
+:1088600007F903E0F7F78FFDF8F725F9B06900780D
+:10887000C00606D4F0690078C00602D4F07900285A
+:1088800006D0B079002803D101210846F7F7F6FD9C
+:10889000032030703079002803D1F7F791FD0120D3
+:1088A0003071F8BD10B5A649002348690246203052
+:1088B000C37483750120412398548032927F002A2B
+:1088C00003D008700021022001E000210320FAF704
+:1088D000D2FB10BD06281AD202007A4412799218EF
+:1088E00097440205090D101000290ED00FE0891ED3
+:1088F00002290AD90BE0891F012906D907E00829B6
+:1089000003D004E00B390B2901D801207047002067
+:10891000704730B5044683B08E48FBF77FFF0028D0
+:1089200004D1F52087A1C00002F015FC844DA86990
+:10893000FBF75AF90321A869FBF777F9A869EF2239
+:108940000178114001702146FBF7D8F90E2C5BD25B
+:1089500020007844007900188744565606561F5A5E
+:108960005A175642565A312B75485D224169525C5E
+:10897000002A04D006218069FBF76DFA48E0C03177
+:10898000C9798069FBF767FA42E06D4841698069FF
+:108990008031497AFBF7D0FA3AE0694D6969A869F4
+:1089A000B031FBF791FA6969A8698431FBF798FA4D
+:1089B0002EE0634806218069FBF7BAFA28E0604D93
+:1089C00028690178A869FBF79DFA28698188A86958
+:1089D000FBF79AFA28694188A869FBF799FA17E02A
+:1089E000002000900190564841694031097F0029DC
+:1089F00005D06A461178012211436A461170694612
+:108A00008069FBF7A7FA03E04EA1554802F0A3FBEB
+:108A1000FBF715FF002804D17F204AA1000102F0D6
+:108A20009AFB0C2C0AD0072C06D04548002140693F
+:108A3000403041810121817303B030BD40480021A5
+:108A400040694030018203B030BDF0B53C4D064670
+:108A500068698DB020300079012801D1F7F7ECFC6E
+:108A60000024012E1ED168692030017E002902D128
+:108A7000C07D002801D0F8F71EF8F7F7C0FCF7F723
+:108A8000B3FCF7F7BFFBF7F761FCF7F777FC687902
+:108A9000C006686902D58030048703E08030018F0A
+:108AA000491C018768790226C107002901D1800786
+:108AB00013D568692030817D002902D0032907D0B1
+:108AC0000BE00121817500210120FAF7D4FA04E0BE
+:108AD000867500210120FAF7CEFA68692030817D81
+:108AE000012903D16979090700D586751448807A70
+:108AF000002861D100F015FF1648FBF78FFE002813
+:108B00005AD00F4D287A002856D16869C621095CD1
+:108B100000290ED02030C17C0120FFF7DBFE0028A9
+:108B200007D168692030C17C0420FFF7D3FE0028FC
+:108B300018D06869CB21095C062919D01FE0000014
+:108B4000100100207372635C6C6C5F736C617665FE
+:108B50002E6300002801002080210020A821002091
+:108B6000EA070000686940300481447702204DE044
+:108B70002030C17C0420FFF7ADFE002815D06869C5
+:108B80002030C07C801E15287ED2010079440979EE
+:108B900049188F449B9B9B1C9B9B9B979B1E9B9B5D
+:108BA0009B243E9B9B9B9B9B900068695621095C84
+:108BB000C90702D0C030C472AEE00C20FFF7A9FE96
+:108BC000686901224030817D11438175A4E007204E
+:108BD0001CE0FBF7F0FE00286CD00B2016E0F3F74A
+:108BE00050FA0C2866D368690821B030F3F74AFAC6
+:108BF000002806D0686904218430F3F743FA00287E
+:108C000003D1F4A1F74802F0A6FA0420FFF781FE91
+:108C100082E068698446C030807A042802D0052842
+:108C200039D079E06046E030007D002874D1EE490B
+:108C30006046102600230822D8306944F51A2D1802
+:108C4000203DEF7F4F70AD7F8D70891C521E9B1CA5
+:108C5000002AF3D103A86346102608210330A83365
+:108C6000B51AED18203DEF7F4770AD7F8570801CF1
+:108C7000491E921C0029F3D16846F9F70CFB08AF96
+:108C80004ECFDA4D686900E020E070304EC005201C
+:108C9000FFF73FFE0BE060464030017D002903D026
+:108CA00001214177022000E00D20FFF732FE6869C4
+:108CB000C030847230E00620FFF72BFE6869403038
+:108CC000847329E00920FFF724FE25E06869CA21A2
+:108CD000095C002920D0062906D02030C17C002064
+:108CE000FFF7F8FD002817D068690146C0318A7A7D
+:108CF000072A11D213007B441B79DB189F440C0C0C
+:108D00000C0C0C0C03004030807DC20700D154E7EE
+:108D1000C043800700D18C72B44D2879002868695F
+:108D200002D08030048303E08030018B491C018332
+:108D30006879C007686904D0A4210C54403084804D
+:108D400003E040308188491C8180E879002806D002
+:108D50006969A0310879022806D8401C0871686941
+:108D6000A0300079022806D9686901468030048362
+:108D70004483A0310C7168692030C17C0020FFF76A
+:108D8000A9FD002804D168692030C07C07284CD197
+:108D900068690146C0318A7A062A46D0C97A06290E
+:108DA00043D03621095C02293FD1A0300079002848
+:108DB0003BD1FBF7AEFC002837D0FBF782FD002843
+:108DC00033D06869014680314A8A012A2DD90122AF
+:108DD0004A77024640329688D288931E9E4201DB33
+:108DE000012302E0921B521E93B20A8BAE89B2425B
+:108DF00001D3012202E0B21A521C92B2934200D96E
+:108E00001346012B00D14C77C0300278002A10D0D5
+:108E1000498B4088814201D3012102E0401A401C65
+:108E200081B28B4205D90B4603E06869012380308B
+:108E300044776A69118D1646C81883B2104680308F
+:108E400083822036B77D002F25D0012F23D0022F1B
+:108E50000CD0032F0AD05FA1654802F07CF9687935
+:108E6000C006686919D58030C4841BE0F67C032EE7
+:108E700009D0082E0FD04032D1889288891A891ED5
+:108E800059180182EBE740329688032E03D3D2882B
+:108E90008918491CF5E70382E1E78030C18CC28A5A
+:108EA0008918C18468690246C0329179002906D0C8
+:108EB0000146403196230E891B5AF3180B81A97A7B
+:108EC0000426002913D002463D214032917001460C
+:108ED0002031CC748C75012151708030807F002846
+:108EE00070D0297000210220FAF7C5F85EE0014633
+:108EF0002031CB7C042B48D02B7A002B1ED05A0774
+:108F000001D4DA0604D51E2240308270CE743CE0D3
+:108F10001A0704D53D2240308270CE7435E0D80760
+:108F200005D1980703D42BA1324802F014F96869DF
+:108F30002A21422211542030C67426E04030837B1F
+:108F4000002B05D047897B1C438183899F420FD228
+:108F5000D37A062B02D0927A062A05D1038A5A1CAC
+:108F600002828289934203D20389C288934203D347
+:108F700022228270CE7408E08B7D002B23D0838860
+:108F800093423CD308228270CE7468694122014624
+:108F90002031CC748C75012111548030807F0028E1
+:108FA0002AD0297000210220FAF765F8F9F7EEFFC0
+:108FB00000282DD068690146FF300130827A002AEE
+:108FC00022D025E018E08288062A18D33E2282703B
+:108FD000CE74DAE77372635C6C6C5F736C61766598
+:108FE0002E63000039060000FFFFFFFF1001002084
+:108FF000790800004502000000210320D4E7012089
+:10900000287000210846CFE74988818101218172BB
+:109010006869803084770DB0F0BDF8B50C4617460E
+:109020006946FAF7F9FA002801D00020F8BD009847
+:109030000146E030027AF74E0025002A17D0002FB3
+:109040007DD1657007212170007A00280DD07169EB
+:10905000E8204D8445540A22A01CEA3101F0F1FEBB
+:109060000098E030007A0028F1D1A57067E0027D19
+:10907000002A2AD0002F62D1017D0D2920D20A00BA
+:109080007A441279921897441B1B1B1B1B1B1B1B3A
+:109090001B1B1B0F060065700C212170817DA170C8
+:1090A00071694988A18009E065700B212170817D7B
+:1090B000A17071694988A180817EA17105753EE02A
+:1090C000D549D64802F047F839E0027F002A15D08A
+:1090D000002F34D16570082222707269FF315288E6
+:1090E000628001310A88A2804A88E2808A882281CF
+:1090F000CA8862810989A181057720E0FF310131A9
+:10910000887A002808D0002F19D1657011202070AE
+:10911000888960808D7212E0887B002886D0002FBD
+:109120000DD1657012202070887B002807D08D73C8
+:10913000088A6080488AA080887B0028F7D10120B7
+:10914000F8BDB4480078012801D00C2070470020F9
+:10915000704770B5AF4C05462078002803D0AE4963
+:10916000AF4801F0F8FF00202561E0720120207077
+:109170002078012803D0A849AA4801F0ECFF70BD6F
+:10918000F8B5A44D2978012901D00C20F8BD01269D
+:10919000686180308677807AFBF749FA00282ED004
+:1091A00068698030807AFBF799FB002827D06869CE
+:1091B0008030807AFBF70EFB002820D06869803071
+:1091C000807AFBF74AFB002819D0F7F7CCF86869DA
+:1091D00000248030408A002825D09348FBF71EFBEE
+:1091E000002820D06869C621095C00291BD02030E6
+:1091F000C17C0120FFF76EFB002802D013E0122093
+:10920000F8BD68692030C17C0420FFF763FB0028AB
+:1092100009D168694030048144770220FFF779FB67
+:109220006869803044776869E821095C002905D1C4
+:10923000418CC288914201D9A98101E0C188A981EC
+:1092400001468031CA8A521E93B20A8BD21892B25A
+:109250000A830F7F002F02D04C830C7702E04F8BE4
+:10926000FF184F8305464035AF88FF18AF804D8A01
+:10927000012D01D86D1C4D82002B01D0A4231C545C
+:109280002030C07C634D042817D0487F002816D0BA
+:10929000A889824213D2FBF73CFA00280FD06869F4
+:1092A0000146C0310A78002A09D08030408B4988B5
+:1092B000884204D3AC70EE7003E0AE7001E0AC7095
+:1092C000EC7068699D210C543321095C062901D09A
+:1092D000072917D1CC21028D095A511A09B2002948
+:1092E00010DB0146CE310A3002F04FF80122022194
+:1092F0006869FAF7C8FE6869CB210C5433210C5415
+:1093000040308677434D962168690A5A01462830D5
+:10931000891CFAF75FFFA87800284DD16869C02141
+:10932000095C002901D0803044830120F6F7DFFD7D
+:10933000384D68691330F6F7A8FF68690F30F6F703
+:10934000E6FE0120F7F70CF8686901462030027E3E
+:10935000002A02D1C07D002806D07031ACC9334844
+:10936000ACC0334802F000F8F6F7F6FF01210846DA
+:10937000F6F7FAFE274D68698030006AF7F706F8BD
+:109380002C48FBF7BEFA002801D06C7002E06E702A
+:109390002948E86168692030007E002802D068789A
+:1093A000002817D0E869F6F7EEFFF7F784FB686945
+:1093B00040300078F6F7BDFE164802214471C471B2
+:1093C000847104724472847204710170F6F7D6FFDE
+:1093D0000020F8BD1848F6F7D6FF144806766A69EB
+:1093E000916ED26E42610161134AE969F7F731FB70
+:1093F0000120F7F73DFBDAE710B5064C207802288C
+:1094000001D00C2010BDA078002817D00020FFF755
+:109410001CFB2FE010010020D48F0100DD080000AC
+:109420002D0900003809000028010020A821002093
+:10943000C12100202C01002080210020F6F793FF9D
+:1094400001210020F7F71AF804202070606920300D
+:109450000079012801D1F6F7F8FFE07A002809D059
+:10946000012807D0022807D0032805D0F949FA4877
+:1094700001F071FE002010BDE9F7CAFDFAE7F749D7
+:10948000C8727047F8B5F54C2078032803D0F1492D
+:10949000F34801F060FE616901252031887A0028D7
+:1094A00006D0002088720D73A07904221043A071A9
+:1094B000A0690278D24392072BD1C97A002928D11A
+:1094C000FAF753FC04281DD0052802D00B2819D127
+:1094D00011E0606901462030C27C102A12D10022BE
+:1094E0008A66CA6605767031CCC9DE48CCC0DE48D3
+:1094F00001F03AFF06E060692030C17C0B2901D100
+:1095000000210176606902212030C572A0790843EC
+:10951000A071A0690078C00606D4E0690078C00692
+:1095200002D4E07900280FD0607800280CD1A0790F
+:10953000002809D1F9F718FD002805D0207A002865
+:1095400002D1607A002803D00120FFF77EFA1DE0E7
+:10955000C648FBF7D6F9002802D00020607002E070
+:109560006570C348E06160692030007E002802D049
+:10957000607800281CD0E069F6F705FFF7F79BFA42
+:1095800001210020F6F77AFF0420207020780128BE
+:109590000DD0E07A00280AD0012808D0022819D07E
+:1095A000032817D0A920AB49000101F0D4FDF8BD74
+:1095B000AF48F6F7E8FEAB4805766269916ED26E69
+:1095C00042610161AA4AE169F7F743FA0120F7F71E
+:1095D0004FFAD5E70120F7F707F8F8BDF8B59F4C2B
+:1095E00005462078042803D09A49A24801F0B3FD2B
+:1095F0009A481027417939434171002D7ED0F7F701
+:1096000072FA0125002814D1944842692032117E53
+:1096100000290ED0C1694B78DB060AD00978D27BCD
+:109620000907C90F914204D185720120FFF70DFA95
+:1096300054E18A4CE07800281ED0E0694178C906E0
+:109640001AD10078C00617D460692030007901284B
+:109650007ED1F6F7F1FE6169881C2831FAF7AAFE7F
+:10966000002875D06069C21D4388F932138220300A
+:10967000007C907495732BE160692030007901289B
+:1096800011D1F6F7D9FE6169881C2831FAF792FEEC
+:10969000002808D06069C21D4388F9321382203047
+:1096A000007C90749573E069002600784007C10F34
+:1096B00060692030827B914242D0407B00283BD0C1
+:1096C00002280FD1FAF7EAFF002803D161496A485E
+:1096D00001F041FD62690023106E516E401C59413A
+:1096E00051661066606920304673017B012903D101
+:1096F0000673A1793943A171C17A00E0D1E0012953
+:1097000014D1C672A07908210843A071FBF7C7F8ED
+:10971000002803D14F49594801F01DFD626900231B
+:10972000106E516E401C59415166106660692030C0
+:10973000817B01292ED085736079082108436071EF
+:109740004649C869496903781A07D40F203100E0F7
+:109750007FE0CA7B94420CD19B07404C9B0F012BAE
+:1097600048D0022B46D0032B16D0207A0421084380
+:1097700020723A48417929434171C67181790907BC
+:1097800004D541692031C97C032962D0017A0029BE
+:109790005FD182E08673CFE76378002BE9D18D72C9
+:1097A000A3792B43A371012A10D0CD73FAF7DDFA08
+:1097B00006280DD00B28DCD1606901462030C27C20
+:1097C0000C2AD6D1C67540310D75D2E7CE73EDE7C0
+:1097D000606901462030C27C122ACAD100220A6682
+:1097E0004A66C57570319CC91E489CC0093001F09D
+:1097F000BBFDBEE74078C30649D06278002AB8D1E5
+:10980000C006C00E1B283FD8C97C0520FFF762F8B0
+:10981000002804D0607A082108436072A9E76079C3
+:10982000042108436071FBF793F8002803D109492C
+:10983000134801F090FC60690023816EC26E491CE0
+:109840005A41C26681662030C17B01291AD0C57396
+:109850008FE73DE0D48F01000D0A000010010020C9
+:10986000360A0000A8210020C12100202C01002080
+:1098700080210020A80A00000A070000220700003B
+:109880007C070000C67374E7207A384370E7012A2A
+:1098900001D0CD736DE7CE736BE7407A002817D106
+:1098A0001AE0F948022211434171C179491CC9B239
+:1098B000C17101290CD840692030007E00280BD0EE
+:1098C000F2484078C106C90E052905D2C00603D06A
+:1098D0000120FFF7BAF801E0FEF72EFFEA48017811
+:1098E00001290CD0C07A002809D0012808D002280C
+:1098F00005D0032804D0E649E64801F02CFCF8BD69
+:109900000120F6F771FEF8BD10B5DF480078042895
+:1099100003D0DF49E04801F01EFC0120FFF795F875
+:1099200010BDF8B5D84C0427A07900250007002801
+:109930002FDA207A00282CD160692030C07C801E6C
+:10994000132826D201007944097949188F44210946
+:1099500021212121212121212121212121212121F7
+:109960001A006069014640318D734A7F002A04D095
+:1099700006228A702030C7740BE016228A702030CD
+:10998000C77406E0606901464031CD748D732030A4
+:10999000C57400F063F9BC4801268279500700289D
+:1099A00022DAB948017A00291ED1406901462031E6
+:1099B0000B46C97C891E072916D20C007C442479E9
+:1099C0002419A744031111110B110E000146403157
+:1099D0008D73C030007A8870DF7405E0C030C672C5
+:1099E00002E00221C030C172A74C90074AD5207A0C
+:1099F000002847D160692030C17C0120FEF76AFF52
+:109A000000283FD1A069C0780E287DD2010079449A
+:109A1000097949188F44A7A706A73747630BA718EA
+:109A2000A7279755616903202031C8749FE06069BA
+:109A30002030C07C052803D09549984801F08BFB65
+:109A400060692030C57492E060692030C07C0928CC
+:109A500003D08F49924801F07EFB60694E210D547E
+:109A60002030C57483E060692030C07C0B2803D0AF
+:109A700087498C4801F06FFB606953210E540C211B
+:109A80002030C17473E060692030C07C0F2803D09F
+:109A90007F49854801F05FFB606953210E54102116
+:109AA0002030C17463E060692030C07C102803D08E
+:109AB00077497E4801F04FFB606912212030C17464
+:109AC00055E060692030C07C102803D07049784888
+:109AD00001F041FB606914212030C17447E06069E6
+:109AE0002030C07C162803D06949724801F033FB4E
+:109AF000606901464030C5748573E031087D0028F7
+:109B000006D063492B2000E02DE0400101F023FB4B
+:109B10006069014640310A7D002A08D00D754288EF
+:109B2000F8210A520146E0318D750C2207E0418888
+:109B3000F82211520146E0318D758E760B220A759E
+:109B40002030C57413E060690146C030827A062A6D
+:109B500004D14031897D890700D58572C17A0629F3
+:109B600005D1C57203E04A49534801F0F4FAA079DF
+:109B7000C00612D5207A00280FD160692030C17C40
+:109B800007290AD20A007A441279921897440505E7
+:109B90000505050503000721C174607A000727D574
+:109BA00060692030C17C0520FEF794FE002807D0B4
+:109BB000207A0821084320726069E030057517E0BB
+:109BC000607938436071FAF7C3FE002803D1304949
+:109BD0003A4801F0C0FA60690023816EC26E491CE8
+:109BE0005A41C26681662030C17B012934D0C673D8
+:109BF00060693321095C08292DD10146028DC031ED
+:109C00008B89521C9A4226D1227A002A23D14A8A71
+:109C100083889A4207D18B8AC788BB4203D1CB8AFB
+:109C20000789BB4208D043888B85CA858A8A0A8601
+:109C3000CA8A4A86E8210E5401221146FAF723FA0D
+:109C400000210420F9F717FA6069CB210D54203068
+:109C5000C57403218175F8BDC573C9E730B50A4CD9
+:109C600083B0A079C0077DD0207A00287AD16069BE
+:109C70002030C17C0120FEF72DFE00284AD1E0698A
+:109C8000C0780D286FD21BE0100100208021002039
+:109C9000D48F01000E0B0000160B000027050000FA
+:109CA0002D050000340500003C05000043050000C0
+:109CB000490500005B050000BD0500009E03000093
+:109CC00001007944097949188F443B1506C14D4D6F
+:109CD000FE24FD4D98B2FC00E069FAF7BEF8616918
+:109CE000C82250540222332042540020403148817F
+:109CF0000120887385E160692030C17C0020FEF777
+:109D0000E9FD0028207A02D0002803D103E00121D8
+:109D10000843207275E1E069FAF798F86169CC228E
+:109D200050520A8D801ABC4A00B290425FDC002873
+:109D30005DDDCE31E069FAF77EF8606906212030FA
+:109D400083E060692030C17C0020FEF7C3FD00285D
+:109D500003D1207A012108432072207A00284CD1B7
+:109D6000E06901E055E134E1FAF732F800282ED03D
+:109D7000E069FAF728F86169CC2250520A8D801AFE
+:109D8000A54A00B2904232DC002830DDE069FAF7E3
+:109D900014F86169C0318873E069FAF707F86169FE
+:109DA000C0310882E069F9F7E6FF6169C031488295
+:109DB000E069F9F7E9FF6169C0318882E069F9F784
+:109DC000ECFF6169D62250520820203196E060698C
+:109DD0002030C17C0020FEF77DFD002803D1207AD1
+:109DE000012108432072207A002806D100E12820B2
+:109DF0004222505404202031C87402E160692030AE
+:109E0000C17C0020FEF766FD002803D1207A0121E5
+:109E100008432072207A00285FD160690022014641
+:109E200040304281012282730B202031C874E8E067
+:109E300060692030C17C0C2903D0217A02221143B1
+:109E40002172217A002948D10D21C174D9E06069BD
+:109E50002030C17C0020FEF73DFD002808D160695C
+:109E60004030007D002803D1207A01210843207270
+:109E7000207A002831D160690022014640304281B9
+:109E800001258573A831E069FAF704F86169E06992
+:109E90008031FAF710F86069E030007F002803D0C5
+:109EA0005E495F4801F057F96169FE204A884252D5
+:109EB000FF310131E069F9F7D7FF6169E069FF31EE
+:109EC000093102E01CE056E008E0F9F7D9FF6069CB
+:109ED000FC210D540F212030C17492E060690146CD
+:109EE0002031CA7C122A03D0227A02231A4322721A
+:109EF000227A002A6CD1403082731620C87480E028
+:109F000060690146C031CA7A002A06D0897A0629DA
+:109F100003D0217A012211432172217A002970D1C4
+:109F20004030807D800715D4E069F9F7F5FF61695D
+:109F30004031C875E069F9F7F1FF61694031088384
+:109F4000E069F9F7F0FF6169022240314883887DBA
+:109F50001043887560690146C0318A7A062A01D1AA
+:109F600000228A724030827DD2074AD10622CA720C
+:109F70000021018245E060692030C17C0020FEF7AD
+:109F8000A9FC002803D1207A012108432072207AFD
+:109F9000002836D16946E069F9F7D5FF68460078B0
+:109FA000C107C90F6846017004D0606901214030C3
+:109FB000017703E060690021403001776069002289
+:109FC0000146403042810122827309202031C87449
+:109FD00017E060692030C17C0020FEF77BFC002880
+:109FE00003D1207A012108432072207A002808D169
+:109FF000E069F9F7BAFE61698922505405202031E1
+:10A00000C87461690023886ECA6E401C5A41CA66D2
+:10A01000886603B030BD0000FE7F0000D48F0100D1
+:10A020002104000047490968016000207047454944
+:10A030000860002070470121434A002803D001280E
+:10A0400003D042487047916300E0D163002070471D
+:10A050003F49012008603D48801C704704223D4B69
+:10A060003B49002805D05A60086901221043086165
+:10A0700008E008694008400008619A603249002001
+:10A08000C03188600020704731490622002808D07E
+:10A09000012809D002280DD003280FD02B48401CDE
+:10A0A00070470869904302E008699043801C08618A
+:10A0B0000020704708699043001DF8E708691043C5
+:10A0C000F5E723494A6A02434A6200207047204963
+:10A0D0004A6A82434A62002070471D49496A01600A
+:10A0E000002070471A49CA690243CA6100207047BC
+:10A0F0001749CA698243CA61002070471449C96977
+:10A100000160002070471249024600204031002AB9
+:10A1100003D0012A01D0072070478A6370470D4998
+:10A120000420886008490020C03188600A4801681E
+:10A130008022090A090211430160084901200860D0
+:10A140007047000000040040400000400420000070
+:10A15000000500400003004000E400E000E100E0F2
+:10A160008107C90E002808DA0007000F08388008A8
+:10A17000814A80008018C06904E080087F4A80001E
+:10A1800080180068C8400006800F704710B504466C
+:10A1900000F0DBF8002813D02046FFF7E1FFC0B243
+:10A1A00000F0E1F800280DD07549E2060B78D20ED8
+:10A1B00001209040002B08D04A681043486006E018
+:10A1C000704810BD6F48401C10BD6F4908600020EA
+:10A1D00010BD10B5044600F0B8F800280BD068494F
+:10A1E000E2060B78D20E01209040002B05D04A6881
+:10A1F00082434A6004E0634810BD634980310860CF
+:10A20000002010BD70B50D46044600F09EF80028F1
+:10A210000BD05E480068E206D20E01219140084052
+:10A2200000D001202860002070BD564870BD10B5D8
+:10A23000044600F08AF8002807D0E106C90E012084
+:10A24000884052490860002010BD4E4810BD10B52E
+:10A25000044600F07AF8002808D0E106C90E012073
+:10A2600088404A4980310860002010BD454810BD33
+:10A2700070B50D46044600F068F8002819D028464D
+:10A2800000F071F8002816D0A007C10EFF228A4006
+:10A29000A807000E8840002C10DA2107090F0839A2
+:10A2A0008B0835499B005B18D96991430143D961FB
+:10A2B0000CE0344870BD3348401C70BDA3082F49E2
+:10A2C0009B005B181968914301431960002070BD21
+:10A2D00070B50C46054600F038F8002805D0284631
+:10A2E000FFF73EFF2070002070BD264870BDBFF311
+:10A2F0004F8F21492648C860BFF34F8FFEE770B5E6
+:10A300001F4C05462178012000290ED1207072B61D
+:10A3100000F0F4F81C4E803631688143616000F033
+:10A32000EDF8C043306062B600202870002070BD98
+:10A3300013490A78002A06D0002804D1124A486836
+:10A340001060002008700020704710B504462028D7
+:10A3500007DA00F0D3F80121A140084201D1012021
+:10A3600010BD002010BD012803D0032801D000201B
+:10A37000704701207047000000ED00E000E400E0BD
+:10A38000300100200120000000E100E000E200E0D8
+:10A390000400FA05F8B504468007002501260028C8
+:10A3A00004DA5848C563C66302208443E00404D538
+:10A3B0005548C563C66380148443600003D5534881
+:10A3C000456080058443E00504D55148C563C663F4
+:10A3D00080158443A00404D54E48C563C663401469
+:10A3E000844360042704C00FF90F884203D04AA1B8
+:10A3F000612000F0B0FEB80F0AD04C49CD634C4844
+:10A40000C563C563CE63C663C6630320800384430C
+:10A4100020050AD5474FFD632F20E6F7C5FEFE63F2
+:10A420002F20E6F7C1FEF8148443F7F7D7FF424820
+:10A43000044203D038A18D2000F08DFEF8BDF0B5A8
+:10A4400000210A46FF230446CC40E4072AD04CB240
+:10A45000E606F60E0125B540384E3560384E3560BB
+:10A46000002C11DA25072D0F083DAE08354DB6003A
+:10A470007719FD69A407E60E1C46B440A5431446AF
+:10A48000B4402543FD610DE0A6082F4DB6007619B6
+:10A490003568A407E70E1C46BC40A5431446BC40E3
+:10A4A00025433560491C2029CDD3F0BD70B5274C1C
+:10A4B0000D462060FFF76EFF2068FFF7C0FF2846BB
+:10A4C000E8F766F8F7F796FEF1F792FDF7F786FFE3
+:10A4D000FFF725FEE7F7E2FE00F06AF870BD10B561
+:10A4E0001A4C2068FFF756FF2068FFF7A8FFF7F720
+:10A4F00075FFE8F7C7F80020206010BD134800681A
+:10A5000070470000C01F0040C0CF004000E5014080
+:10A51000C08F0040C0DF00407372635C736F635F85
+:10A52000636F6E6669672E6300000000C0EF004035
+:10A53000C0FF0040C0BF0040FEFF0FFC80E100E014
+:10A5400080E200E000ED00E000E400E038010020DF
+:10A5500070B5002402460D4620462146002A1ED032
+:10A56000012A04D0022A04D0032A1ED103E00120CC
+:10A5700002E0022013E003202B0000F00DFF07167D
+:10A580000507090B0D0F1600012108E0022106E066
+:10A59000032104E0042102E0052100E00621F2F796
+:10A5A00058FA002801D0204670BD0724FBE70000C0
+:10A5B000B348002101708170704770B5B14D01231F
+:10A5C0006B60B14B1C68002CFCD0002407E00E68C7
+:10A5D00006601E68002EFCD0001D091D641C9442FC
+:10A5E000F5D30020686018680028FCD070BD70B5F5
+:10A5F000A34C0E466178884203D0A4A16F2000F0DE
+:10A60000AAFD0325330000F0C7FE09520624245298
+:10A610005252524952002078022803D09BA1732045
+:10A6200000F099FD2570A078022802D0012804D0FE
+:10A6300008E0A068E8F7C6FC04E02046083007C838
+:10A64000FFF7BBFF0020A070F2F7A4F904202070F0
+:10A6500070BDF2F754FA01466068F3F769FC0646EC
+:10A660002078022803D089A1872000F074FD8B4A4E
+:10A670008B498C48964205D86269032A02D2521C43
+:10A68000626102E0864207D84D71801BC860844930
+:10A690006078F2F7ABFE70BD032003E0A0780028DD
+:10A6A000FAD10220F2F77EF800F0E1F870BD77A150
+:10A6B000B12000F050FD70BD70B50546F2F71FFAED
+:10A6C0006F4C60602078012803D070A1B82000F0A2
+:10A6D00042FD73490220087000220A718D60042235
+:10A6E0004A71704ACA6020706078F2F77FFE70BDD0
+:10A6F00010B5634CA078002802D12078002801D042
+:10A70000112010BD6848F2F78BF96070607800285E
+:10A7100004D0012020700020606110BD032010BD16
+:10A7200010B50124020B64040121604BA04202D247
+:10A730009140186802E0203A58689140084000D0E3
+:10A74000012010BDF8B50E46910005464F1914467C
+:10A750003F1F0091E8F747FC009980028919091F03
+:10A76000B14201D2012200E00022002C03D0FF21DF
+:10A7700001318C4201D90920F8BD4D498D4219D3D0
+:10A78000AF4217D3854205D2874203D228463043D1
+:10A79000800701D01020F8BD8E420BD3002A09D1CA
+:10A7A0002846FFF7BDFF002804D13846FFF7B8FF61
+:10A7B000002801D00F20F8BD3E483F49006888427C
+:10A7C00005D0224631462846FFF7F7FE0FE0FFF797
+:10A7D0008FFF0028EFD12A480121C66085600461FF
+:10A7E00081702046302148431830FFF765FF002074
+:10A7F000F8BD10B504462E48800A84420BD3E8F712
+:10A80000F2FBA04201D8102010BDA0020446FFF7C1
+:10A8100087FF002801D00F2010BD26482649006878
+:10A82000884203D02046E8F7CDFB0AE0FFF760FF3F
+:10A830000028F1D112480221846081701F48FFF77F
+:10A840003BFF002010BD1A48010B01208840401E2C
+:10A85000704700B50B460246FFF7F5FF104201D0E6
+:10A860000F2000BD114802604360002000BD10B5FC
+:10A87000034C6078F2F728F900202070A07010BD1A
+:10A880003C01002000E5014000E401407372635C7C
+:10A89000736F635F666C6173682E630030750000D0
+:10A8A000D0210020D0FB0100EFA5010000060040F0
+:10A8B00000C0010064000020BEBAFECA3A56000083
+:10A8C000F94805218170002101704170C1708160DB
+:10A8D000704710B5F5490A78022A07D0CA681018DF
+:10A8E000C860C8689638F3F7DBFA10BD8A6810189C
+:10A8F00088608868F6E70378ED49EE4A002B02D0BD
+:10A90000012B10D014E00379002B01D0012B0FD1C3
+:10A910004379002B01D0012B0AD18368643B8B4221
+:10A9200006D2C06810E00379002B03D0012B01D0C0
+:10A93000002070474379002B01D0012BF8D1C36868
+:10A94000643B8B42F4D280689042F1D8012070477A
+:10A95000F8B504460226F2F731FF0068002803D05C
+:10A96000D5A1BD2000F0F7FB0127CF4D002C08D06A
+:10A970002078002817D0012805D0022811D00328FC
+:10A9800013D02F710DE06068C82808D3F3F7FEFAE2
+:10A99000002804D06068FFF79CFF012603E0002632
+:10A9A00001E000F0FDF93046F8BD28780028F8D124
+:10A9B0006068FFF7A0FF0028E3D0606800780028F7
+:10A9C00026D0A878042803D0BBA1F72000F0C3FB51
+:10A9D000B64F0020387060680079012800D0002050
+:10A9E000387160684079002837D004207871606839
+:10A9F0008168E868F2F715FBB8606068C068963057
+:10AA0000F8600320A870A949E878F2F7EFFCC8E7DE
+:10AA1000A6480221017061680979012919D0002135
+:10AA2000017161684979002915D00421417161687B
+:10AA30008968963181606168C968C160C0689A4C54
+:10AA400014346060F2F75BF820606F700220A87029
+:10AA5000A7E70321E4E70321E8E70320C6E7F8B509
+:10AA6000914C0D46E178884204D0FF2092A11A3023
+:10AA700000F071FB2846002501268C4F030000F0F2
+:10AA80008BFC0906123C5E82939DCAA6CA00A07880
+:10AA9000032807D0A078022804D0FF2086A11E300A
+:10AAA00000F059FBF8BDA078032807D0A078022851
+:10AAB00004D0FF2080A1223000F04DFB0420A070C4
+:10AAC00025712078002815D1FFF703FF3878022878
+:10AAD0000CD0B868E0607F49886A7F4A02402261F2
+:10AAE0007D4AD24310408862002055E0E078F2F7BA
+:10AAF000BFFAEFE700F054F9F8BDA078032807D0BB
+:10AB0000A078022804D0FF206BA14B3000F023FB7B
+:10AB10002078002802D000F04FF9F8BDA078032873
+:10AB20001ED104202BE0081AF8606049E078F2F7A3
+:10AB30005DFCF8BD0420F1F735FEA570F8BDA078E6
+:10AB4000032807D0A078022804D0FF205AA16C3037
+:10AB500000F001FB20780028DDD1A07803280DD07B
+:10AB6000F1F7CDFF504E014614363068F3F7E0F9A7
+:10AB70000028DFDB71688142DCDBD4E70520F1F7D8
+:10AB800011FEA670F8BDA078042804D0FF204AA1C9
+:10AB90008D3000F0E0FA0220A1688847FFF7D8FE68
+:10ABA000FF260546C63642E0A078042804D0FF20E0
+:10ABB00041A1923000F0CFFA0120EDE7A0780428FF
+:10ABC00098D0FF203CA1973000F0C5FA92E7A0781A
+:10ABD00004280AD06078002802D0A078022804D087
+:10ABE000FF2035A19C3000F0B6FA2078002892D1E1
+:10ABF0002079002804D00620F1F7D4FD2571C0E7A4
+:10AC00006078002805D02949E078F2F7EFFB6570FD
+:10AC1000F8BD0720B3E7FF2027A1B73040E7002D9C
+:10AC20000AD0012D06D024A1304600F094FA022D5E
+:10AC3000F5D1F8BD042000E00320A1688847FFF7A4
+:10AC400087FE0546F3E770B5050005D0164CA078E1
+:10AC5000052803D0112070BD102070BD1F48F1F7EA
+:10AC6000DFFEE070E078002803D0A5600020A0702F
+:10AC700070BD032070BD10B50B480178002901D0CC
+:10AC8000112010BD817805292AD08178012929D089
+:10AC90008178002926D0012101708178012921D0F5
+:10ACA000807800281ED01FE054010020E021002001
+:10ACB0003D860100FF1FA1077372635C736F635FC2
+:10ACC000726164696F5F74696D65736C6F742E6314
+:10ACD0000000000000050040028100005FAA0100A2
+:10ACE0000F2010BD00F068F8002010BDF8B5394EF7
+:10ACF0000446B078002801D001280DD1002C0DD0D9
+:10AD00002046FFF7F8FD00280AD02078324D0028B1
+:10AD100008D0B078012823D00F20F8BD1020F8BD4E
+:10AD20000720F8BD02272F702079012814D00020B9
+:10AD300028716079002811D004206871A0689630CD
+:10AD4000A860E068E860E868224C14346060F1F7BD
+:10AD5000D6FE2060B77019E00320E9E70320ECE796
+:10AD6000002028702079012816D0002028716079F1
+:10AD7000002813D004206871A168F068F2F751F937
+:10AD8000A860E0689630E8600320B0701249F0785F
+:10AD9000F2F72CFB0020F8BD0320E7E70320EAE7E9
+:10ADA00010B50E48816A0E4A11400A4A12691143D1
+:10ADB0008162F1F7EFFD10BD10B5064CE078F1F7B8
+:10ADC00083FE0820F1F7EEFC0520A0700020207023
+:10ADD000607010BD54010020E021002000050040FB
+:10ADE000FD7EFFFF70477047034610B50B439B077E
+:10ADF0000FD1042A0DD308C810C9121FA342F8D0DE
+:10AE000018BA21BA884201D9012010BD0020C043E0
+:10AE100010BD002A03D0D30703D0521C07E0002046
+:10AE200010BD03780C78401C491C1B1B07D103780C
+:10AE30000C78401C491C1B1B01D1921EF1D11846F5
+:10AE400010BDF8B5042A2CD3830712D00B78491C07
+:10AE50000370401C521E83070BD00B78491C0370F3
+:10AE6000401C521E830704D00B78491C0370401C01
+:10AE7000521E8B079B0F05D0C91ADF002023DE1B53
+:10AE800008C90AE0E6F7A0F9F8BD1D4608C9FD406B
+:10AE90001C46B4402C4310C0121F042AF5D2F308FC
+:10AEA000C91A521EF0D40B78491C0370401C521E64
+:10AEB000EAD40B78491C0370401C012AE4D40978B9
+:10AEC0000170F8BD01E004C0091F0429FBD28B0703
+:10AED00001D50280801CC90700D00270704700298C
+:10AEE0000BD0C30702D00270401C491E022904D3B4
+:10AEF000830702D50280801C891EE3E70022EEE76B
+:10AF00000022DFE7020A08704A70020C8A70020E03
+:10AF1000CA707047002203098B4273D3030A8B4225
+:10AF200058D3030B8B423CD3030C8B4221D312E04A
+:10AF300003460B437FD4002243088B4274D303099A
+:10AF40008B425FD3030A8B4244D3030B8B4228D33B
+:10AF5000030C8B420DD3FF22090212BA030C8B4261
+:10AF600002D31212090265D0030B8B4219D300E001
+:10AF7000090AC30B8B4201D3CB03C01A5241830B86
+:10AF80008B4201D38B03C01A5241430B8B4201D336
+:10AF90004B03C01A5241030B8B4201D30B03C01A5F
+:10AFA0005241C30A8B4201D3CB02C01A5241830AD9
+:10AFB0008B4201D38B02C01A5241430A8B4201D308
+:10AFC0004B02C01A5241030A8B4201D30B02C01A32
+:10AFD0005241CDD2C3098B4201D3CB01C01A524199
+:10AFE00083098B4201D38B01C01A524143098B4222
+:10AFF00001D34B01C01A524103098B4201D30B010B
+:10B00000C01A5241C3088B4201D3CB00C01A52412F
+:10B0100083088B4201D38B00C01A524143088B42F4
+:10B0200001D34B00C01A5241411A00D2014652418D
+:10B03000104670475DE0CA0F00D04942031000D3AC
+:10B040004042534000229C4603098B422DD3030A01
+:10B050008B4212D3FC22890112BA030A8B420CD311
+:10B06000890192118B4208D3890192118B4204D33A
+:10B0700089013AD0921100E08909C3098B4201D3BA
+:10B08000CB01C01A524183098B4201D38B01C01AF4
+:10B09000524143098B4201D34B01C01A524103096B
+:10B0A0008B4201D30B01C01A5241C3088B4201D31A
+:10B0B000CB00C01A524183088B4201D38B00C01AC7
+:10B0C0005241D9D243088B4201D34B00C01A52419E
+:10B0D000411A00D20146634652415B10104601D32B
+:10B0E0004042002B00D54942704763465B1000D3B5
+:10B0F000404201B50020C046C04602BD70477047BF
+:10B10000704710B500F058F810BD30B58C180278B3
+:10B11000401C13071B0F01D10378401C120906D1F4
+:10B120000278401C03E00578401C0D70491C5B1E32
+:10B13000F9D101E00B70491C521EFBD1A142E6D3AC
+:10B14000002030BD012308CB134B1860134B19604E
+:10B15000134B1A607047134A134B13607246053A3B
+:10B16000F0E7114A0F4B1B689A420ED10D4B00209D
+:10B17000186001980D4B04B598470CBC9E460246DA
+:10B18000029800990A4B1B68184706980599094BC5
+:10B190001B68DB6818470000780100207C01002054
+:10B1A0008001002070010020EFBEADDE4D2F0000B9
+:10B1B00098000020040000201D481E497047FFF73A
+:10B1C000FBFFE5F7BBFF00BD01200007C06AC0B26E
+:10B1D000FF2804D1184819490968884202D0184844
+:10B1E00018490160184819490968884203D1184A6A
+:10B1F00013605B68184700BD20BFFDE71248134984
+:10B20000096888420ED1134B18680B498842F3D065
+:10B2100080F308881049884204DD10480268022142
+:10B220000A4302600E4880470E4880470E48004798
+:10B23000F0210020F0210020FFFFFFFF0010001090
+:10B240002C05004008000000001000000000002055
+:10B250000400002000C00100002000202405004060
+:10B26000632F0000C9B1010045B1010013487045CA
+:10B2700002D1EFF3098101E0EFF308818869023818
+:10B280000078102814DB202810DB2B280BDB0C4A5D
+:10B2900012680C4B9A4203D1602804DB0A4A10471B
+:10B2A000022008607047094A10470000084A10470A
+:10B2B000084A12682C32126810470000FDFFFFFF99
+:10B2C00064000020BEBAFECAAD120000991F010042
+:10B2D0001B1F0100040000200D4B0E4908470E4BB8
+:10B2E0000C4908470D4B0B4908470D4B09490847C6
+:10B2F0000C4B084908470C4B064908470B4B0549BE
+:10B3000008470B4B034908470A4B0249084700000E
+:10B31000B125000051220000D52B0000772A000043
+:10B32000252A0000D7270000B912000017140000DA
+:10B33000392B0000472300000A7802704B784370D5
+:10B340008A788270CA78C2700B79037170470A7864
+:10B3500002704B7843708A788270CA78C2700B7919
+:10B3600003714A79427170470A7802704B784370D2
+:10B370008A788270CA78C2700B7903714A794271F7
+:10B380008A798271CB79C37170470A8802804A88B2
+:10B3900042800A790271704730B47446641E257881
+:10B3A000641CAB4200D21D46635D5B00E31830BCF9
+:10B3B00018470000FFFFFFFF0000FFFF0100030030
+:10B3C000000001000000000000000000000000007C
+:10B3D00000000000870000000000000000000000E6
+:10B3E0000000000000000001020304000D0E0F1019
+:10B3F000000000000F6900002D6B0000F56B0000DD
+:10B400004F6C0000A36C00000B6D00006969000028
+:10B41000216A0000AD6D0000BB7900001001100131
+:10B420003A0200001A020000040104013C00170067
+:10B4300044000E00F401FA00960064004B00320054
+:10B440001E001400010204081020408055555525A7
+:10B450002627D6BE898E555555D6BE898E0000004A
+:10B460007006120DB413000014035A06A009000060
+:10B470006004F208840D0000A8B401000800002058
+:10B480001000000004110000B8B4010018000020F2
+:10B490006C0100000AB10100D8B401008401002051
+:10B4A0006C20000020110000024801688907FCD5CB
+:10B4B0007047000000E200E0013536010001005451
+:10B4C0003720FB349B5F80B4800010026801337F1B
+:08B4D0000102A029E449B101C9
+:00000001FF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/PeripheralNames.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,58 @@
+/* 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_PERIPHERALNAMES_H
+#define MBED_PERIPHERALNAMES_H
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STDIO_UART_TX     TX_PIN_NUMBER
+#define STDIO_UART_RX     RX_PIN_NUMBER
+#define STDIO_UART        UART_0
+
+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)NRF_ADC_BASE
+} ADCName;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/PortNames.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,30 @@
+/* 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_PORTNAMES_H
+#define MBED_PORTNAMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    Port0 = 0 //GPIO pins 0-31
+} PortName;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/PinNames.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,198 @@
+/* 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,  
+    
+    //NORMAL PINS...
+    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,
+
+    //PADS
+    PAD3 = p1,
+    PAD2 = p2,
+    PAD1 = p3,
+    
+
+    //LED MATRIX COLS
+    COL1 = p4,
+    COL2 = p5,
+    COL3 = p6,
+    COL4 = p7,
+    COL5 = p8,
+    COL6 = p9,
+    COL7 = p10,
+    COL8 = p11,
+    COL9 = p12,
+
+    //LED MATRIX ROWS
+    ROW1 = p13,
+    ROW2 = p14,
+    ROW3 = p15,
+
+    //NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
+    //PIN_16
+
+    // BUTTON A
+    BUTTON_A = p17,
+    
+
+    //NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
+    //PIN_18
+    
+    //TARGET RESET
+    TGT_NRESET = p19,
+
+    //NORMAL PIN (NO SPECIFIED FUNCTIONALITY)
+    //PIN_20
+
+    //MASTER OUT SLAVE IN
+    MOSI = p21,
+    
+    //MASTER IN SLAVE OUT
+    MISO = p22,
+
+    //SERIAL CLOCK
+    SCK = p23,
+
+    // RX AND TX PINS
+    TGT_TX = p24,
+    TGT_RX = p25,
+
+    //BUTTON B
+    BUTTON_B = p26,
+    
+    //ACCEL INTERRUPT PINS (MMA8653FC)
+    ACCEL_INT2 = p27,
+    ACCEL_INT1 = p28,
+
+    //MAGENETOMETER INTERRUPT PIN (MAG3110)
+    MAG_INT1 = p29,
+
+    // Not connected
+    NC = (int)0xFFFFFFFF,
+
+    RX_PIN_NUMBER = TGT_RX,
+    TX_PIN_NUMBER = TGT_TX,
+    CTS_PIN_NUMBER = 31, //unused  ** REQUIRES A PROPER FIX **
+    RTS_PIN_NUMBER = 31, //unused 
+
+    // mBed interface Pins
+    USBTX = TX_PIN_NUMBER,
+    USBRX = RX_PIN_NUMBER,
+
+    LED1    = PAD1,
+    LED2    = PAD2,
+    LED3    = PAD3,
+    LED4    = P0_16,
+
+    //SDA (SERIAL DATA LINE)
+    I2C_SDA0 = p30,
+
+    //SCL (SERIAL CLOCK LINE)
+    I2C_SCL0 = p0
+
+} PinName;
+
+typedef enum {
+    PullNone = 0,
+    PullDown = 1,
+    PullUp = 3,
+    PullDefault = PullUp
+} PinMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/device.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,57 @@
+/* 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
+
+#define DEVICE_PORTIN           1
+#define DEVICE_PORTOUT          1
+#define DEVICE_PORTINOUT        1
+
+#define DEVICE_INTERRUPTIN      1
+
+#define DEVICE_ANALOGIN         1
+#define DEVICE_ANALOGOUT        0
+
+#define DEVICE_SERIAL           1
+
+#define DEVICE_I2C              1
+#define DEVICE_I2CSLAVE         0
+
+#define DEVICE_SPI              1
+#define DEVICE_SPISLAVE         1
+
+#define DEVICE_CAN              0
+
+#define DEVICE_RTC              0
+
+#define DEVICE_ETHERNET         0
+
+#define DEVICE_PWMOUT           1
+
+#define DEVICE_SEMIHOST         0
+#define DEVICE_LOCALFILESYSTEM  0
+
+#define DEVICE_SLEEP            1
+
+#define DEVICE_DEBUG_AWARENESS  0
+
+#define DEVICE_STDIO_MESSAGES   0
+
+#define DEVICE_ERROR_PATTERN    1
+
+#include "objects.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_object.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,56 @@
+/* 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_GPIO_OBJECT_H
+#define MBED_GPIO_OBJECT_H
+
+#include "mbed_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PinName  pin;
+    uint32_t mask;
+
+    __IO uint32_t *reg_dir;
+    __IO uint32_t *reg_set;
+    __IO uint32_t *reg_clr;
+    __I  uint32_t *reg_in;
+} gpio_t;
+
+static inline void gpio_write(gpio_t *obj, int value) {
+    MBED_ASSERT(obj->pin != (PinName)NC);
+    if (value)
+        *obj->reg_set = obj->mask;
+    else
+        *obj->reg_clr = obj->mask;
+}
+
+static inline int gpio_read(gpio_t *obj) {
+    MBED_ASSERT(obj->pin != (PinName)NC);
+    return ((*obj->reg_in & obj->mask) ? 1 : 0);
+}
+
+static inline int gpio_is_connected(const gpio_t *obj) {
+    return obj->pin != (PinName)NC;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/objects.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,86 @@
+/* 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_OBJECTS_H
+#define MBED_OBJECTS_H
+
+#include "cmsis.h"
+#include "PortNames.h"
+#include "PeripheralNames.h"
+#include "PinNames.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define I2C_SPI_PERIPHERAL_FOR_I2C      1
+#define I2C_SPI_PERIPHERAL_FOR_SPI      2
+
+typedef struct {
+    uint8_t usage;   // I2C: 1, SPI: 2
+    uint8_t sda_mosi;
+    uint8_t scl_miso;
+    uint8_t sclk;
+} i2c_spi_peripheral_t;
+
+struct serial_s {
+    NRF_UART_Type *uart;
+    int index;
+};
+
+struct spi_s {
+    NRF_SPI_Type *spi;
+    NRF_SPIS_Type *spis;
+    uint8_t peripheral;
+};
+
+struct port_s {
+    __IO uint32_t *reg_cnf;
+    __IO uint32_t *reg_out;
+    __I  uint32_t *reg_in;
+    PortName port;
+    uint32_t mask;
+};
+
+struct pwmout_s {
+    PWMName pwm;
+    PinName pin;
+};
+
+struct i2c_s {
+    NRF_TWI_Type *i2c;
+    PinName sda;
+    PinName scl;
+    int freq;
+    uint8_t address_set;
+    uint8_t peripheral;
+};
+
+struct analogin_s {
+    ADCName adc;
+    uint8_t adc_pin;
+};
+
+struct gpio_irq_s {
+    uint32_t ch;
+};
+
+#include "gpio_object.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_config.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,20 @@
+/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+#ifndef TWI_MASTER_CONFIG
+#define TWI_MASTER_CONFIG
+
+#include "PinNames.h"
+
+#define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (I2C_SCL0)
+#define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (I2C_SDA0)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_master.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,108 @@
+ /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef TWI_MASTER_H
+#define TWI_MASTER_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/** @file
+* @brief Software controlled TWI Master driver.
+*
+*
+* @defgroup lib_driver_twi_master Software controlled TWI Master driver
+* @{
+* @ingroup nrf_drivers
+* @brief Software controlled TWI Master driver.
+*
+* Supported features:
+* - Repeated start
+* - No multi-master
+* - Only 7-bit addressing
+* - Supports clock stretching (with optional SMBus style slave timeout)
+* - Tries to handle slaves stuck in the middle of transfer
+*/
+
+#define TWI_READ_BIT                 (0x01)        //!< If this bit is set in the address field, transfer direction is from slave to master.
+
+#define TWI_ISSUE_STOP               ((bool)true)  //!< Parameter for @ref twi_master_transfer
+#define TWI_DONT_ISSUE_STOP          ((bool)false) //!< Parameter for @ref twi_master_transfer
+
+/* These macros are needed to see if the slave is stuck and we as master send dummy clock cycles to end its wait */
+/*lint -e717 -save "Suppress do {} while (0) for these macros" */
+/*lint ++flb "Enter library region" */
+#define TWI_SCL_HIGH()   do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0)   /*!< Pulls SCL line high */
+#define TWI_SCL_LOW()    do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0)   /*!< Pulls SCL line low  */
+#define TWI_SDA_HIGH()   do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER);  } while(0)   /*!< Pulls SDA line high */
+#define TWI_SDA_LOW()    do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER);  } while(0)   /*!< Pulls SDA line low  */
+#define TWI_SDA_INPUT()  do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER);  } while(0)   /*!< Configures SDA pin as input  */
+#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER);  } while(0)   /*!< Configures SDA pin as output */
+#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0)   /*!< Configures SCL pin as output */
+/*lint -restore */
+
+#define TWI_SDA_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_DATA_PIN_NUMBER) & 0x1UL)                     /*!< Reads current state of SDA */
+#define TWI_SCL_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL)                    /*!< Reads current state of SCL */
+
+#define TWI_DELAY() nrf_delay_us(4) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */
+
+
+/**
+ * @brief Function for initializing TWI bus IO pins and checks if the bus is operational.
+ *
+ * Both pins are configured as Standard-0, No-drive-1 (open drain).
+ *
+ * @return
+ * @retval true TWI bus is clear for transfers.
+ * @retval false TWI bus is stuck.
+ */
+bool twi_master_init_and_clear(void);
+
+/**
+ * @brief Function for transferring data over TWI bus.
+ *
+ * If TWI master detects even one NACK from the slave or timeout occurs, STOP condition is issued
+ * and the function returns false.
+ * Bit 0 (@ref TWI_READ_BIT) in the address parameter controls transfer direction;
+ * - If 1, master reads data_length number of bytes from the slave
+ * - If 0, master writes data_length number of bytes to the slave.
+ *
+ * @note Make sure at least data_length number of bytes is allocated in data if TWI_READ_BIT is set.
+ * @note @ref TWI_ISSUE_STOP
+ *
+ * @param address Data transfer direction (LSB) / Slave address (7 MSBs).
+ * @param data Pointer to data.
+ * @param data_length Number of bytes to transfer.
+ * @param issue_stop_condition If @ref TWI_ISSUE_STOP, STOP condition is issued before exiting function. If @ref TWI_DONT_ISSUE_STOP, STOP condition is not issued before exiting function. If transfer failed for any reason, STOP condition will be issued in any case.
+ * @return
+ * @retval true Data transfer succeeded without errors.
+ * @retval false Data transfer failed.
+ */
+bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bool issue_stop_condition);
+
+/**
+ *@}
+ **/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*lint --flb "Leave library region" */
+#endif //TWI_MASTER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/.archive_files.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1 @@
+"C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_irq_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/i2c_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/pinmap.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/port_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/pwmout_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/sleep.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/spi_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_master.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./BusIn.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./BusInOut.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./BusOut.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./CAN.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./CallChain.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Ethernet.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./FileBase.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./FileLike.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./FilePath.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./FileSystemLike.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./I2C.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./I2CSlave.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./InterruptIn.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./InterruptManager.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./LocalFileSystem.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./RawSerial.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./SPI.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./SPISlave.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Serial.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./SerialBase.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Stream.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Ticker.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Timeout.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./Timer.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./TimerEvent.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./assert.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./error.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./gpio.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./lp_ticker_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./mbed_interface.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./pinmap_common.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./rtc_time.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./semihost_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./ticker_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./us_ticker_api.o" "C:/Users/devinej/Desktop/mbed/.build/mbed/.temp/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/./wait_api.o"
\ No newline at end of file
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/board.o has changed
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/cmsis_nvic.o has changed
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/mbed.ar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/nRF51822.sct	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,24 @@
+;WITHOUT SOFTDEVICE:
+;LR_IROM1 0x00000000 0x00040000  {
+;  ER_IROM1 0x00000000 0x00040000  {
+;   *.o (RESET, +First)
+;   *(InRoot$$Sections)
+;   .ANY (+RO)
+;  }
+;  RW_IRAM1 0x20000000 0x00004000  {
+;   .ANY (+RW +ZI)
+;  }
+;}
+;
+;WITH SOFTDEVICE:
+
+LR_IROM1 0x18000 0x0028000  {
+  ER_IROM1 0x18000 0x0028000  {
+   *.o (RESET, +First)
+   *(InRoot$$Sections)
+   .ANY (+RO)
+  }
+  RW_IRAM1 0x20002000 0x00002000  {
+   .ANY (+RW +ZI)
+  }
+}
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/retarget.o has changed
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/startup_nRF51822.o has changed
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/sys.o has changed
Binary file microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/TOOLCHAIN_ARM_STD/system_nrf51.o has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/cmsis.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,13 @@
+/* mbed Microcontroller Library - CMSIS
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * A generic CMSIS include header, pulling in LPC407x_8x specifics
+ */
+
+#ifndef MBED_CMSIS_H
+#define MBED_CMSIS_H
+
+#include "nrf.h"
+#include "cmsis_nvic.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/cmsis_nvic.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,53 @@
+/* mbed Microcontroller Library
+ * CMSIS-style functionality to support dynamic vectors
+ *******************************************************************************
+ * Copyright (c) 2011 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 + 32)   // CORE + MCU Peripherals
+#define NVIC_USER_IRQ_OFFSET  16
+
+#include "nrf51.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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/compiler_abstraction.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,109 @@
+/* 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:
+ *
+ *   * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (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 _COMPILER_ABSTRACTION_H
+#define _COMPILER_ABSTRACTION_H
+
+/*lint ++flb "Enter library region" */
+
+#if defined ( __CC_ARM )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       /*!< asm keyword for ARM Compiler */
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            __inline                    /*!< inline keyword for ARM Compiler */
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      /*!< weak keyword for ARM Compiler */
+    #endif
+    
+    #define GET_SP()                __current_sp()              /*!> read current SP function for ARM Compiler */
+  
+#elif defined ( __ICCARM__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       /*!< asm keyword for IAR Compiler */
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      /*!> define weak function for IAR Compiler */
+    #endif
+    
+    #define GET_SP()                __get_SP()                  /*!> read current SP function for IAR Compiler */
+    
+#elif defined   ( __GNUC__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       /*!< asm keyword for GNU Compiler */
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      /*!< inline keyword for GNU Compiler */
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))       /*!< weak keyword for GNU Compiler */
+    #endif
+    
+    #define GET_SP()                gcc_current_sp()            /*!> read current SP function for GNU Compiler */
+
+    static inline unsigned int gcc_current_sp(void)
+    {
+        register unsigned sp asm("sp");
+        return sp;
+    }
+    
+#elif defined   ( __TASKING__ )
+        
+    #ifndef __ASM        
+        #define __ASM               __asm                       /*!< asm keyword for TASKING Compiler */
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      /*!< inline keyword for TASKING Compiler */
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))       /*!< weak keyword for TASKING Compiler */
+    #endif
+    
+    #define GET_SP()                __get_MSP()                 /*!> read current SP function for TASKING Compiler */
+    
+#endif
+
+/*lint --flb "Leave library region" */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_ca9.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,271 @@
+/**************************************************************************//**
+ * @file     core_ca9.h
+ * @brief    CMSIS Cortex-A9 Core Peripheral Access Layer Header File
+ * @version
+ * @date     25 March 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 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.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CA9_H_GENERIC
+#define __CORE_CA9_H_GENERIC
+
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_A9
+  @{
+ */
+
+/*  CMSIS CA9 definitions */
+#define __CA9_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CA9_CMSIS_VERSION_SUB   (0x10)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CA9_CMSIS_VERSION       ((__CA9_CMSIS_VERSION_MAIN << 16) | \
+                                    __CA9_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_A                (0x09)                                   /*!< Cortex-A Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+  #define __STATIC_ASM     static __asm
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+  #define __STATIC_ASM     static __asm
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+  #define __STATIC_ASM     static __asm
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+  #define __STATIC_ASM     static __asm
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+  #define __STATIC_ASM     static __asm
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+#endif
+
+#include <stdint.h>                      /*!< standard types definitions                      */
+#include "core_caInstr.h"                /*!< Core Instruction Access                         */
+#include "core_caFunc.h"                 /*!< Core Function Access                            */
+#include "core_cm4_simd.h"               /*!< Compiler specific SIMD Intrinsics               */
+
+#endif /* __CORE_CA9_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CA9_H_DEPENDANT
+#define __CORE_CA9_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CA9_REV
+    #define __CA9_REV               0x0000
+    #warning "__CA9_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             1
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    1
+  #endif
+
+  #if __Vendor_SysTickConfig == 0
+    #error "__Vendor_SysTickConfig set to 0, but vendor systick timer must be supplied for Cortex-A9"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_A9 */
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-A processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t reserved1:7;                /*!< bit: 20..23  Reserved                           */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */ 
+} APSR_Type;
+
+
+/*@} end of group CMSIS_CORE */
+
+/*@} end of CMSIS_Core_FPUFunctions */
+
+
+#endif /* __CORE_CA9_H_GENERIC */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_caFunc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1161 @@
+/**************************************************************************//**
+ * @file     core_caFunc.h
+ * @brief    CMSIS Cortex-A Core Function Access Header File
+ * @version  V3.10
+ * @date     9 May 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 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.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CAFUNC_H__
+#define __CORE_CAFUNC_H__
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_MON 0x16
+#define MODE_ABT 0x17
+#define MODE_HYP 0x1A
+#define MODE_UND 0x1B
+#define MODE_SYS 0x1F
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/** \brief  Get CPSR Register
+
+    This function returns the content of the CPSR Register.
+
+    \return               CPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_CPSR(void)
+{
+  register uint32_t __regCPSR          __ASM("cpsr");
+  return(__regCPSR);
+}
+
+/** \brief  Set Stack Pointer
+
+    This function assigns the given value to the current stack pointer.
+
+    \param [in]    topOfStack  Stack Pointer value to set
+ */
+register uint32_t __regSP              __ASM("sp");
+__STATIC_INLINE void __set_SP(uint32_t topOfStack)
+{
+    __regSP = topOfStack;
+}
+
+
+/** \brief  Get link register
+
+    This function returns the value of the link register
+
+    \return    Value of link register
+ */
+register uint32_t __reglr         __ASM("lr");
+__STATIC_INLINE uint32_t __get_LR(void)
+{
+  return(__reglr);
+}
+
+/** \brief  Set link register
+
+    This function sets the value of the link register
+
+    \param [in]    lr  LR value to set
+ */
+__STATIC_INLINE void __set_LR(uint32_t lr)
+{
+  __reglr = lr;
+}
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the USR/SYS Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
+ */
+__STATIC_ASM void __set_PSP(uint32_t topOfProcStack)
+{
+    ARM
+    PRESERVE8
+
+    BIC     R0, R0, #7  ;ensure stack is 8-byte aligned
+    MRS     R1, CPSR
+    CPS     #MODE_SYS   ;no effect in USR mode
+    MOV     SP, R0
+    MSR     CPSR_c, R1  ;no effect in USR mode
+    ISB
+    BX      LR
+
+}
+
+/** \brief  Set User Mode
+
+    This function changes the processor state to User Mode
+
+    \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
+ */
+__STATIC_ASM void __set_CPS_USR(void)
+{
+    ARM 
+
+    CPS  #MODE_USR  
+    BX   LR
+}
+
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+/** \brief  Get FPEXC
+
+    This function returns the current value of the Floating Point Exception Control register.
+
+    \return               Floating Point Exception Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPEXC(void)
+{
+#if (__FPU_PRESENT == 1)
+  register uint32_t __regfpexc         __ASM("fpexc");
+  return(__regfpexc);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPEXC
+
+    This function assigns the given value to the Floating Point Exception Control register.
+
+    \param [in]    fpscr  Floating Point Exception Control value to set
+ */
+__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
+{
+#if (__FPU_PRESENT == 1)
+  register uint32_t __regfpexc         __ASM("fpexc");
+  __regfpexc = (fpexc);
+#endif
+}
+
+/** \brief  Get CPACR
+
+    This function returns the current value of the Coprocessor Access Control register.
+
+    \return               Coprocessor Access Control register value
+ */
+__STATIC_INLINE uint32_t __get_CPACR(void)
+{
+    register uint32_t __regCPACR         __ASM("cp15:0:c1:c0:2");
+    return __regCPACR;
+}
+
+/** \brief  Set CPACR
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    cpacr  Coporcessor Acccess Control value to set
+ */
+__STATIC_INLINE void __set_CPACR(uint32_t cpacr)
+{
+    register uint32_t __regCPACR         __ASM("cp15:0:c1:c0:2");
+    __regCPACR = cpacr;
+    __ISB();
+}
+
+/** \brief  Get CBAR
+
+    This function returns the value of the Configuration Base Address register.
+
+    \return               Configuration Base Address register value
+ */
+__STATIC_INLINE uint32_t __get_CBAR() {
+    register uint32_t __regCBAR         __ASM("cp15:4:c15:c0:0");
+    return(__regCBAR);
+}
+
+/** \brief  Get TTBR0
+
+    This function returns the value of the Configuration Base Address register.
+
+    \return               Translation Table Base Register 0 value
+ */
+__STATIC_INLINE uint32_t __get_TTBR0() {
+    register uint32_t __regTTBR0        __ASM("cp15:0:c2:c0:0");
+    return(__regTTBR0);
+}
+
+/** \brief  Set TTBR0
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    ttbr0  Translation Table Base Register 0 value to set
+ */
+__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
+    register uint32_t __regTTBR0        __ASM("cp15:0:c2:c0:0");
+    __regTTBR0 = ttbr0;
+    __ISB();
+}
+
+/** \brief  Get DACR
+
+    This function returns the value of the Domain Access Control Register.
+
+    \return               Domain Access Control Register value
+ */
+__STATIC_INLINE uint32_t __get_DACR() {
+    register uint32_t __regDACR         __ASM("cp15:0:c3:c0:0");
+    return(__regDACR);
+}
+
+/** \brief  Set DACR
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    dacr   Domain Access Control Register value to set
+ */
+__STATIC_INLINE void __set_DACR(uint32_t dacr) {
+    register uint32_t __regDACR         __ASM("cp15:0:c3:c0:0");
+    __regDACR = dacr;
+    __ISB();
+}
+
+/******************************** Cache and BTAC enable  ****************************************************/
+
+/** \brief  Set SCTLR
+
+    This function assigns the given value to the System Control Register.
+
+    \param [in]    sctlr  System Control Register, value to set
+ */
+__STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
+{
+    register uint32_t __regSCTLR         __ASM("cp15:0:c1:c0:0");
+    __regSCTLR = sctlr;
+}
+
+/** \brief  Get SCTLR
+
+    This function returns the value of the System Control Register.
+
+    \return               System Control Register value
+ */
+__STATIC_INLINE uint32_t __get_SCTLR() {
+    register uint32_t __regSCTLR         __ASM("cp15:0:c1:c0:0");
+    return(__regSCTLR);
+}
+
+/** \brief  Enable Caches
+
+    Enable Caches
+ */
+__STATIC_INLINE void __enable_caches(void) {
+    // Set I bit 12 to enable I Cache
+    // Set C bit  2 to enable D Cache
+    __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2));
+}
+
+/** \brief  Disable Caches
+
+    Disable Caches
+ */
+__STATIC_INLINE void __disable_caches(void) {
+    // Clear I bit 12 to disable I Cache
+    // Clear C bit  2 to disable D Cache
+    __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2));
+    __ISB();
+}
+
+/** \brief  Enable BTAC
+
+    Enable BTAC
+ */
+__STATIC_INLINE void __enable_btac(void) {
+    // Set Z bit 11 to enable branch prediction
+    __set_SCTLR( __get_SCTLR() | (1 << 11));
+    __ISB();
+}
+
+/** \brief  Disable BTAC
+
+    Disable BTAC
+ */
+__STATIC_INLINE void __disable_btac(void) {
+    // Clear Z bit 11 to disable branch prediction
+    __set_SCTLR( __get_SCTLR() & ~(1 << 11));
+}
+
+
+/** \brief  Enable MMU
+
+    Enable MMU
+ */
+__STATIC_INLINE void __enable_mmu(void) {
+    // Set M bit 0 to enable the MMU
+    // Set AFE bit to enable simplified access permissions model
+    // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking
+    __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29));
+    __ISB();
+}
+
+/** \brief  Enable MMU
+
+    Enable MMU
+ */
+__STATIC_INLINE void __disable_mmu(void) {
+    // Clear M bit 0 to disable the MMU
+    __set_SCTLR( __get_SCTLR() & ~1);
+    __ISB();
+}
+
+/******************************** TLB maintenance operations ************************************************/
+/** \brief  Invalidate the whole tlb
+
+    TLBIALL. Invalidate the whole tlb
+ */
+
+__STATIC_INLINE void __ca9u_inv_tlb_all(void) {
+    register uint32_t __TLBIALL         __ASM("cp15:0:c8:c7:0");
+    __TLBIALL = 0;
+    __DSB();
+    __ISB();
+}
+
+/******************************** BTB maintenance operations ************************************************/
+/** \brief  Invalidate entire branch predictor array
+
+    BPIALL. Branch Predictor Invalidate All.
+ */
+
+__STATIC_INLINE void __v7_inv_btac(void) {
+    register uint32_t __BPIALL          __ASM("cp15:0:c7:c5:6");
+    __BPIALL  = 0;
+    __DSB();     //ensure completion of the invalidation
+    __ISB();     //ensure instruction fetch path sees new state
+}
+
+
+/******************************** L1 cache operations ******************************************************/
+
+/** \brief  Invalidate the whole I$
+
+    ICIALLU. Instruction Cache Invalidate All to PoU
+ */
+__STATIC_INLINE void __v7_inv_icache_all(void) {
+    register uint32_t __ICIALLU         __ASM("cp15:0:c7:c5:0");
+    __ICIALLU = 0;
+    __DSB();     //ensure completion of the invalidation
+    __ISB();     //ensure instruction fetch path sees new I cache state
+}
+
+/** \brief  Clean D$ by MVA
+
+    DCCMVAC. Data cache clean by MVA to PoC
+ */
+__STATIC_INLINE void __v7_clean_dcache_mva(void *va) {
+    register uint32_t __DCCMVAC         __ASM("cp15:0:c7:c10:1");
+    __DCCMVAC = (uint32_t)va;
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief  Invalidate D$ by MVA
+
+    DCIMVAC. Data cache invalidate by MVA to PoC
+ */
+__STATIC_INLINE void __v7_inv_dcache_mva(void *va) {
+    register uint32_t __DCIMVAC         __ASM("cp15:0:c7:c6:1");
+    __DCIMVAC = (uint32_t)va;
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief  Clean and Invalidate D$ by MVA
+
+    DCCIMVAC. Data cache clean and invalidate by MVA to PoC
+ */
+__STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) {
+    register uint32_t __DCCIMVAC        __ASM("cp15:0:c7:c14:1");
+    __DCCIMVAC = (uint32_t)va;
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief
+ * Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency.
+ */
+#pragma push
+#pragma arm
+__STATIC_ASM void __v7_all_cache(uint32_t op) {
+        ARM 
+
+        PUSH    {R4-R11}
+
+        MRC     p15, 1, R6, c0, c0, 1      // Read CLIDR
+        ANDS    R3, R6, #0x07000000        // Extract coherency level
+        MOV     R3, R3, LSR #23            // Total cache levels << 1
+        BEQ     Finished                   // If 0, no need to clean
+
+        MOV     R10, #0                    // R10 holds current cache level << 1
+Loop1   ADD     R2, R10, R10, LSR #1       // R2 holds cache "Set" position
+        MOV     R1, R6, LSR R2             // Bottom 3 bits are the Cache-type for this level
+        AND     R1, R1, #7                 // Isolate those lower 3 bits
+        CMP     R1, #2
+        BLT     Skip                       // No cache or only instruction cache at this level
+
+        MCR     p15, 2, R10, c0, c0, 0     // Write the Cache Size selection register
+        ISB                                // ISB to sync the change to the CacheSizeID reg
+        MRC     p15, 1, R1, c0, c0, 0      // Reads current Cache Size ID register
+        AND     R2, R1, #7                 // Extract the line length field
+        ADD     R2, R2, #4                 // Add 4 for the line length offset (log2 16 bytes)
+        LDR     R4, =0x3FF
+        ANDS    R4, R4, R1, LSR #3         // R4 is the max number on the way size (right aligned)
+        CLZ     R5, R4                     // R5 is the bit position of the way size increment
+        LDR     R7, =0x7FFF
+        ANDS    R7, R7, R1, LSR #13        // R7 is the max number of the index size (right aligned)
+
+Loop2   MOV     R9, R4                     // R9 working copy of the max way size (right aligned)
+
+Loop3   ORR     R11, R10, R9, LSL R5       // Factor in the Way number and cache number into R11
+        ORR     R11, R11, R7, LSL R2       // Factor in the Set number
+        CMP     R0, #0
+        BNE     Dccsw
+        MCR     p15, 0, R11, c7, c6, 2     // DCISW. Invalidate by Set/Way
+        B       cont
+Dccsw   CMP     R0, #1
+        BNE     Dccisw
+        MCR     p15, 0, R11, c7, c10, 2    // DCCSW. Clean by Set/Way
+        B       cont
+Dccisw  MCR     p15, 0, R11, c7, c14, 2    // DCCISW, Clean and Invalidate by Set/Way
+cont    SUBS    R9, R9, #1                 // Decrement the Way number
+        BGE     Loop3
+        SUBS    R7, R7, #1                 // Decrement the Set number
+        BGE     Loop2
+Skip    ADD     R10, R10, #2               // increment the cache number
+        CMP     R3, R10
+        BGT     Loop1
+
+Finished
+        DSB
+        POP    {R4-R11}
+        BX     lr
+
+}
+#pragma pop
+
+/** \brief  __v7_all_cache - helper function
+
+ */
+
+/** \brief  Invalidate the whole D$
+
+    DCISW. Invalidate by Set/Way
+ */
+
+__STATIC_INLINE void __v7_inv_dcache_all(void) {
+    __v7_all_cache(0);
+}
+
+/** \brief  Clean the whole D$
+
+    DCCSW. Clean by Set/Way
+ */
+
+__STATIC_INLINE void __v7_clean_dcache_all(void) {
+    __v7_all_cache(1);
+}
+
+/** \brief  Clean and invalidate the whole D$
+
+    DCCISW. Clean and Invalidate by Set/Way
+ */
+
+__STATIC_INLINE void __v7_clean_inv_dcache_all(void) {
+    __v7_all_cache(2);
+}
+
+#include "core_ca_mmu.h"
+
+#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
+
+#error IAR Compiler support not implemented for Cortex-A
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+
+/* GNU gcc specific functions */
+
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_MON 0x16
+#define MODE_ABT 0x17
+#define MODE_HYP 0x1A
+#define MODE_UND 0x1B
+#define MODE_SYS 0x1F
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+    __ASM volatile ("cpsie i");
+}
+
+/** \brief  Disable IRQ Interrupts
+
+  This function disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __disable_irq(void)
+{
+    uint32_t result;
+
+    __ASM volatile ("mrs %0, cpsr" : "=r" (result));
+    __ASM volatile ("cpsid i");
+    return(result & 0x80);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+#if 1
+    uint32_t result;
+
+    __ASM volatile ("mrs %0, apsr" : "=r" (result) );
+    return (result);
+#else
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+#endif
+}
+
+
+/** \brief  Get CPSR Register
+
+    This function returns the content of the CPSR Register.
+
+    \return               CPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPSR(void)
+{
+#if 1
+  register uint32_t __regCPSR;
+  __ASM volatile ("mrs %0, cpsr" : "=r" (__regCPSR));
+#else
+  register uint32_t __regCPSR          __ASM("cpsr");
+#endif
+  return(__regCPSR);
+}
+
+#if 0
+/** \brief  Set Stack Pointer
+
+    This function assigns the given value to the current stack pointer.
+
+    \param [in]    topOfStack  Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_SP(uint32_t topOfStack)
+{
+    register uint32_t __regSP       __ASM("sp");
+    __regSP = topOfStack;
+}
+#endif
+
+/** \brief  Get link register
+
+    This function returns the value of the link register
+
+    \return    Value of link register
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_LR(void)
+{
+  register uint32_t __reglr         __ASM("lr");
+  return(__reglr);
+}
+
+#if 0
+/** \brief  Set link register
+
+    This function sets the value of the link register
+
+    \param [in]    lr  LR value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_LR(uint32_t lr)
+{
+  register uint32_t __reglr         __ASM("lr");
+  __reglr = lr;
+}
+#endif
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the USR/SYS Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/** \brief  Set User Mode
+
+    This function changes the processor state to User Mode
+
+    \param [in]    topOfProcStack  USR/SYS Stack Pointer value to set
+ */
+extern void __set_CPS_USR(void);
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+#if 1
+    uint32_t result;
+
+    __ASM volatile ("vmrs %0, fpscr" : "=r" (result) );
+    return (result);
+#else
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#endif
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+#if 1
+    __ASM volatile ("vmsr fpscr, %0" : : "r" (fpscr) );
+#else
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+#endif
+}
+
+/** \brief  Get FPEXC
+
+    This function returns the current value of the Floating Point Exception Control register.
+
+    \return               Floating Point Exception Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPEXC(void)
+{
+#if (__FPU_PRESENT == 1)
+#if 1
+    uint32_t result;
+
+    __ASM volatile ("vmrs %0, fpexc" : "=r" (result));
+    return (result);
+#else
+  register uint32_t __regfpexc         __ASM("fpexc");
+  return(__regfpexc);
+#endif
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPEXC
+
+    This function assigns the given value to the Floating Point Exception Control register.
+
+    \param [in]    fpscr  Floating Point Exception Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
+{
+#if (__FPU_PRESENT == 1)
+#if 1
+    __ASM volatile ("vmsr fpexc, %0" : : "r" (fpexc));
+#else
+  register uint32_t __regfpexc         __ASM("fpexc");
+  __regfpexc = (fpexc);
+#endif
+#endif
+}
+
+/** \brief  Get CPACR
+
+    This function returns the current value of the Coprocessor Access Control register.
+
+    \return               Coprocessor Access Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CPACR(void)
+{
+#if 1
+    register uint32_t __regCPACR;
+    __ASM volatile ("mrc p15, 0, %0, c1, c0, 2" : "=r" (__regCPACR));
+#else
+    register uint32_t __regCPACR         __ASM("cp15:0:c1:c0:2");
+#endif
+    return __regCPACR;
+}
+
+/** \brief  Set CPACR
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    cpacr  Coporcessor Acccess Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CPACR(uint32_t cpacr)
+{
+#if 1
+    __ASM volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r" (cpacr));
+#else
+    register uint32_t __regCPACR         __ASM("cp15:0:c1:c0:2");
+    __regCPACR = cpacr;
+#endif
+    __ISB();
+}
+
+/** \brief  Get CBAR
+
+    This function returns the value of the Configuration Base Address register.
+
+    \return               Configuration Base Address register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CBAR() {
+#if 1
+    register uint32_t __regCBAR;
+    __ASM volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r" (__regCBAR));
+#else
+    register uint32_t __regCBAR         __ASM("cp15:4:c15:c0:0");
+#endif
+    return(__regCBAR);
+}
+
+/** \brief  Get TTBR0
+
+    This function returns the value of the Configuration Base Address register.
+
+    \return               Translation Table Base Register 0 value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_TTBR0() {
+#if 1
+    register uint32_t __regTTBR0;
+    __ASM volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (__regTTBR0));
+#else
+    register uint32_t __regTTBR0        __ASM("cp15:0:c2:c0:0");
+#endif
+    return(__regTTBR0);
+}
+
+/** \brief  Set TTBR0
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    ttbr0  Translation Table Base Register 0 value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r" (ttbr0));
+#else
+    register uint32_t __regTTBR0        __ASM("cp15:0:c2:c0:0");
+    __regTTBR0 = ttbr0;
+#endif
+    __ISB();
+}
+
+/** \brief  Get DACR
+
+    This function returns the value of the Domain Access Control Register.
+
+    \return               Domain Access Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_DACR() {
+#if 1
+    register uint32_t __regDACR;
+    __ASM volatile ("mrc p15, 0, %0, c3, c0, 0" : "=r" (__regDACR));
+#else
+    register uint32_t __regDACR         __ASM("cp15:0:c3:c0:0");
+#endif
+    return(__regDACR);
+}
+
+/** \brief  Set DACR
+
+    This function assigns the given value to the Coprocessor Access Control register.
+
+    \param [in]    dacr   Domain Access Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_DACR(uint32_t dacr) {
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r" (dacr));
+#else
+    register uint32_t __regDACR         __ASM("cp15:0:c3:c0:0");
+    __regDACR = dacr;
+#endif
+    __ISB();
+}
+
+/******************************** Cache and BTAC enable  ****************************************************/
+
+/** \brief  Set SCTLR
+
+    This function assigns the given value to the System Control Register.
+
+    \param [in]    sctlr  System Control Register, value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
+{
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r" (sctlr));
+#else
+    register uint32_t __regSCTLR         __ASM("cp15:0:c1:c0:0");
+    __regSCTLR = sctlr;
+#endif
+}
+
+/** \brief  Get SCTLR
+
+    This function returns the value of the System Control Register.
+
+    \return               System Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_SCTLR() {
+#if 1
+	register uint32_t __regSCTLR;
+	__ASM volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (__regSCTLR));
+#else
+    register uint32_t __regSCTLR         __ASM("cp15:0:c1:c0:0");
+#endif
+    return(__regSCTLR);
+}
+
+/** \brief  Enable Caches
+
+    Enable Caches
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_caches(void) {
+    // Set I bit 12 to enable I Cache
+    // Set C bit  2 to enable D Cache
+    __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2));
+}
+
+/** \brief  Disable Caches
+
+    Disable Caches
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_caches(void) {
+    // Clear I bit 12 to disable I Cache
+    // Clear C bit  2 to disable D Cache
+    __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2));
+    __ISB();
+}
+
+/** \brief  Enable BTAC
+
+    Enable BTAC
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_btac(void) {
+    // Set Z bit 11 to enable branch prediction
+    __set_SCTLR( __get_SCTLR() | (1 << 11));
+    __ISB();
+}
+
+/** \brief  Disable BTAC
+
+    Disable BTAC
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_btac(void) {
+    // Clear Z bit 11 to disable branch prediction
+    __set_SCTLR( __get_SCTLR() & ~(1 << 11));
+}
+
+
+/** \brief  Enable MMU
+
+    Enable MMU
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_mmu(void) {
+    // Set M bit 0 to enable the MMU
+    // Set AFE bit to enable simplified access permissions model
+    // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking
+    __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29));
+    __ISB();
+}
+
+/** \brief  Enable MMU
+
+    Enable MMU
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_mmu(void) {
+    // Clear M bit 0 to disable the MMU
+    __set_SCTLR( __get_SCTLR() & ~1);
+    __ISB();
+}
+
+/******************************** TLB maintenance operations ************************************************/
+/** \brief  Invalidate the whole tlb
+
+    TLBIALL. Invalidate the whole tlb
+ */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ca9u_inv_tlb_all(void) {
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+#else
+    register uint32_t __TLBIALL         __ASM("cp15:0:c8:c7:0");
+    __TLBIALL = 0;
+#endif
+    __DSB();
+    __ISB();
+}
+
+/******************************** BTB maintenance operations ************************************************/
+/** \brief  Invalidate entire branch predictor array
+
+    BPIALL. Branch Predictor Invalidate All.
+ */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_btac(void) {
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
+#else
+    register uint32_t __BPIALL          __ASM("cp15:0:c7:c5:6");
+    __BPIALL  = 0;
+#endif
+    __DSB();     //ensure completion of the invalidation
+    __ISB();     //ensure instruction fetch path sees new state
+}
+
+
+/******************************** L1 cache operations ******************************************************/
+
+/** \brief  Invalidate the whole I$
+
+    ICIALLU. Instruction Cache Invalidate All to PoU
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_icache_all(void) {
+#if 1
+	__ASM volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+#else
+    register uint32_t __ICIALLU         __ASM("cp15:0:c7:c5:0");
+    __ICIALLU = 0;
+#endif
+    __DSB();     //ensure completion of the invalidation
+    __ISB();     //ensure instruction fetch path sees new I cache state
+}
+
+/** \brief  Clean D$ by MVA
+
+    DCCMVAC. Data cache clean by MVA to PoC
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_dcache_mva(void *va) {
+#if 1
+    __ASM volatile ("mcr p15, 0, %0, c7, c10, 1" : : "r" ((uint32_t)va));
+#else
+    register uint32_t __DCCMVAC         __ASM("cp15:0:c7:c10:1");
+    __DCCMVAC = (uint32_t)va;
+#endif
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief  Invalidate D$ by MVA
+
+    DCIMVAC. Data cache invalidate by MVA to PoC
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_dcache_mva(void *va) {
+#if 1
+    __ASM volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" ((uint32_t)va));
+#else
+    register uint32_t __DCIMVAC         __ASM("cp15:0:c7:c6:1");
+    __DCIMVAC = (uint32_t)va;
+#endif
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief  Clean and Invalidate D$ by MVA
+
+    DCCIMVAC. Data cache clean and invalidate by MVA to PoC
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) {
+#if 1
+    __ASM volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" ((uint32_t)va));
+#else
+    register uint32_t __DCCIMVAC        __ASM("cp15:0:c7:c14:1");
+    __DCCIMVAC = (uint32_t)va;
+#endif
+    __DMB();     //ensure the ordering of data cache maintenance operations and their effects
+}
+
+/** \brief
+ * Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency.
+ */
+
+/** \brief  __v7_all_cache - helper function
+
+ */
+
+extern void __v7_all_cache(uint32_t op);
+
+
+/** \brief  Invalidate the whole D$
+
+    DCISW. Invalidate by Set/Way
+ */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_inv_dcache_all(void) {
+    __v7_all_cache(0);
+}
+
+/** \brief  Clean the whole D$
+
+    DCCSW. Clean by Set/Way
+ */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_dcache_all(void) {
+    __v7_all_cache(1);
+}
+
+/** \brief  Clean and invalidate the whole D$
+
+    DCCISW. Clean and Invalidate by Set/Way
+ */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __v7_clean_inv_dcache_all(void) {
+    __v7_all_cache(2);
+}
+
+#include "core_ca_mmu.h"
+
+#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
+
+#error TASKING Compiler support not implemented for Cortex-A
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CAFUNC_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_caInstr.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,45 @@
+/**************************************************************************//**
+ * @file     core_caInstr.h
+ * @brief    CMSIS Cortex-A9 Core Peripheral Access Layer Header File
+ * @version
+ * @date     04. December 2012
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 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.
+   ---------------------------------------------------------------------------*/
+
+#ifndef __CORE_CAINSTR_H__
+#define __CORE_CAINSTR_H__
+
+#define __CORTEX_M 0x3
+#include "core_cmInstr.h"
+#undef  __CORTEX_M
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_ca_mmu.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,848 @@
+;/**************************************************************************//**
+; * @file     core_ca_mmu.h
+; * @brief    MMU Startup File for
+; *           VE_A9_MP Device Series
+; * @version  V1.01
+; * @date     25 March 2013
+; *
+; * @note
+; *
+; ******************************************************************************/
+;/* 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.
+;   ---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef _MMU_FUNC_H
+#define _MMU_FUNC_H
+
+#define SECTION_DESCRIPTOR      (0x2)
+#define SECTION_MASK            (0xFFFFFFFC)
+
+#define SECTION_TEXCB_MASK      (0xFFFF8FF3)
+#define SECTION_B_SHIFT         (2)
+#define SECTION_C_SHIFT         (3)
+#define SECTION_TEX0_SHIFT      (12)
+#define SECTION_TEX1_SHIFT      (13)
+#define SECTION_TEX2_SHIFT      (14)
+
+#define SECTION_XN_MASK         (0xFFFFFFEF)
+#define SECTION_XN_SHIFT        (4)
+
+#define SECTION_DOMAIN_MASK     (0xFFFFFE1F)
+#define SECTION_DOMAIN_SHIFT    (5)
+
+#define SECTION_P_MASK          (0xFFFFFDFF)
+#define SECTION_P_SHIFT         (9)
+
+#define SECTION_AP_MASK         (0xFFFF73FF)
+#define SECTION_AP_SHIFT        (10)
+#define SECTION_AP2_SHIFT       (15)
+
+#define SECTION_S_MASK          (0xFFFEFFFF)
+#define SECTION_S_SHIFT         (16)
+
+#define SECTION_NG_MASK         (0xFFFDFFFF)
+#define SECTION_NG_SHIFT        (17)
+
+#define SECTION_NS_MASK         (0xFFF7FFFF)
+#define SECTION_NS_SHIFT        (19)
+
+
+#define PAGE_L1_DESCRIPTOR      (0x1)
+#define PAGE_L1_MASK            (0xFFFFFFFC)
+
+#define PAGE_L2_4K_DESC         (0x2)
+#define PAGE_L2_4K_MASK         (0xFFFFFFFD)
+
+#define PAGE_L2_64K_DESC        (0x1)
+#define PAGE_L2_64K_MASK        (0xFFFFFFFC)
+
+#define PAGE_4K_TEXCB_MASK      (0xFFFFFE33)
+#define PAGE_4K_B_SHIFT         (2)
+#define PAGE_4K_C_SHIFT         (3)
+#define PAGE_4K_TEX0_SHIFT      (6)
+#define PAGE_4K_TEX1_SHIFT      (7)
+#define PAGE_4K_TEX2_SHIFT      (8)
+
+#define PAGE_64K_TEXCB_MASK     (0xFFFF8FF3)
+#define PAGE_64K_B_SHIFT        (2)
+#define PAGE_64K_C_SHIFT        (3)
+#define PAGE_64K_TEX0_SHIFT     (12)
+#define PAGE_64K_TEX1_SHIFT     (13)
+#define PAGE_64K_TEX2_SHIFT     (14)
+
+#define PAGE_TEXCB_MASK         (0xFFFF8FF3)
+#define PAGE_B_SHIFT            (2)
+#define PAGE_C_SHIFT            (3)
+#define PAGE_TEX_SHIFT          (12)
+
+#define PAGE_XN_4K_MASK         (0xFFFFFFFE)
+#define PAGE_XN_4K_SHIFT        (0)
+#define PAGE_XN_64K_MASK        (0xFFFF7FFF)
+#define PAGE_XN_64K_SHIFT       (15)
+
+
+#define PAGE_DOMAIN_MASK        (0xFFFFFE1F)
+#define PAGE_DOMAIN_SHIFT       (5)
+
+#define PAGE_P_MASK             (0xFFFFFDFF)
+#define PAGE_P_SHIFT            (9)
+
+#define PAGE_AP_MASK            (0xFFFFFDCF)
+#define PAGE_AP_SHIFT           (4)
+#define PAGE_AP2_SHIFT          (9)
+
+#define PAGE_S_MASK             (0xFFFFFBFF)
+#define PAGE_S_SHIFT            (10)
+
+#define PAGE_NG_MASK            (0xFFFFF7FF)
+#define PAGE_NG_SHIFT           (11)
+
+#define PAGE_NS_MASK            (0xFFFFFFF7)
+#define PAGE_NS_SHIFT           (3)
+
+#define OFFSET_1M               (0x00100000)
+#define OFFSET_64K              (0x00010000)
+#define OFFSET_4K               (0x00001000)
+
+#define DESCRIPTOR_FAULT        (0x00000000)
+
+/* ###########################  MMU Function Access  ########################### */
+/** \ingroup  MMU_FunctionInterface
+    \defgroup MMU_Functions MMU Functions Interface
+  @{
+ */
+
+/* Attributes enumerations */
+
+/* Region size attributes */
+typedef enum
+{
+   SECTION,
+   PAGE_4k,
+   PAGE_64k,
+} mmu_region_size_Type;
+
+/* Region type attributes */
+typedef enum
+{
+   NORMAL,
+   DEVICE,
+   SHARED_DEVICE,
+   NON_SHARED_DEVICE,
+   STRONGLY_ORDERED
+} mmu_memory_Type;
+
+/* Region cacheability attributes */
+typedef enum
+{
+   NON_CACHEABLE,
+   WB_WA,
+   WT,
+   WB_NO_WA,
+} mmu_cacheability_Type;
+
+/* Region parity check attributes */
+typedef enum
+{
+   ECC_DISABLED,
+   ECC_ENABLED,
+} mmu_ecc_check_Type;
+
+/* Region execution attributes */
+typedef enum
+{
+   EXECUTE,
+   NON_EXECUTE,
+} mmu_execute_Type;
+
+/* Region global attributes */
+typedef enum
+{
+   GLOBAL,
+   NON_GLOBAL,
+} mmu_global_Type;
+
+/* Region shareability attributes */
+typedef enum
+{
+   NON_SHARED,
+   SHARED,
+} mmu_shared_Type;
+
+/* Region security attributes */
+typedef enum
+{
+   SECURE,
+   NON_SECURE,
+} mmu_secure_Type;
+
+/* Region access attributes */
+typedef enum
+{
+   NO_ACCESS,
+   RW,
+   READ,
+} mmu_access_Type;
+
+/* Memory Region definition */
+typedef struct RegionStruct {
+    mmu_region_size_Type rg_t;
+    mmu_memory_Type mem_t;
+    uint8_t domain;
+    mmu_cacheability_Type inner_norm_t;
+    mmu_cacheability_Type outer_norm_t;
+    mmu_ecc_check_Type e_t;
+    mmu_execute_Type xn_t;
+    mmu_global_Type g_t;
+    mmu_secure_Type sec_t;
+    mmu_access_Type priv_t;
+    mmu_access_Type user_t;
+    mmu_shared_Type sh_t;
+
+} mmu_region_attributes_Type;
+
+/** \brief  Set section execution-never attribute
+
+    The function sets section execution-never attribute
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]                xn  Section execution-never attribute : EXECUTE , NON_EXECUTE.
+
+    \return          0  
+ */
+__STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn)
+{
+    *descriptor_l1 &= SECTION_XN_MASK;
+    *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT);
+    return 0;
+}
+
+/** \brief  Set section domain
+
+    The function sets section domain
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]            domain  Section domain
+
+    \return          0  
+ */
+__STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain)
+{
+    *descriptor_l1 &= SECTION_DOMAIN_MASK;
+    *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT);
+    return 0;
+}
+
+/** \brief  Set section parity check
+
+    The function sets section parity check
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]              p_bit Parity check: ECC_DISABLED, ECC_ENABLED
+
+    \return          0  
+ */
+__STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
+{
+    *descriptor_l1 &= SECTION_P_MASK;
+    *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
+    return 0;
+}
+
+/** \brief  Set section access privileges
+
+    The function sets section access privileges
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]              user  User Level Access: NO_ACCESS, RW, READ
+    \param [in]              priv  Privilege Level Access: NO_ACCESS, RW, READ
+    \param [in]               afe  Access flag enable
+
+    \return          0  
+ */
+__STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv,  uint32_t afe)
+{
+    uint32_t ap = 0;
+
+    if (afe == 0) { //full access
+        if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
+        else if ((priv == RW) && (user == NO_ACCESS))   { ap = 0x1; }
+        else if ((priv == RW) && (user == READ))        { ap = 0x2; }
+        else if ((priv == RW) && (user == RW))          { ap = 0x3; }
+        else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
+        else if ((priv == READ) && (user == READ))      { ap = 0x6; }
+    }
+
+    else { //Simplified access
+        if ((priv == RW) && (user == NO_ACCESS))        { ap = 0x1; }
+        else if ((priv == RW) && (user == RW))          { ap = 0x3; }
+        else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
+        else if ((priv == READ) && (user == READ))      { ap = 0x7; }
+    }
+
+    *descriptor_l1 &= SECTION_AP_MASK;
+    *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT;
+    *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT;
+
+    return 0;
+}
+
+/** \brief  Set section shareability
+
+    The function sets section shareability
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]             s_bit  Section shareability: NON_SHARED, SHARED
+
+    \return          0  
+ */
+__STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit)
+{
+    *descriptor_l1 &= SECTION_S_MASK;
+    *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT);
+    return 0;
+}
+
+/** \brief  Set section Global attribute
+
+    The function sets section Global attribute
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]             g_bit  Section attribute: GLOBAL, NON_GLOBAL
+
+    \return          0  
+ */
+__STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit)
+{
+    *descriptor_l1 &= SECTION_NG_MASK;
+    *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT);
+    return 0;
+}
+
+/** \brief  Set section Security attribute
+
+    The function sets section Global attribute
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]             s_bit  Section Security attribute: SECURE, NON_SECURE
+
+    \return          0  
+ */
+__STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
+{
+    *descriptor_l1 &= SECTION_NS_MASK;
+    *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT);
+    return 0;
+}
+
+/* Page 4k or 64k */
+/** \brief  Set 4k/64k page execution-never attribute
+
+    The function sets 4k/64k page execution-never attribute
+
+    \param [out]    descriptor_l2  L2 descriptor.
+    \param [in]                xn  Page execution-never attribute : EXECUTE , NON_EXECUTE.
+    \param [in]              page  Page size: PAGE_4k, PAGE_64k,
+   
+    \return          0  
+ */
+__STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page)
+{
+    if (page == PAGE_4k)
+    {
+        *descriptor_l2 &= PAGE_XN_4K_MASK;
+        *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT);
+    }
+    else
+    {
+        *descriptor_l2 &= PAGE_XN_64K_MASK;
+        *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT);
+    }
+    return 0;
+}
+
+/** \brief  Set 4k/64k page domain
+
+    The function sets 4k/64k page domain
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]            domain  Page domain
+
+    \return          0  
+ */
+__STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain)
+{
+    *descriptor_l1 &= PAGE_DOMAIN_MASK;
+    *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT);
+    return 0;
+}
+
+/** \brief  Set 4k/64k page parity check
+
+    The function sets 4k/64k page parity check
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]              p_bit Parity check: ECC_DISABLED, ECC_ENABLED
+
+    \return          0  
+ */
+__STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
+{
+    *descriptor_l1 &= SECTION_P_MASK;
+    *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
+    return 0;
+}
+
+/** \brief  Set 4k/64k page access privileges
+
+    The function sets 4k/64k page access privileges
+
+    \param [out]    descriptor_l2  L2 descriptor.
+    \param [in]              user  User Level Access: NO_ACCESS, RW, READ
+    \param [in]              priv  Privilege Level Access: NO_ACCESS, RW, READ
+    \param [in]               afe  Access flag enable
+
+    \return          0  
+ */
+__STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv,  uint32_t afe)
+{
+    uint32_t ap = 0;
+
+    if (afe == 0) { //full access
+        if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
+        else if ((priv == RW) && (user == NO_ACCESS))   { ap = 0x1; }
+        else if ((priv == RW) && (user == READ))        { ap = 0x2; }
+        else if ((priv == RW) && (user == RW))          { ap = 0x3; }
+        else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
+        else if ((priv == READ) && (user == READ))      { ap = 0x6; }
+    }
+
+    else { //Simplified access
+        if ((priv == RW) && (user == NO_ACCESS))        { ap = 0x1; }
+        else if ((priv == RW) && (user == RW))          { ap = 0x3; }
+        else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
+        else if ((priv == READ) && (user == READ))      { ap = 0x7; }
+    }
+
+    *descriptor_l2 &= PAGE_AP_MASK;
+    *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT;
+    *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT;
+
+    return 0;
+}
+
+/** \brief  Set 4k/64k page shareability
+
+    The function sets 4k/64k page shareability
+
+    \param [out]    descriptor_l2  L2 descriptor.
+    \param [in]             s_bit  4k/64k page shareability: NON_SHARED, SHARED
+
+    \return          0  
+ */
+__STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit)
+{
+    *descriptor_l2 &= PAGE_S_MASK;
+    *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT);
+    return 0;
+}
+
+/** \brief  Set 4k/64k page Global attribute
+
+    The function sets 4k/64k page Global attribute
+
+    \param [out]    descriptor_l2  L2 descriptor.
+    \param [in]             g_bit  4k/64k page attribute: GLOBAL, NON_GLOBAL
+
+    \return          0  
+ */
+__STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit)
+{
+    *descriptor_l2 &= PAGE_NG_MASK;
+    *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT);
+    return 0;
+}
+
+/** \brief  Set 4k/64k page Security attribute
+
+    The function sets 4k/64k page Global attribute
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]             s_bit  4k/64k page Security attribute: SECURE, NON_SECURE
+
+    \return          0  
+ */
+__STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
+{
+    *descriptor_l1 &= PAGE_NS_MASK;
+    *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT);
+    return 0;
+}
+
+
+/** \brief  Set Section memory attributes
+
+    The function sets section memory attributes
+
+    \param [out]    descriptor_l1  L1 descriptor.
+    \param [in]               mem  Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
+    \param [in]             outer  Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
+    \param [in]             inner  Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
+
+    \return          0  
+ */
+__STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner)
+{
+    *descriptor_l1 &= SECTION_TEXCB_MASK;
+
+    if (STRONGLY_ORDERED == mem)
+    {
+        return 0;
+    }
+    else if (SHARED_DEVICE == mem)
+    {
+        *descriptor_l1 |= (1 << SECTION_B_SHIFT);
+    }
+    else if (NON_SHARED_DEVICE == mem)
+    {
+        *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT);
+    }
+    else if (NORMAL == mem)
+    {
+           *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT;
+           switch(inner)
+           {
+            case NON_CACHEABLE:
+            break;
+            case WB_WA:
+                *descriptor_l1 |= (1 << SECTION_B_SHIFT);
+                break;
+            case WT:
+                *descriptor_l1 |= 1 << SECTION_C_SHIFT;
+                break;
+            case WB_NO_WA:
+                *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT);
+                break;
+        }
+        switch(outer)
+        {
+            case NON_CACHEABLE:
+             break;
+            case WB_WA:
+                *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT);
+                break;
+            case WT:
+                *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT;
+                break;
+            case WB_NO_WA:
+                *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT);
+                break;
+        }
+    }
+
+    return 0;
+}
+
+/** \brief  Set 4k/64k page memory attributes
+
+    The function sets 4k/64k page memory attributes
+
+    \param [out]    descriptor_l2  L2 descriptor.
+    \param [in]               mem  4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
+    \param [in]             outer  Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
+    \param [in]             inner  Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
+
+    \return          0  
+ */
+__STATIC_INLINE int __memory_page(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page)
+{
+    *descriptor_l2 &= PAGE_4K_TEXCB_MASK;
+
+    if (page == PAGE_64k)
+    {
+        //same as section
+        __memory_section(descriptor_l2, mem, outer, inner);
+    }
+    else
+    {
+        if (STRONGLY_ORDERED == mem)
+        {
+            return 0;
+        }
+        else if (SHARED_DEVICE == mem)
+        {
+            *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
+        }
+        else if (NON_SHARED_DEVICE == mem)
+        {
+             *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT);
+        }
+        else if (NORMAL == mem)
+        {
+            *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT;
+            switch(inner)
+            {
+                case NON_CACHEABLE:
+                break;
+                case WB_WA:
+                     *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
+                     break;
+                case WT:
+                    *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT;
+                     break;
+                case WB_NO_WA:
+                    *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT);
+                    break;
+            }
+            switch(outer)
+            {
+                case NON_CACHEABLE:
+                break;
+                case WB_WA:
+                      *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT);
+                    break;
+                case WT:
+                     *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT;
+                    break;
+                case WB_NO_WA:
+                    *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT);
+                    break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/** \brief  Create a L1 section descriptor
+
+    The function creates a section descriptor.
+    
+    Assumptions:
+    - 16MB super sections not suported
+    - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
+    - Functions always return 0
+
+    \param [out]       descriptor  L1 descriptor
+    \param [out]      descriptor2  L2 descriptor
+    \param [in]               reg  Section attributes
+
+    \return          0  
+ */
+__STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg)
+{
+    *descriptor  = 0;
+
+   __memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t);
+   __xn_section(descriptor,reg.xn_t);
+   __domain_section(descriptor, reg.domain);
+   __p_section(descriptor, reg.e_t);
+   __ap_section(descriptor, reg.priv_t, reg.user_t, 1);
+   __shared_section(descriptor,reg.sh_t);
+   __global_section(descriptor,reg.g_t);
+   __secure_section(descriptor,reg.sec_t);
+   *descriptor &= SECTION_MASK;
+   *descriptor |= SECTION_DESCRIPTOR;
+
+   return 0;
+
+}
+
+
+/** \brief  Create a L1 and L2 4k/64k page descriptor
+
+    The function creates a 4k/64k page descriptor.
+    Assumptions:
+    - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
+    - Functions always return 0
+
+    \param [out]       descriptor  L1 descriptor
+    \param [out]      descriptor2  L2 descriptor
+    \param [in]               reg  4k/64k page attributes
+
+    \return          0  
+ */
+__STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg)
+{
+    *descriptor  = 0;
+    *descriptor2 = 0;
+
+    switch (reg.rg_t)
+    {
+        case PAGE_4k:
+            __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k);
+            __xn_page(descriptor2, reg.xn_t, PAGE_4k);
+            __domain_page(descriptor, reg.domain);
+            __p_page(descriptor, reg.e_t);
+            __ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
+            __shared_page(descriptor2,reg.sh_t);
+            __global_page(descriptor2,reg.g_t);
+            __secure_page(descriptor,reg.sec_t);
+            *descriptor &= PAGE_L1_MASK;
+            *descriptor |= PAGE_L1_DESCRIPTOR;
+            *descriptor2 &= PAGE_L2_4K_MASK;
+            *descriptor2 |= PAGE_L2_4K_DESC;
+            break;
+
+        case PAGE_64k:
+            __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k);
+            __xn_page(descriptor2, reg.xn_t, PAGE_64k);
+            __domain_page(descriptor, reg.domain);
+            __p_page(descriptor, reg.e_t);
+            __ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
+            __shared_page(descriptor2,reg.sh_t);
+            __global_page(descriptor2,reg.g_t);
+            __secure_page(descriptor,reg.sec_t);
+            *descriptor &= PAGE_L1_MASK;
+            *descriptor |= PAGE_L1_DESCRIPTOR;
+            *descriptor2 &= PAGE_L2_64K_MASK;
+            *descriptor2 |= PAGE_L2_64K_DESC;
+            break;
+
+        case SECTION:
+            //error
+            break;    
+
+    }
+
+   return 0;
+
+}
+
+/** \brief  Create a 1MB Section
+
+    \param [in]               ttb  Translation table base address
+    \param [in]      base_address  Section base address
+    \param [in]             count  Number of sections to create
+    \param [in]     descriptor_l1  L1 descriptor (region attributes) 
+
+ */
+__STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1)
+{
+    uint32_t offset;
+    uint32_t entry;
+    uint32_t i;
+
+    offset = base_address >> 20;
+    entry  = (base_address & 0xFFF00000) | descriptor_l1;
+
+    //4 bytes aligned
+    ttb = ttb + offset;
+
+    for (i = 0; i < count; i++ )
+    {
+        //4 bytes aligned
+       *ttb++ = entry;
+       entry += OFFSET_1M;
+    }
+}
+
+/** \brief  Create a 4k page entry
+
+    \param [in]               ttb  L1 table base address
+    \param [in]      base_address  4k base address
+    \param [in]             count  Number of 4k pages to create
+    \param [in]     descriptor_l1  L1 descriptor (region attributes) 
+    \param [in]            ttb_l2  L2 table base address
+    \param [in]     descriptor_l2  L2 descriptor (region attributes) 
+
+ */
+__STATIC_INLINE void __TTPage_4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
+{
+
+    uint32_t offset, offset2;
+    uint32_t entry, entry2;
+    uint32_t i;
+
+
+    offset = base_address >> 20;
+    entry  = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
+
+    //4 bytes aligned
+    ttb += offset;
+    //create l1_entry
+    *ttb = entry;
+
+    offset2 = (base_address & 0xff000) >> 12;
+    ttb_l2 += offset2;
+    entry2 = (base_address & 0xFFFFF000) | descriptor_l2;
+    for (i = 0; i < count; i++ )
+    {
+        //4 bytes aligned
+       *ttb_l2++ = entry2;
+       entry2 += OFFSET_4K;
+    }
+}
+
+/** \brief  Create a 64k page entry
+
+    \param [in]               ttb  L1 table base address
+    \param [in]      base_address  64k base address
+    \param [in]             count  Number of 64k pages to create
+    \param [in]     descriptor_l1  L1 descriptor (region attributes) 
+    \param [in]            ttb_l2  L2 table base address
+    \param [in]     descriptor_l2  L2 descriptor (region attributes) 
+
+ */
+__STATIC_INLINE void __TTPage_64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
+{
+    uint32_t offset, offset2;
+    uint32_t entry, entry2;
+    uint32_t i,j;
+
+
+    offset = base_address >> 20;
+    entry  = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
+
+    //4 bytes aligned
+    ttb += offset;
+    //create l1_entry
+    *ttb = entry;
+
+    offset2 = (base_address & 0xff000) >> 12;
+    ttb_l2 += offset2;
+    entry2 = (base_address & 0xFFFF0000) | descriptor_l2;
+    for (i = 0; i < count; i++ )
+    {
+        //create 16 entries
+        for (j = 0; j < 16; j++)
+            //4 bytes aligned
+            *ttb_l2++ = entry2;
+        entry2 += OFFSET_64K;
+    }
+}
+
+/*@} end of MMU_Functions */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm0.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,682 @@
+/**************************************************************************//**
+ * @file     core_cm0.h
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M0
+  @{
+ */
+
+/*  CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM0_CMSIS_VERSION_SUB   (0x20)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM0_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x00)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0_REV
+    #define __CM0_REV               0x0000
+    #warning "__CM0_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[1];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[31];
+  __IO uint32_t ICER[1];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register          */
+       uint32_t RSERVED1[31];
+  __IO uint32_t ISPR[1];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register           */
+       uint32_t RESERVED2[31];
+  __IO uint32_t ICPR[1];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register         */
+       uint32_t RESERVED3[31];
+       uint32_t RESERVED4[64];
+  __IO uint32_t IP[8];                   /*!< Offset: 0x300 (R/W)  Interrupt Priority Register              */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+       uint32_t RESERVED0;
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+       uint32_t RESERVED1;
+  __IO uint32_t SHP[2];                  /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED   */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
+                are only accessible over DAP and not via processor. Therefore
+                they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address              */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                 */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  (((uint32_t)(IRQn)       )    &  0x03) * 8 )
+#define _SHP_IDX(IRQn)           ( ((((uint32_t)(IRQn) & 0x0F)-8) >>    2)     )
+#define _IP_IDX(IRQn)            (   ((uint32_t)(IRQn)            >>    2)     )
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+  else {
+    NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M0 system interrupts */
+  else {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm0plus.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,793 @@
+/**************************************************************************//**
+ * @file     core_cm0plus.h
+ * @brief    CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex-M0+
+  @{
+ */
+
+/*  CMSIS CM0P definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03)                                /*!< [31:16] CMSIS HAL main version   */
+#define __CM0PLUS_CMSIS_VERSION_SUB  (0x20)                                /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM0PLUS_CMSIS_VERSION      ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
+                                       __CM0PLUS_CMSIS_VERSION_SUB)        /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x00)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0PLUS_REV
+    #define __CM0PLUS_REV             0x0000
+    #warning "__CM0PLUS_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __VTOR_PRESENT
+    #define __VTOR_PRESENT            0
+    #warning "__VTOR_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core MPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[1];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[31];
+  __IO uint32_t ICER[1];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register          */
+       uint32_t RSERVED1[31];
+  __IO uint32_t ISPR[1];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register           */
+       uint32_t RESERVED2[31];
+  __IO uint32_t ICPR[1];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register         */
+       uint32_t RESERVED3[31];
+       uint32_t RESERVED4[64];
+  __IO uint32_t IP[8];                   /*!< Offset: 0x300 (R/W)  Interrupt Priority Register              */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+#if (__VTOR_PRESENT == 1)
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+#else
+       uint32_t RESERVED0;
+#endif
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+       uint32_t RESERVED1;
+  __IO uint32_t SHP[2];                  /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED   */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 8                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   8                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0xFFFFFFUL << MPU_RBAR_ADDR_Pos)              /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL << MPU_RASR_ENABLE_Pos)                   /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
+                are only accessible over DAP and not via processor. Therefore
+                they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address              */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                 */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  (((uint32_t)(IRQn)       )    &  0x03) * 8 )
+#define _SHP_IDX(IRQn)           ( ((((uint32_t)(IRQn) & 0x0F)-8) >>    2)     )
+#define _IP_IDX(IRQn)            (   ((uint32_t)(IRQn)            >>    2)     )
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+  else {
+    NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M0 system interrupts */
+  else {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm3.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1627 @@
+/**************************************************************************//**
+ * @file     core_cm3.h
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M3
+  @{
+ */
+
+/*  CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM3_CMSIS_VERSION_SUB   (0x20)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM3_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x03)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI__VFP_SUPPORT____
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM3_REV
+    #define __CM3_REV               0x0200
+    #warning "__CM3_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL << NVIC_STIR_INTID_Pos)            /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+  __IO uint8_t  SHP[12];                 /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t PFR[2];                  /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t DFR;                     /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ADR;                     /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t MMFR[4];                 /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ISAR[5];                 /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[5];
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register                   */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201)                   /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos               29                                             /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL << SCB_AIRCR_VECTRESET_Pos)               /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL << SCB_CCR_NONBASETHRDENA_Pos)            /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL << SCB_SHCSR_MEMFAULTACT_Pos)             /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos)            /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL << SCB_DFSR_HALTED_Pos)                   /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register      */
+#else
+       uint32_t RESERVED1[1];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos)      /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1                                          /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos)        /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL << ITM_TPR_PRIVMASK_Pos)                /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL << ITM_TCR_ITMENA_Pos)                    /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL << ITM_IWR_ATVALIDM_Pos)                  /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL << ITM_IRR_ATREADYM_Pos)                  /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL << ITM_IMCR_INTEGRATION_Pos)              /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL << ITM_LSR_Present_Pos)                   /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL << DWT_CTRL_CYCCNTENA_Pos)           /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL << DWT_CPICNT_CPICNT_Pos)           /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL << DWT_EXCCNT_EXCCNT_Pos)           /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos)       /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL << DWT_LSUCNT_LSUCNT_Pos)           /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos)         /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL << DWT_MASK_MASK_Pos)               /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL << DWT_FUNCTION_FUNCTION_Pos)        /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL << TPI_ACPR_PRESCALER_Pos)        /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL << TPI_SPPR_TXMODE_Pos)              /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL << TPI_FFSR_FlInProg_Pos)            /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL << TPI_TRIGGER_TRIGGER_Pos)          /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL << TPI_FIFO0_ETM0_Pos)              /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL << TPI_ITATBCTR2_ATREADY_Pos)        /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL << TPI_FIFO1_ITM0_Pos)              /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL << TPI_ITATBCTR0_ATREADY_Pos)        /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL << TPI_ITCTRL_Mode_Pos)              /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL << TPI_DEVID_NrTraceInput_Pos)      /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL << TPI_DEVTYPE_SubType_Pos)          /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL << MPU_RASR_ENABLE_Pos)                   /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos)         /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos)         /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos)      /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                  */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address  */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07);               /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
+  reg_value  =  (reg_value                                 |
+                ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */
+}
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M  System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M  system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if ((ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
+      (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t) ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm4.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1772 @@
+/**************************************************************************//**
+ * @file     core_cm4.h
+ * @brief    CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M4
+  @{
+ */
+
+/*  CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM4_CMSIS_VERSION_SUB   (0x20)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM4_CMSIS_VERSION       ((__CM4_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM4_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x04)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+#include <core_cm4_simd.h>               /* Compiler specific SIMD Intrinsics               */
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM4_REV
+    #define __CM4_REV               0x0000
+    #warning "__CM4_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M4 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL << NVIC_STIR_INTID_Pos)            /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+  __IO uint8_t  SHP[12];                 /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t PFR[2];                  /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t DFR;                     /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ADR;                     /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t MMFR[4];                 /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ISAR[5];                 /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[5];
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register                   */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL << SCB_AIRCR_VECTRESET_Pos)               /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL << SCB_CCR_NONBASETHRDENA_Pos)            /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL << SCB_SHCSR_MEMFAULTACT_Pos)             /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos)            /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL << SCB_DFSR_HALTED_Pos)                   /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register              */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos)      /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos            9                                          /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk           (1UL << SCnSCB_ACTLR_DISOOFP_Pos)           /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos            8                                          /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk           (1UL << SCnSCB_ACTLR_DISFPCA_Pos)           /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1                                          /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos)        /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL << ITM_TPR_PRIVMASK_Pos)                /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL << ITM_TCR_ITMENA_Pos)                    /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL << ITM_IWR_ATVALIDM_Pos)                  /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL << ITM_IRR_ATREADYM_Pos)                  /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL << ITM_IMCR_INTEGRATION_Pos)              /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL << ITM_LSR_Present_Pos)                   /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL << DWT_CTRL_CYCCNTENA_Pos)           /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL << DWT_CPICNT_CPICNT_Pos)           /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL << DWT_EXCCNT_EXCCNT_Pos)           /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos)       /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL << DWT_LSUCNT_LSUCNT_Pos)           /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos)         /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL << DWT_MASK_MASK_Pos)               /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL << DWT_FUNCTION_FUNCTION_Pos)        /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL << TPI_ACPR_PRESCALER_Pos)        /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL << TPI_SPPR_TXMODE_Pos)              /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL << TPI_FFSR_FlInProg_Pos)            /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL << TPI_TRIGGER_TRIGGER_Pos)          /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL << TPI_FIFO0_ETM0_Pos)              /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL << TPI_ITATBCTR2_ATREADY_Pos)        /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL << TPI_FIFO1_ITM0_Pos)              /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL << TPI_ITATBCTR0_ATREADY_Pos)        /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL << TPI_ITCTRL_Mode_Pos)              /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL << TPI_DEVID_NrTraceInput_Pos)      /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL << TPI_DEVTYPE_SubType_Pos)          /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL << MPU_RASR_ENABLE_Pos)                   /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+    \brief      Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __IO uint32_t FPCCR;                   /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register               */
+  __IO uint32_t FPCAR;                   /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register               */
+  __IO uint32_t FPDSCR;                  /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register        */
+  __I  uint32_t MVFR0;                   /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0                       */
+  __I  uint32_t MVFR1;                   /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1                       */
+} FPU_Type;
+
+/* Floating-Point Context Control Register */
+#define FPU_FPCCR_ASPEN_Pos                31                                             /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30                                             /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8                                             /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6                                             /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5                                             /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4                                             /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3                                             /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1                                             /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0                                             /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL << FPU_FPCCR_LSPACT_Pos)                  /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register */
+#define FPU_FPCAR_ADDRESS_Pos               3                                             /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register */
+#define FPU_FPDSCR_AHP_Pos                 26                                             /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25                                             /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24                                             /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22                                             /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28                                             /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24                                             /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20                                             /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16                                             /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12                                             /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8                                             /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4                                             /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0                                             /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos)      /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28                                             /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24                                             /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4                                             /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0                                             /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL << FPU_MVFR1_FtZ_mode_Pos)              /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos)         /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos)         /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos)      /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                  */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address  */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+#if (__FPU_PRESENT == 1)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit                */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit                */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07);               /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
+  reg_value  =  (reg_value                                 |
+                ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */
+}
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+/*  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));  enable interrupt */
+  NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M  System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M  system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if ((ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
+      (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t) ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm4_simd.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,673 @@
+/**************************************************************************//**
+ * @file     core_cm4_simd.h
+ * @brief    CMSIS Cortex-M4 SIMD Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 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.
+   ---------------------------------------------------------------------------*/
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_SIMD_H
+#define __CORE_CM4_SIMD_H
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32)      ) >> 32))
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+#include <cmsis_iar.h>
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+#include <cmsis_ccs.h>
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SMLALD(ARG1,ARG2,ARG3) \
+({ \
+  uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+  (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+#define __SMLALDX(ARG1,ARG2,ARG3) \
+({ \
+  uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+  (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SMLSLD(ARG1,ARG2,ARG3) \
+({ \
+  uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+  (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+#define __SMLSLDX(ARG1,ARG2,ARG3) \
+({ \
+  uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+  (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+/* not yet supported */
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CORE_CM4_SIMD_H */
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cm7.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,2397 @@
+/**************************************************************************//**
+ * @file     core_cm7.h
+ * @brief    CMSIS Cortex-M7 Core Peripheral Access Layer Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifndef __CORE_CM7_H_GENERIC
+#define __CORE_CM7_H_GENERIC
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M7
+  @{
+ */
+
+/*  CMSIS CM7 definitions */
+#define __CM7_CMSIS_VERSION_MAIN  (0x04)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM7_CMSIS_VERSION_SUB   (0x00)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM7_CMSIS_VERSION       ((__CM7_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM7_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x07)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __CSMC__ )
+  #define __packed
+  #define __ASM            _asm                                      /*!< asm keyword for COSMIC Compiler      */
+  #define __INLINE         inline                                    /*use -pc99 on compile line !< inline keyword for COSMIC Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+    For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI_VFP_SUPPORT__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+
+#elif defined ( __CSMC__ )		/* Cosmic */
+  #if ( __CSMC__ & 0x400)		// FPU present for parser
+    #if (__FPU_PRESENT == 1)
+      #define __FPU_USED       1
+    #else
+      #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+      #define __FPU_USED       0
+    #endif
+  #else
+    #define __FPU_USED         0
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+#include <core_cmSimd.h>                 /* Compiler specific SIMD Intrinsics               */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM7_H_DEPENDANT
+#define __CORE_CM7_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM7_REV
+    #define __CM7_REV               0x0000
+    #warning "__CM7_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __FPU_PRESENT
+    #define __FPU_PRESENT             0
+    #warning "__FPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __ICACHE_PRESENT
+    #define __ICACHE_PRESENT          0
+    #warning "__ICACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DCACHE_PRESENT
+    #define __DCACHE_PRESENT          0
+    #warning "__DCACHE_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __DTCM_PRESENT
+    #define __DTCM_PRESENT            0
+    #warning "__DTCM_PRESENT        not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          3
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M7 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+  - Core FPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos                         31                                             /*!< APSR: N Position */
+#define APSR_N_Msk                         (1UL << APSR_N_Pos)                            /*!< APSR: N Mask */
+
+#define APSR_Z_Pos                         30                                             /*!< APSR: Z Position */
+#define APSR_Z_Msk                         (1UL << APSR_Z_Pos)                            /*!< APSR: Z Mask */
+
+#define APSR_C_Pos                         29                                             /*!< APSR: C Position */
+#define APSR_C_Msk                         (1UL << APSR_C_Pos)                            /*!< APSR: C Mask */
+
+#define APSR_V_Pos                         28                                             /*!< APSR: V Position */
+#define APSR_V_Msk                         (1UL << APSR_V_Pos)                            /*!< APSR: V Mask */
+
+#define APSR_Q_Pos                         27                                             /*!< APSR: Q Position */
+#define APSR_Q_Msk                         (1UL << APSR_Q_Pos)                            /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos                        16                                             /*!< APSR: GE Position */
+#define APSR_GE_Msk                        (0xFUL << APSR_GE_Pos)                         /*!< APSR: GE Mask */
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos                        0                                             /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk                       (0x1FFUL /*<< IPSR_ISR_Pos*/)                  /*!< IPSR: ISR Mask */
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos                         31                                             /*!< xPSR: N Position */
+#define xPSR_N_Msk                         (1UL << xPSR_N_Pos)                            /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos                         30                                             /*!< xPSR: Z Position */
+#define xPSR_Z_Msk                         (1UL << xPSR_Z_Pos)                            /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos                         29                                             /*!< xPSR: C Position */
+#define xPSR_C_Msk                         (1UL << xPSR_C_Pos)                            /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos                         28                                             /*!< xPSR: V Position */
+#define xPSR_V_Msk                         (1UL << xPSR_V_Pos)                            /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos                         27                                             /*!< xPSR: Q Position */
+#define xPSR_Q_Msk                         (1UL << xPSR_Q_Pos)                            /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos                        25                                             /*!< xPSR: IT Position */
+#define xPSR_IT_Msk                        (3UL << xPSR_IT_Pos)                           /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos                         24                                             /*!< xPSR: T Position */
+#define xPSR_T_Msk                         (1UL << xPSR_T_Pos)                            /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos                        16                                             /*!< xPSR: GE Position */
+#define xPSR_GE_Msk                        (0xFUL << xPSR_GE_Pos)                         /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos                        0                                             /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk                       (0x1FFUL /*<< xPSR_ISR_Pos*/)                  /*!< xPSR: ISR Mask */
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos                    2                                             /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk                   (1UL << CONTROL_FPCA_Pos)                      /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos                   1                                             /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk                  (1UL << CONTROL_SPSEL_Pos)                     /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos                   0                                             /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk                  (1UL /*<< CONTROL_nPRIV_Pos*/)                 /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/)        /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+  __IO uint8_t  SHPR[12];                /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t ID_PFR[2];               /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t ID_DFR;                  /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ID_AFR;                  /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t ID_MFR[4];               /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ID_ISAR[5];              /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[1];
+  __I  uint32_t CLIDR;                   /*!< Offset: 0x078 (R/ )  Cache Level ID register                               */
+  __I  uint32_t CTR;                     /*!< Offset: 0x07C (R/ )  Cache Type register                                   */
+  __I  uint32_t CCSIDR;                  /*!< Offset: 0x080 (R/ )  Cache Size ID Register                                */
+  __IO uint32_t CSSELR;                  /*!< Offset: 0x084 (R/W)  Cache Size Selection Register                         */
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register                   */
+       uint32_t RESERVED3[93];
+  __O  uint32_t STIR;                    /*!< Offset: 0x200 ( /W)  Software Triggered Interrupt Register                 */
+       uint32_t RESERVED4[15];
+  __I  uint32_t MVFR0;                   /*!< Offset: 0x240 (R/ )  Media and VFP Feature Register 0                      */
+  __I  uint32_t MVFR1;                   /*!< Offset: 0x244 (R/ )  Media and VFP Feature Register 1                      */
+  __I  uint32_t MVFR2;                   /*!< Offset: 0x248 (R/ )  Media and VFP Feature Register 1                      */
+       uint32_t RESERVED5[1];
+  __O  uint32_t ICIALLU;                 /*!< Offset: 0x250 ( /W)  I-Cache Invalidate All to PoU                         */
+       uint32_t RESERVED6[1];
+  __O  uint32_t ICIMVAU;                 /*!< Offset: 0x258 ( /W)  I-Cache Invalidate by MVA to PoU                      */
+  __O  uint32_t DCIMVAC;                 /*!< Offset: 0x25C ( /W)  D-Cache Invalidate by MVA to PoC                      */
+  __O  uint32_t DCISW;                   /*!< Offset: 0x260 ( /W)  D-Cache Invalidate by Set-way                         */
+  __O  uint32_t DCCMVAU;                 /*!< Offset: 0x264 ( /W)  D-Cache Clean by MVA to PoU                           */
+  __O  uint32_t DCCMVAC;                 /*!< Offset: 0x268 ( /W)  D-Cache Clean by MVA to PoC                           */
+  __O  uint32_t DCCSW;                   /*!< Offset: 0x26C ( /W)  D-Cache Clean by Set-way                              */
+  __O  uint32_t DCCIMVAC;                /*!< Offset: 0x270 ( /W)  D-Cache Clean and Invalidate by MVA to PoC            */
+  __O  uint32_t DCCISW;                  /*!< Offset: 0x274 ( /W)  D-Cache Clean and Invalidate by Set-way               */
+       uint32_t RESERVED7[6];
+  __IO uint32_t ITCMCR;                  /*!< Offset: 0x290 (R/W)  Instruction Tightly-Coupled Memory Control Register   */
+  __IO uint32_t DTCMCR;                  /*!< Offset: 0x294 (R/W)  Data Tightly-Coupled Memory Control Registers         */
+  __IO uint32_t AHBPCR;                  /*!< Offset: 0x298 (R/W)  AHBP Control Register                                 */
+  __IO uint32_t CACR;                    /*!< Offset: 0x29C (R/W)  L1 Cache Control Register                             */
+  __IO uint32_t AHBSCR;                  /*!< Offset: 0x2A0 (R/W)  AHB Slave Control Register                            */
+       uint32_t RESERVED8[1];
+  __IO uint32_t ABFSR;                   /*!< Offset: 0x2A8 (R/W)  Auxiliary Bus Fault Status Register                   */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL /*<< SCB_CPUID_REVISION_Pos*/)          /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/)       /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/)           /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_BP_Pos                      18                                            /*!< SCB CCR: Branch prediction enable bit Position */
+#define SCB_CCR_BP_Msk                     (1UL << SCB_CCR_BP_Pos)                        /*!< SCB CCR: Branch prediction enable bit Mask */
+
+#define SCB_CCR_IC_Pos                      17                                            /*!< SCB CCR: Instruction cache enable bit Position */
+#define SCB_CCR_IC_Msk                     (1UL << SCB_CCR_IC_Pos)                        /*!< SCB CCR: Instruction cache enable bit Mask */
+
+#define SCB_CCR_DC_Pos                      16                                            /*!< SCB CCR: Cache enable bit Position */
+#define SCB_CCR_DC_Msk                     (1UL << SCB_CCR_DC_Pos)                        /*!< SCB CCR: Cache enable bit Mask */
+
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/)        /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/)         /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/)        /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL /*<< SCB_DFSR_HALTED_Pos*/)               /*!< SCB DFSR: HALTED Mask */
+
+/* Cache Level ID register */
+#define SCB_CLIDR_LOUU_Pos                 27                                             /*!< SCB CLIDR: LoUU Position */
+#define SCB_CLIDR_LOUU_Msk                 (7UL << SCB_CLIDR_LOUU_Pos)                    /*!< SCB CLIDR: LoUU Mask */
+
+#define SCB_CLIDR_LOC_Pos                  24                                             /*!< SCB CLIDR: LoC Position */
+#define SCB_CLIDR_LOC_Msk                  (7UL << SCB_CLIDR_FORMAT_Pos)                  /*!< SCB CLIDR: LoC Mask */
+
+/* Cache Type register */
+#define SCB_CTR_FORMAT_Pos                 29                                             /*!< SCB CTR: Format Position */
+#define SCB_CTR_FORMAT_Msk                 (7UL << SCB_CTR_FORMAT_Pos)                    /*!< SCB CTR: Format Mask */
+
+#define SCB_CTR_CWG_Pos                    24                                             /*!< SCB CTR: CWG Position */
+#define SCB_CTR_CWG_Msk                    (0xFUL << SCB_CTR_CWG_Pos)                     /*!< SCB CTR: CWG Mask */
+
+#define SCB_CTR_ERG_Pos                    20                                             /*!< SCB CTR: ERG Position */
+#define SCB_CTR_ERG_Msk                    (0xFUL << SCB_CTR_ERG_Pos)                     /*!< SCB CTR: ERG Mask */
+
+#define SCB_CTR_DMINLINE_Pos               16                                             /*!< SCB CTR: DminLine Position */
+#define SCB_CTR_DMINLINE_Msk               (0xFUL << SCB_CTR_DMINLINE_Pos)                /*!< SCB CTR: DminLine Mask */
+
+#define SCB_CTR_IMINLINE_Pos                0                                             /*!< SCB CTR: ImInLine Position */
+#define SCB_CTR_IMINLINE_Msk               (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/)            /*!< SCB CTR: ImInLine Mask */
+
+/* Cache Size ID Register */
+#define SCB_CCSIDR_WT_Pos                  31                                             /*!< SCB CCSIDR: WT Position */
+#define SCB_CCSIDR_WT_Msk                  (7UL << SCB_CCSIDR_WT_Pos)                     /*!< SCB CCSIDR: WT Mask */
+
+#define SCB_CCSIDR_WB_Pos                  30                                             /*!< SCB CCSIDR: WB Position */
+#define SCB_CCSIDR_WB_Msk                  (7UL << SCB_CCSIDR_WB_Pos)                     /*!< SCB CCSIDR: WB Mask */
+
+#define SCB_CCSIDR_RA_Pos                  29                                             /*!< SCB CCSIDR: RA Position */
+#define SCB_CCSIDR_RA_Msk                  (7UL << SCB_CCSIDR_RA_Pos)                     /*!< SCB CCSIDR: RA Mask */
+
+#define SCB_CCSIDR_WA_Pos                  28                                             /*!< SCB CCSIDR: WA Position */
+#define SCB_CCSIDR_WA_Msk                  (7UL << SCB_CCSIDR_WA_Pos)                     /*!< SCB CCSIDR: WA Mask */
+
+#define SCB_CCSIDR_NUMSETS_Pos             13                                             /*!< SCB CCSIDR: NumSets Position */
+#define SCB_CCSIDR_NUMSETS_Msk             (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos)           /*!< SCB CCSIDR: NumSets Mask */
+
+#define SCB_CCSIDR_ASSOCIATIVITY_Pos        3                                             /*!< SCB CCSIDR: Associativity Position */
+#define SCB_CCSIDR_ASSOCIATIVITY_Msk       (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos)      /*!< SCB CCSIDR: Associativity Mask */
+
+#define SCB_CCSIDR_LINESIZE_Pos             0                                             /*!< SCB CCSIDR: LineSize Position */
+#define SCB_CCSIDR_LINESIZE_Msk            (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/)           /*!< SCB CCSIDR: LineSize Mask */
+
+/* Cache Size Selection Register */
+#define SCB_CSSELR_LEVEL_Pos                1                                             /*!< SCB CSSELR: Level Position */
+#define SCB_CSSELR_LEVEL_Msk               (7UL << SCB_CSSELR_LEVEL_Pos)                  /*!< SCB CSSELR: Level Mask */
+
+#define SCB_CSSELR_IND_Pos                  0                                             /*!< SCB CSSELR: InD Position */
+#define SCB_CSSELR_IND_Msk                 (1UL /*<< SCB_CSSELR_IND_Pos*/)                /*!< SCB CSSELR: InD Mask */
+
+/* SCB Software Triggered Interrupt Register */
+#define SCB_STIR_INTID_Pos                  0                                             /*!< SCB STIR: INTID Position */
+#define SCB_STIR_INTID_Msk                 (0x1FFUL /*<< SCB_STIR_INTID_Pos*/)            /*!< SCB STIR: INTID Mask */
+
+/* Instruction Tightly-Coupled Memory Control Register*/
+#define SCB_ITCMCR_SZ_Pos                   3                                             /*!< SCB ITCMCR: SZ Position */
+#define SCB_ITCMCR_SZ_Msk                  (0xFUL << SCB_ITCMCR_SZ_Pos)                   /*!< SCB ITCMCR: SZ Mask */
+
+#define SCB_ITCMCR_RETEN_Pos                2                                             /*!< SCB ITCMCR: RETEN Position */
+#define SCB_ITCMCR_RETEN_Msk               (1UL << SCB_ITCMCR_RETEN_Pos)                  /*!< SCB ITCMCR: RETEN Mask */
+
+#define SCB_ITCMCR_RMW_Pos                  1                                             /*!< SCB ITCMCR: RMW Position */
+#define SCB_ITCMCR_RMW_Msk                 (1UL << SCB_ITCMCR_RMW_Pos)                    /*!< SCB ITCMCR: RMW Mask */
+
+#define SCB_ITCMCR_EN_Pos                   0                                             /*!< SCB ITCMCR: EN Position */
+#define SCB_ITCMCR_EN_Msk                  (1UL /*<< SCB_ITCMCR_EN_Pos*/)                 /*!< SCB ITCMCR: EN Mask */
+
+/* Data Tightly-Coupled Memory Control Registers */
+#define SCB_DTCMCR_SZ_Pos                   3                                             /*!< SCB DTCMCR: SZ Position */
+#define SCB_DTCMCR_SZ_Msk                  (0xFUL << SCB_DTCMCR_SZ_Pos)                   /*!< SCB DTCMCR: SZ Mask */
+
+#define SCB_DTCMCR_RETEN_Pos                2                                             /*!< SCB DTCMCR: RETEN Position */
+#define SCB_DTCMCR_RETEN_Msk               (1UL << SCB_DTCMCR_RETEN_Pos)                   /*!< SCB DTCMCR: RETEN Mask */
+
+#define SCB_DTCMCR_RMW_Pos                  1                                             /*!< SCB DTCMCR: RMW Position */
+#define SCB_DTCMCR_RMW_Msk                 (1UL << SCB_DTCMCR_RMW_Pos)                    /*!< SCB DTCMCR: RMW Mask */
+
+#define SCB_DTCMCR_EN_Pos                   0                                             /*!< SCB DTCMCR: EN Position */
+#define SCB_DTCMCR_EN_Msk                  (1UL /*<< SCB_DTCMCR_EN_Pos*/)                 /*!< SCB DTCMCR: EN Mask */
+
+/* AHBP Control Register */
+#define SCB_AHBPCR_SZ_Pos                   1                                             /*!< SCB AHBPCR: SZ Position */
+#define SCB_AHBPCR_SZ_Msk                  (7UL << SCB_AHBPCR_SZ_Pos)                     /*!< SCB AHBPCR: SZ Mask */
+
+#define SCB_AHBPCR_EN_Pos                   0                                             /*!< SCB AHBPCR: EN Position */
+#define SCB_AHBPCR_EN_Msk                  (1UL /*<< SCB_AHBPCR_EN_Pos*/)                 /*!< SCB AHBPCR: EN Mask */
+
+/* L1 Cache Control Register */
+#define SCB_CACR_FORCEWT_Pos                2                                             /*!< SCB CACR: FORCEWT Position */
+#define SCB_CACR_FORCEWT_Msk               (1UL << SCB_CACR_FORCEWT_Pos)                  /*!< SCB CACR: FORCEWT Mask */
+
+#define SCB_CACR_ECCEN_Pos                  1                                             /*!< SCB CACR: ECCEN Position */
+#define SCB_CACR_ECCEN_Msk                 (1UL << SCB_CACR_ECCEN_Pos)                    /*!< SCB CACR: ECCEN Mask */
+
+#define SCB_CACR_SIWT_Pos                   0                                             /*!< SCB CACR: SIWT Position */
+#define SCB_CACR_SIWT_Msk                  (1UL /*<< SCB_CACR_SIWT_Pos*/)                 /*!< SCB CACR: SIWT Mask */
+
+/* AHBS control register */
+#define SCB_AHBSCR_INITCOUNT_Pos           11                                             /*!< SCB AHBSCR: INITCOUNT Position */
+#define SCB_AHBSCR_INITCOUNT_Msk           (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos)           /*!< SCB AHBSCR: INITCOUNT Mask */
+
+#define SCB_AHBSCR_TPRI_Pos                 2                                             /*!< SCB AHBSCR: TPRI Position */
+#define SCB_AHBSCR_TPRI_Msk                (0x1FFUL << SCB_AHBPCR_TPRI_Pos)               /*!< SCB AHBSCR: TPRI Mask */
+
+#define SCB_AHBSCR_CTL_Pos                  0                                             /*!< SCB AHBSCR: CTL Position*/
+#define SCB_AHBSCR_CTL_Msk                 (3UL /*<< SCB_AHBPCR_CTL_Pos*/)                /*!< SCB AHBSCR: CTL Mask */
+
+/* Auxiliary Bus Fault Status Register */
+#define SCB_ABFSR_AXIMTYPE_Pos              8                                             /*!< SCB ABFSR: AXIMTYPE Position*/
+#define SCB_ABFSR_AXIMTYPE_Msk             (3UL << SCB_ABFSR_AXIMTYPE_Pos)                /*!< SCB ABFSR: AXIMTYPE Mask */
+
+#define SCB_ABFSR_EPPB_Pos                  4                                             /*!< SCB ABFSR: EPPB Position*/
+#define SCB_ABFSR_EPPB_Msk                 (1UL << SCB_ABFSR_EPPB_Pos)                    /*!< SCB ABFSR: EPPB Mask */
+
+#define SCB_ABFSR_AXIM_Pos                  3                                             /*!< SCB ABFSR: AXIM Position*/
+#define SCB_ABFSR_AXIM_Msk                 (1UL << SCB_ABFSR_AXIM_Pos)                    /*!< SCB ABFSR: AXIM Mask */
+
+#define SCB_ABFSR_AHBP_Pos                  2                                             /*!< SCB ABFSR: AHBP Position*/
+#define SCB_ABFSR_AHBP_Msk                 (1UL << SCB_ABFSR_AHBP_Pos)                    /*!< SCB ABFSR: AHBP Mask */
+
+#define SCB_ABFSR_DTCM_Pos                  1                                             /*!< SCB ABFSR: DTCM Position*/
+#define SCB_ABFSR_DTCM_Msk                 (1UL << SCB_ABFSR_DTCM_Pos)                    /*!< SCB ABFSR: DTCM Mask */
+
+#define SCB_ABFSR_ITCM_Pos                  0                                             /*!< SCB ABFSR: ITCM Position*/
+#define SCB_ABFSR_ITCM_Msk                 (1UL /*<< SCB_ABFSR_ITCM_Pos*/)                /*!< SCB ABFSR: ITCM Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register              */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/)  /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos    12                                          /*!< ACTLR: DISITMATBFLUSH Position */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk    (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos)    /*!< ACTLR: DISITMATBFLUSH Mask */
+
+#define SCnSCB_ACTLR_DISRAMODE_Pos         11                                          /*!< ACTLR: DISRAMODE Position */
+#define SCnSCB_ACTLR_DISRAMODE_Msk         (1UL << SCnSCB_ACTLR_DISRAMODE_Pos)         /*!< ACTLR: DISRAMODE Mask */
+
+#define SCnSCB_ACTLR_FPEXCODIS_Pos         10                                          /*!< ACTLR: FPEXCODIS Position */
+#define SCnSCB_ACTLR_FPEXCODIS_Msk         (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos)         /*!< ACTLR: FPEXCODIS Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/)    /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL /*<< SysTick_CTRL_ENABLE_Pos*/)           /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/)    /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/)    /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/)    /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/)            /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL /*<< ITM_TCR_ITMENA_Pos*/)                /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL /*<< ITM_IWR_ATVALIDM_Pos*/)              /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL /*<< ITM_IRR_ATREADYM_Pos*/)              /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/)          /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL /*<< ITM_LSR_Present_Pos*/)               /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+       uint32_t RESERVED3[981];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 (  W)  Lock Access Register                      */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R  )  Lock Status Register                      */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/)       /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/)       /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/)   /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/)       /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/)     /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL /*<< DWT_MASK_MASK_Pos*/)           /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/)    /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/)    /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/)          /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/)        /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/)      /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/)          /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/)    /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/)          /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/)    /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/)          /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/)  /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/)      /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL /*<< MPU_TYPE_SEPARATE_Pos*/)             /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL /*<< MPU_CTRL_ENABLE_Pos*/)               /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL /*<< MPU_RNR_REGION_Pos*/)             /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL /*<< MPU_RBAR_REGION_Pos*/)             /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL /*<< MPU_RASR_ENABLE_Pos*/)               /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_FPU     Floating Point Unit (FPU)
+    \brief      Type definitions for the Floating Point Unit (FPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __IO uint32_t FPCCR;                   /*!< Offset: 0x004 (R/W)  Floating-Point Context Control Register               */
+  __IO uint32_t FPCAR;                   /*!< Offset: 0x008 (R/W)  Floating-Point Context Address Register               */
+  __IO uint32_t FPDSCR;                  /*!< Offset: 0x00C (R/W)  Floating-Point Default Status Control Register        */
+  __I  uint32_t MVFR0;                   /*!< Offset: 0x010 (R/ )  Media and FP Feature Register 0                       */
+  __I  uint32_t MVFR1;                   /*!< Offset: 0x014 (R/ )  Media and FP Feature Register 1                       */
+  __I  uint32_t MVFR2;                   /*!< Offset: 0x018 (R/ )  Media and FP Feature Register 2                       */
+} FPU_Type;
+
+/* Floating-Point Context Control Register */
+#define FPU_FPCCR_ASPEN_Pos                31                                             /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk                (1UL << FPU_FPCCR_ASPEN_Pos)                   /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos                30                                             /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk                (1UL << FPU_FPCCR_LSPEN_Pos)                   /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos                8                                             /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk               (1UL << FPU_FPCCR_MONRDY_Pos)                  /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos                 6                                             /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk                (1UL << FPU_FPCCR_BFRDY_Pos)                   /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos                 5                                             /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk                (1UL << FPU_FPCCR_MMRDY_Pos)                   /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos                 4                                             /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk                (1UL << FPU_FPCCR_HFRDY_Pos)                   /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos                3                                             /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk               (1UL << FPU_FPCCR_THREAD_Pos)                  /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos                  1                                             /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk                 (1UL << FPU_FPCCR_USER_Pos)                    /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos                0                                             /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk               (1UL /*<< FPU_FPCCR_LSPACT_Pos*/)              /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register */
+#define FPU_FPCAR_ADDRESS_Pos               3                                             /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk              (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos)        /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register */
+#define FPU_FPDSCR_AHP_Pos                 26                                             /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk                 (1UL << FPU_FPDSCR_AHP_Pos)                    /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos                  25                                             /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk                  (1UL << FPU_FPDSCR_DN_Pos)                     /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos                  24                                             /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk                  (1UL << FPU_FPDSCR_FZ_Pos)                     /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos               22                                             /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk               (3UL << FPU_FPDSCR_RMode_Pos)                  /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 */
+#define FPU_MVFR0_FP_rounding_modes_Pos    28                                             /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk    (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos)     /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos        24                                             /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk        (0xFUL << FPU_MVFR0_Short_vectors_Pos)         /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos          20                                             /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk          (0xFUL << FPU_MVFR0_Square_root_Pos)           /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos               16                                             /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk               (0xFUL << FPU_MVFR0_Divide_Pos)                /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos    12                                             /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk    (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos)     /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos      8                                             /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk     (0xFUL << FPU_MVFR0_Double_precision_Pos)      /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos      4                                             /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk     (0xFUL << FPU_MVFR0_Single_precision_Pos)      /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos      0                                             /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk     (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/)  /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 */
+#define FPU_MVFR1_FP_fused_MAC_Pos         28                                             /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk         (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos)          /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos              24                                             /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk              (0xFUL << FPU_MVFR1_FP_HPFP_Pos)               /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos            4                                             /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk           (0xFUL << FPU_MVFR1_D_NaN_mode_Pos)            /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos              0                                             /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk             (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/)          /*!< MVFR1: FtZ mode bits Mask */
+
+/* Media and FP Feature Register 2 */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/)     /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/)     /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/)  /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                  */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address  */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+#if (__FPU_PRESENT == 1)
+  #define FPU_BASE          (SCS_BASE +  0x0F30UL)                    /*!< Floating Point Unit                */
+  #define FPU               ((FPU_Type       *)     FPU_BASE      )   /*!< Floating Point Unit                */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk));             /* clear bits to change               */
+  reg_value  =  (reg_value                                   |
+                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8)                       );              /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if((int32_t)IRQn < 0) {
+    SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+  else {
+    NVIC->IP[((uint32_t)(int32_t)IRQn)]                = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+  }
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if((int32_t)IRQn < 0) {
+    return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS)));
+  }
+  else {
+    return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)]               >> (8 - __NVIC_PRIO_BITS)));
+  }
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  return (
+           ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+           ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+  SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+  *pSubPriority     = (Priority                   ) & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                          /* Ensure all outstanding memory accesses included
+                                                                       buffered write are completed before reset */
+  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
+                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
+  __DSB();                                                          /* Ensure completion of memory access */
+  while(1) { __NOP(); }                                             /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+/* ##########################  FPU functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_FpuFunctions FPU Functions
+    \brief      Function that provides FPU type.
+    @{
+ */
+
+/**
+  \fn          uint32_t SCB_GetFPUType(void)
+  \brief       get FPU type
+  \returns
+   - \b  0: No FPU
+   - \b  1: Single precision FPU
+   - \b  2: Double + Single precision FPU
+ */
+__STATIC_INLINE uint32_t SCB_GetFPUType(void)
+{
+  uint32_t mvfr0;
+
+  mvfr0 = SCB->MVFR0;
+  if        ((mvfr0 & 0x00000FF0UL) == 0x220UL) {
+    return 2UL;           // Double + Single precision FPU
+  } else if ((mvfr0 & 0x00000FF0UL) == 0x020UL) {
+    return 1UL;           // Single precision FPU
+  } else {
+    return 0UL;           // No FPU
+  }
+}
+
+
+/*@} end of CMSIS_Core_FpuFunctions */
+
+
+
+/* ##########################  Cache functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_CacheFunctions Cache Functions
+    \brief      Functions that configure Instruction and Data cache.
+    @{
+ */
+
+/* Cache Size ID Register Macros */
+#define CCSIDR_WAYS(x)         (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+#define CCSIDR_SETS(x)         (((x) & SCB_CCSIDR_NUMSETS_Msk      ) >> SCB_CCSIDR_NUMSETS_Pos      )
+#define CCSIDR_LSSHIFT(x)      (((x) & SCB_CCSIDR_LINESIZE_Msk     ) /*>> SCB_CCSIDR_LINESIZE_Pos*/ )
+
+
+/** \brief Enable I-Cache
+
+    The function turns on I-Cache
+  */
+__STATIC_INLINE void SCB_EnableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;                     // invalidate I-Cache
+    SCB->CCR |=  (uint32_t)SCB_CCR_IC_Msk;  // enable I-Cache
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Disable I-Cache
+
+    The function turns off I-Cache
+  */
+__STATIC_INLINE void SCB_DisableICache (void)
+{
+  #if (__ICACHE_PRESENT == 1)
+    __DSB();
+    __ISB();
+    SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk;  // disable I-Cache
+    SCB->ICIALLU = 0UL;                     // invalidate I-Cache
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Invalidate I-Cache
+
+    The function invalidates I-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateICache (void)
+{
+  #if (__ICACHE_PRESENT == 1)
+    __DSB();
+    __ISB();
+    SCB->ICIALLU = 0UL;
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Enable D-Cache
+
+    The function turns on D-Cache
+  */
+__STATIC_INLINE void SCB_EnableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1)
+    uint32_t ccsidr, sshift, wshift, sw;
+    uint32_t sets, ways;
+
+    SCB->CSSELR = (0UL << 1) | 0UL;         // Level 1 data cache
+    ccsidr  = SCB->CCSIDR;
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL);
+
+    __DSB();
+
+    do {                                   // invalidate D-Cache
+         uint32_t tmpways = ways;
+         do {
+              sw = ((tmpways << wshift) | (sets << sshift));
+              SCB->DCISW = sw;
+            } while(tmpways--);
+        } while(sets--);
+    __DSB();
+
+    SCB->CCR |=  (uint32_t)SCB_CCR_DC_Msk;   // enable D-Cache
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Disable D-Cache
+
+    The function turns off D-Cache
+  */
+__STATIC_INLINE void SCB_DisableDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1)
+    uint32_t ccsidr, sshift, wshift, sw;
+    uint32_t sets, ways;
+
+    SCB->CSSELR = (0UL << 1) | 0UL;         // Level 1 data cache
+    ccsidr  = SCB->CCSIDR;
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL);
+
+    __DSB();
+
+    SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk;  // disable D-Cache
+
+    do {                                    // clean & invalidate D-Cache
+         uint32_t tmpways = ways;
+         do {
+              sw = ((tmpways << wshift) | (sets << sshift));
+              SCB->DCCISW = sw;
+            } while(tmpways--);
+        } while(sets--);
+
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Invalidate D-Cache
+
+    The function invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_InvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1)
+    uint32_t ccsidr, sshift, wshift, sw;
+    uint32_t sets, ways;
+
+    SCB->CSSELR = (0UL << 1) | 0UL;         // Level 1 data cache
+    ccsidr  = SCB->CCSIDR;
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL);
+
+    __DSB();
+
+    do {                                    // invalidate D-Cache
+         uint32_t tmpways = ways;
+         do {
+              sw = ((tmpways << wshift) | (sets << sshift));
+              SCB->DCISW = sw;
+            } while(tmpways--);
+        } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Clean D-Cache
+
+    The function cleans D-Cache
+  */
+__STATIC_INLINE void SCB_CleanDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1)
+    uint32_t ccsidr, sshift, wshift, sw;
+    uint32_t sets, ways;
+
+    SCB->CSSELR = (0UL << 1) | 0UL;         // Level 1 data cache
+    ccsidr  = SCB->CCSIDR;
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL);
+
+    __DSB();
+
+    do {                                    // clean D-Cache
+         uint32_t tmpways = ways;
+         do {
+              sw = ((tmpways << wshift) | (sets << sshift));
+              SCB->DCCSW = sw;
+            } while(tmpways--);
+        } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/** \brief Clean & Invalidate D-Cache
+
+    The function cleans and Invalidates D-Cache
+  */
+__STATIC_INLINE void SCB_CleanInvalidateDCache (void)
+{
+  #if (__DCACHE_PRESENT == 1)
+    uint32_t ccsidr, sshift, wshift, sw;
+    uint32_t sets, ways;
+
+    SCB->CSSELR = (0UL << 1) | 0UL;         // Level 1 data cache
+    ccsidr  = SCB->CCSIDR;
+    sets    = (uint32_t)(CCSIDR_SETS(ccsidr));
+    sshift  = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL);
+    ways    = (uint32_t)(CCSIDR_WAYS(ccsidr));
+    wshift  = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL);
+
+    __DSB();
+
+    do {                                    // clean & invalidate D-Cache
+         uint32_t tmpways = ways;
+         do {
+              sw = ((tmpways << wshift) | (sets << sshift));
+              SCB->DCCISW = sw;
+            } while(tmpways--);
+        } while(sets--);
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \fn          void SCB_InvalidateDCache_by_Addr(volatile uint32_t *addr, int32_t dsize)
+  \brief       D-Cache Invalidate by address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1)
+    int32_t  op_size = dsize;
+    uint32_t op_addr = (uint32_t)addr;
+    uint32_t linesize = 32UL;               // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes)
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCIMVAC = op_addr;
+      op_addr +=          linesize;
+      op_size -= (int32_t)linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \fn          void SCB_CleanDCache_by_Addr(volatile uint32_t *addr, int32_t dsize)
+  \brief       D-Cache Clean by address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1)
+    int32_t  op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+    uint32_t linesize = 32UL;               // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes)
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCMVAC = op_addr;
+      op_addr +=          linesize;
+      op_size -= (int32_t)linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/**
+  \fn          void SCB_CleanInvalidateDCache_by_Addr(volatile uint32_t *addr, int32_t dsize)
+  \brief       D-Cache Clean and Invalidate by address
+  \param[in]   addr    address (aligned to 32-byte boundary)
+  \param[in]   dsize   size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+  #if (__DCACHE_PRESENT == 1)
+    int32_t  op_size = dsize;
+    uint32_t op_addr = (uint32_t) addr;
+    uint32_t linesize = 32UL;               // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes)
+
+    __DSB();
+
+    while (op_size > 0) {
+      SCB->DCCIMVAC = op_addr;
+      op_addr +=          linesize;
+      op_size -= (int32_t)linesize;
+    }
+
+    __DSB();
+    __ISB();
+  #endif
+}
+
+
+/*@} end of CMSIS_Core_CacheFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); }    /* Reload value impossible */
+
+  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
+  return (0UL);                                                     /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
+      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0UL) { __NOP(); }
+    ITM->PORT[0].u8 = (uint8_t)ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmFunc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,636 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief  Enable IRQ Interrupts
+
+  This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/** \brief  Disable IRQ Interrupts
+
+  This function disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  uint32_t result;
+
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CMFUNC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmInstr.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,688 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V3.20
+ * @date     05. March 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+#define __ISB()                           __isb(0xF)
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()                           __dsb(0xF)
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+#define __DMB()                           __dmb(0xF)
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+#endif
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __breakpoint(value)
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __RBIT                            __rbit
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr)                     ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr)                     ((uint16_t) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr)                     ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXB(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXH(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXW(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX                           __clrex
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constrant "l"
+ * Otherwise, use general registers, specified by constrant "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb");
+}
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb");
+}
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb");
+}
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+  return __builtin_bswap32(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+  return (short)__builtin_bswap16(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32 - op2)); 
+}
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
+{
+   uint32_t result;
+
+  __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/core_cmSimd.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,697 @@
+/**************************************************************************//**
+ * @file     core_cmSimd.h
+ * @brief    CMSIS Cortex-M SIMD Header File
+ * @version  V4.10
+ * @date     18. March 2015
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2014 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+/* ###################  Compiler specific Intrinsics  ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+  Access to dedicated SIMD instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+#define __SADD8                           __sadd8
+#define __QADD8                           __qadd8
+#define __SHADD8                          __shadd8
+#define __UADD8                           __uadd8
+#define __UQADD8                          __uqadd8
+#define __UHADD8                          __uhadd8
+#define __SSUB8                           __ssub8
+#define __QSUB8                           __qsub8
+#define __SHSUB8                          __shsub8
+#define __USUB8                           __usub8
+#define __UQSUB8                          __uqsub8
+#define __UHSUB8                          __uhsub8
+#define __SADD16                          __sadd16
+#define __QADD16                          __qadd16
+#define __SHADD16                         __shadd16
+#define __UADD16                          __uadd16
+#define __UQADD16                         __uqadd16
+#define __UHADD16                         __uhadd16
+#define __SSUB16                          __ssub16
+#define __QSUB16                          __qsub16
+#define __SHSUB16                         __shsub16
+#define __USUB16                          __usub16
+#define __UQSUB16                         __uqsub16
+#define __UHSUB16                         __uhsub16
+#define __SASX                            __sasx
+#define __QASX                            __qasx
+#define __SHASX                           __shasx
+#define __UASX                            __uasx
+#define __UQASX                           __uqasx
+#define __UHASX                           __uhasx
+#define __SSAX                            __ssax
+#define __QSAX                            __qsax
+#define __SHSAX                           __shsax
+#define __USAX                            __usax
+#define __UQSAX                           __uqsax
+#define __UHSAX                           __uhsax
+#define __USAD8                           __usad8
+#define __USADA8                          __usada8
+#define __SSAT16                          __ssat16
+#define __USAT16                          __usat16
+#define __UXTB16                          __uxtb16
+#define __UXTAB16                         __uxtab16
+#define __SXTB16                          __sxtb16
+#define __SXTAB16                         __sxtab16
+#define __SMUAD                           __smuad
+#define __SMUADX                          __smuadx
+#define __SMLAD                           __smlad
+#define __SMLADX                          __smladx
+#define __SMLALD                          __smlald
+#define __SMLALDX                         __smlaldx
+#define __SMUSD                           __smusd
+#define __SMUSDX                          __smusdx
+#define __SMLSD                           __smlsd
+#define __SMLSDX                          __smlsdx
+#define __SMLSLD                          __smlsld
+#define __SMLSLDX                         __smlsldx
+#define __SEL                             __sel
+#define __QADD                            __qadd
+#define __QSUB                            __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0x0000FFFFUL) |  \
+                                           ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)  )
+
+#define __PKHTB(ARG1,ARG2,ARG3)          ( ((((uint32_t)(ARG1))          ) & 0xFFFF0000UL) |  \
+                                           ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)  )
+
+#define __SMMLA(ARG1,ARG2,ARG3)          ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+                                                      ((int64_t)(ARG3) << 32)      ) >> 32))
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat16 %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+  uint32_t result;
+
+  __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+  union llreg_u{
+    uint32_t w32[2];
+    uint64_t w64;
+  } llr;
+  llr.w64 = acc;
+
+#ifndef __ARMEB__   // Little endian
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else               // Big endian
+  __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+  return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL  (uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
+{
+  uint32_t result;
+
+  __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+  return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+  if (ARG3 == 0) \
+    __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2)  ); \
+  else \
+    __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) :  "r" (__ARG1), "r" (__ARG2), "I" (ARG3)  ); \
+  __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r"  (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+/* not yet supported */
+
+
+#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
+/* Cosmic specific functions */
+#include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,48 @@
+/* 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:
+ *
+ *   * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (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 NRF_H
+#define NRF_H
+
+#ifndef _WIN32
+
+/* Family selection for main includes. NRF51 must be selected. */
+#ifdef NRF51
+    #include "nrf51.h"
+    #include "nrf51_bitfields.h"
+#else
+    #error "Device family must be defined. See nrf.h."
+#endif /* NRF51 */
+
+#include "compiler_abstraction.h"
+
+#endif /* _WIN32 */
+
+#endif /* NRF_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf51.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1263 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF51_H
+#define NRF51_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* -------------------------  Interrupt Number Definition  ------------------------ */
+
+typedef enum {
+/* -------------------  Cortex-M0 Processor Exceptions Numbers  ------------------- */
+  Reset_IRQn                    = -15,              /*!<   1  Reset Vector, invoked on Power up and warm reset                 */
+  NonMaskableInt_IRQn           = -14,              /*!<   2  Non maskable Interrupt, cannot be stopped or preempted           */
+  HardFault_IRQn                = -13,              /*!<   3  Hard Fault, all classes of Fault                                 */
+  SVCall_IRQn                   =  -5,              /*!<  11  System Service Call via SVC instruction                          */
+  DebugMonitor_IRQn             =  -4,              /*!<  12  Debug Monitor                                                    */
+  PendSV_IRQn                   =  -2,              /*!<  14  Pendable request for system service                              */
+  SysTick_IRQn                  =  -1,              /*!<  15  System Tick Timer                                                */
+/* ----------------------  nrf51 Specific Interrupt Numbers  ---------------------- */
+  POWER_CLOCK_IRQn              =   0,              /*!<   0  POWER_CLOCK                                                      */
+  RADIO_IRQn                    =   1,              /*!<   1  RADIO                                                            */
+  UART0_IRQn                    =   2,              /*!<   2  UART0                                                            */
+  SPI0_TWI0_IRQn                =   3,              /*!<   3  SPI0_TWI0                                                        */
+  SPI1_TWI1_IRQn                =   4,              /*!<   4  SPI1_TWI1                                                        */
+  GPIOTE_IRQn                   =   6,              /*!<   6  GPIOTE                                                           */
+  ADC_IRQn                      =   7,              /*!<   7  ADC                                                              */
+  TIMER0_IRQn                   =   8,              /*!<   8  TIMER0                                                           */
+  TIMER1_IRQn                   =   9,              /*!<   9  TIMER1                                                           */
+  TIMER2_IRQn                   =  10,              /*!<  10  TIMER2                                                           */
+  RTC0_IRQn                     =  11,              /*!<  11  RTC0                                                             */
+  TEMP_IRQn                     =  12,              /*!<  12  TEMP                                                             */
+  RNG_IRQn                      =  13,              /*!<  13  RNG                                                              */
+  ECB_IRQn                      =  14,              /*!<  14  ECB                                                              */
+  CCM_AAR_IRQn                  =  15,              /*!<  15  CCM_AAR                                                          */
+  WDT_IRQn                      =  16,              /*!<  16  WDT                                                              */
+  RTC1_IRQn                     =  17,              /*!<  17  RTC1                                                             */
+  QDEC_IRQn                     =  18,              /*!<  18  QDEC                                                             */
+  LPCOMP_IRQn                   =  19,              /*!<  19  LPCOMP                                                           */
+  SWI0_IRQn                     =  20,              /*!<  20  SWI0                                                             */
+  SWI1_IRQn                     =  21,              /*!<  21  SWI1                                                             */
+  SWI2_IRQn                     =  22,              /*!<  22  SWI2                                                             */
+  SWI3_IRQn                     =  23,              /*!<  23  SWI3                                                             */
+  SWI4_IRQn                     =  24,              /*!<  24  SWI4                                                             */
+  SWI5_IRQn                     =  25               /*!<  25  SWI5                                                             */
+} IRQn_Type;
+
+
+/** @addtogroup Configuration_of_CMSIS
+  * @{
+  */
+
+
+/* ================================================================================ */
+/* ================      Processor and Core Peripheral Section     ================ */
+/* ================================================================================ */
+
+/* ----------------Configuration of the Cortex-M0 Processor and Core Peripherals---------------- */
+#define __CM0_REV                 0x0301            /*!< Cortex-M0 Core Revision                                               */
+#define __MPU_PRESENT                  0            /*!< MPU present or not                                                    */
+#define __NVIC_PRIO_BITS               2            /*!< Number of Bits used for Priority Levels                               */
+#define __Vendor_SysTickConfig         0            /*!< Set to 1 if different SysTick Config is used                          */
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+#include "core_cm0.h"                               /*!< Cortex-M0 processor and core peripherals                              */
+#include "system_nrf51.h"                           /*!< nrf51 System                                                          */
+
+
+/* ================================================================================ */
+/* ================       Device Specific Peripheral Section       ================ */
+/* ================================================================================ */
+
+
+/** @addtogroup Device_Peripheral_Registers
+  * @{
+  */
+
+
+/* -------------------  Start of section using anonymous unions  ------------------ */
+#if defined(__CC_ARM)
+  #pragma push
+  #pragma anon_unions
+#elif defined(__ICCARM__)
+  #pragma language=extended
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TMS470__)
+/* anonymous unions are enabled by default */
+#elif defined(__TASKING__)
+  #pragma warning 586
+#else
+  #warning Not supported compiler type
+#endif
+
+
+typedef struct {
+  __IO uint32_t  CPU0;                              /*!< Configurable priority configuration register for CPU0.                */
+  __IO uint32_t  SPIS1;                             /*!< Configurable priority configuration register for SPIS1.               */
+  __IO uint32_t  RADIO;                             /*!< Configurable priority configuration register for RADIO.               */
+  __IO uint32_t  ECB;                               /*!< Configurable priority configuration register for ECB.                 */
+  __IO uint32_t  CCM;                               /*!< Configurable priority configuration register for CCM.                 */
+  __IO uint32_t  AAR;                               /*!< Configurable priority configuration register for AAR.                 */
+} AMLI_RAMPRI_Type;
+
+typedef struct {
+  __IO uint32_t  SCK;                               /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  MOSI;                              /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  MISO;                              /*!< Pin select for MISO.                                                  */
+} SPIM_PSEL_Type;
+
+typedef struct {
+  __IO uint32_t  PTR;                               /*!< Data pointer.                                                         */
+  __IO uint32_t  MAXCNT;                            /*!< Maximum number of buffer bytes to receive.                            */
+  __I  uint32_t  AMOUNT;                            /*!< Number of bytes received in the last transaction.                     */
+} SPIM_RXD_Type;
+
+typedef struct {
+  __IO uint32_t  PTR;                               /*!< Data pointer.                                                         */
+  __IO uint32_t  MAXCNT;                            /*!< Maximum number of buffer bytes to send.                               */
+  __I  uint32_t  AMOUNT;                            /*!< Number of bytes sent in the last transaction.                         */
+} SPIM_TXD_Type;
+
+typedef struct {
+  __O  uint32_t  EN;                                /*!< Enable channel group.                                                 */
+  __O  uint32_t  DIS;                               /*!< Disable channel group.                                                */
+} PPI_TASKS_CHG_Type;
+
+typedef struct {
+  __IO uint32_t  EEP;                               /*!< Channel event end-point.                                              */
+  __IO uint32_t  TEP;                               /*!< Channel task end-point.                                               */
+} PPI_CH_Type;
+
+
+/* ================================================================================ */
+/* ================                      POWER                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Power Control. (POWER)
+  */
+
+typedef struct {                                    /*!< POWER Structure                                                       */
+  __I  uint32_t  RESERVED0[30];
+  __O  uint32_t  TASKS_CONSTLAT;                    /*!< Enable constant latency mode.                                         */
+  __O  uint32_t  TASKS_LOWPWR;                      /*!< Enable low power mode (variable latency).                             */
+  __I  uint32_t  RESERVED1[34];
+  __IO uint32_t  EVENTS_POFWARN;                    /*!< Power failure warning.                                                */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __IO uint32_t  RESETREAS;                         /*!< Reset reason.                                                         */
+  __I  uint32_t  RESERVED4[9];
+  __I  uint32_t  RAMSTATUS;                         /*!< Ram status register.                                                  */
+  __I  uint32_t  RESERVED5[53];
+  __O  uint32_t  SYSTEMOFF;                         /*!< System off register.                                                  */
+  __I  uint32_t  RESERVED6[3];
+  __IO uint32_t  POFCON;                            /*!< Power failure configuration.                                          */
+  __I  uint32_t  RESERVED7[2];
+  __IO uint32_t  GPREGRET;                          /*!< General purpose retention register. This register is a retained
+                                                         register.                                                             */
+  __I  uint32_t  RESERVED8;
+  __IO uint32_t  RAMON;                             /*!< Ram on/off.                                                           */
+  __I  uint32_t  RESERVED9[7];
+  __IO uint32_t  RESET;                             /*!< Pin reset functionality configuration register. This register
+                                                         is a retained register.                                               */
+  __I  uint32_t  RESERVED10[3];
+  __IO uint32_t  RAMONB;                            /*!< Ram on/off.                                                           */
+  __I  uint32_t  RESERVED11[8];
+  __IO uint32_t  DCDCEN;                            /*!< DCDC converter enable configuration register.                         */
+  __I  uint32_t  RESERVED12[291];
+  __IO uint32_t  DCDCFORCE;                         /*!< DCDC power-up force register.                                         */
+} NRF_POWER_Type;
+
+
+/* ================================================================================ */
+/* ================                      CLOCK                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Clock control. (CLOCK)
+  */
+
+typedef struct {                                    /*!< CLOCK Structure                                                       */
+  __O  uint32_t  TASKS_HFCLKSTART;                  /*!< Start HFCLK clock source.                                             */
+  __O  uint32_t  TASKS_HFCLKSTOP;                   /*!< Stop HFCLK clock source.                                              */
+  __O  uint32_t  TASKS_LFCLKSTART;                  /*!< Start LFCLK clock source.                                             */
+  __O  uint32_t  TASKS_LFCLKSTOP;                   /*!< Stop LFCLK clock source.                                              */
+  __O  uint32_t  TASKS_CAL;                         /*!< Start calibration of LFCLK RC oscillator.                             */
+  __O  uint32_t  TASKS_CTSTART;                     /*!< Start calibration timer.                                              */
+  __O  uint32_t  TASKS_CTSTOP;                      /*!< Stop calibration timer.                                               */
+  __I  uint32_t  RESERVED0[57];
+  __IO uint32_t  EVENTS_HFCLKSTARTED;               /*!< HFCLK oscillator started.                                             */
+  __IO uint32_t  EVENTS_LFCLKSTARTED;               /*!< LFCLK oscillator started.                                             */
+  __I  uint32_t  RESERVED1;
+  __IO uint32_t  EVENTS_DONE;                       /*!< Calibration of LFCLK RC oscillator completed.                         */
+  __IO uint32_t  EVENTS_CTTO;                       /*!< Calibration timer timeout.                                            */
+  __I  uint32_t  RESERVED2[124];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[63];
+  __I  uint32_t  HFCLKRUN;                          /*!< Task HFCLKSTART trigger status.                                       */
+  __I  uint32_t  HFCLKSTAT;                         /*!< High frequency clock status.                                          */
+  __I  uint32_t  RESERVED4;
+  __I  uint32_t  LFCLKRUN;                          /*!< Task LFCLKSTART triggered status.                                     */
+  __I  uint32_t  LFCLKSTAT;                         /*!< Low frequency clock status.                                           */
+  __I  uint32_t  LFCLKSRCCOPY;                      /*!< Clock source for the LFCLK clock, set when task LKCLKSTART is
+                                                         triggered.                                                            */
+  __I  uint32_t  RESERVED5[62];
+  __IO uint32_t  LFCLKSRC;                          /*!< Clock source for the LFCLK clock.                                     */
+  __I  uint32_t  RESERVED6[7];
+  __IO uint32_t  CTIV;                              /*!< Calibration timer interval.                                           */
+  __I  uint32_t  RESERVED7[5];
+  __IO uint32_t  XTALFREQ;                          /*!< Crystal frequency.                                                    */
+} NRF_CLOCK_Type;
+
+
+/* ================================================================================ */
+/* ================                       MPU                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Memory Protection Unit. (MPU)
+  */
+
+typedef struct {                                    /*!< MPU Structure                                                         */
+  __I  uint32_t  RESERVED0[330];
+  __IO uint32_t  PERR0;                             /*!< Configuration of peripherals in mpu regions.                          */
+  __IO uint32_t  RLENR0;                            /*!< Length of RAM region 0.                                               */
+  __I  uint32_t  RESERVED1[52];
+  __IO uint32_t  PROTENSET0;                        /*!< Erase and write protection bit enable set register.                   */
+  __IO uint32_t  PROTENSET1;                        /*!< Erase and write protection bit enable set register.                   */
+  __IO uint32_t  DISABLEINDEBUG;                    /*!< Disable erase and write protection mechanism in debug mode.           */
+  __IO uint32_t  PROTBLOCKSIZE;                     /*!< Erase and write protection block size.                                */
+} NRF_MPU_Type;
+
+
+/* ================================================================================ */
+/* ================                      AMLI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AHB Multi-Layer Interface. (AMLI)
+  */
+
+typedef struct {                                    /*!< AMLI Structure                                                        */
+  __I  uint32_t  RESERVED0[896];
+  AMLI_RAMPRI_Type RAMPRI;                          /*!< RAM configurable priority configuration structure.                    */
+} NRF_AMLI_Type;
+
+
+/* ================================================================================ */
+/* ================                      RADIO                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief The radio. (RADIO)
+  */
+
+typedef struct {                                    /*!< RADIO Structure                                                       */
+  __O  uint32_t  TASKS_TXEN;                        /*!< Enable radio in TX mode.                                              */
+  __O  uint32_t  TASKS_RXEN;                        /*!< Enable radio in RX mode.                                              */
+  __O  uint32_t  TASKS_START;                       /*!< Start radio.                                                          */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop radio.                                                           */
+  __O  uint32_t  TASKS_DISABLE;                     /*!< Disable radio.                                                        */
+  __O  uint32_t  TASKS_RSSISTART;                   /*!< Start the RSSI and take one sample of the receive signal strength.    */
+  __O  uint32_t  TASKS_RSSISTOP;                    /*!< Stop the RSSI measurement.                                            */
+  __O  uint32_t  TASKS_BCSTART;                     /*!< Start the bit counter.                                                */
+  __O  uint32_t  TASKS_BCSTOP;                      /*!< Stop the bit counter.                                                 */
+  __I  uint32_t  RESERVED0[55];
+  __IO uint32_t  EVENTS_READY;                      /*!< Ready event.                                                          */
+  __IO uint32_t  EVENTS_ADDRESS;                    /*!< Address event.                                                        */
+  __IO uint32_t  EVENTS_PAYLOAD;                    /*!< Payload event.                                                        */
+  __IO uint32_t  EVENTS_END;                        /*!< End event.                                                            */
+  __IO uint32_t  EVENTS_DISABLED;                   /*!< Disable event.                                                        */
+  __IO uint32_t  EVENTS_DEVMATCH;                   /*!< A device address match occurred on the last received packet.          */
+  __IO uint32_t  EVENTS_DEVMISS;                    /*!< No device address match occurred on the last received packet.         */
+  __IO uint32_t  EVENTS_RSSIEND;                    /*!< Sampling of the receive signal strength complete. A new RSSI
+                                                         sample is ready for readout at the RSSISAMPLE register.               */
+  __I  uint32_t  RESERVED1[2];
+  __IO uint32_t  EVENTS_BCMATCH;                    /*!< Bit counter reached bit count value specified in BCC register.        */
+  __I  uint32_t  RESERVED2[53];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the radio.                                              */
+  __I  uint32_t  RESERVED3[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED4[61];
+  __I  uint32_t  CRCSTATUS;                         /*!< CRC status of received packet.                                        */
+  __I  uint32_t  RESERVED5;
+  __I  uint32_t  RXMATCH;                           /*!< Received address.                                                     */
+  __I  uint32_t  RXCRC;                             /*!< Received CRC.                                                         */
+  __I  uint32_t  DAI;                               /*!< Device address match index.                                           */
+  __I  uint32_t  RESERVED6[60];
+  __IO uint32_t  PACKETPTR;                         /*!< Packet pointer. Decision point: START task.                           */
+  __IO uint32_t  FREQUENCY;                         /*!< Frequency.                                                            */
+  __IO uint32_t  TXPOWER;                           /*!< Output power.                                                         */
+  __IO uint32_t  MODE;                              /*!< Data rate and modulation.                                             */
+  __IO uint32_t  PCNF0;                             /*!< Packet configuration 0.                                               */
+  __IO uint32_t  PCNF1;                             /*!< Packet configuration 1.                                               */
+  __IO uint32_t  BASE0;                             /*!< Radio base address 0. Decision point: START task.                     */
+  __IO uint32_t  BASE1;                             /*!< Radio base address 1. Decision point: START task.                     */
+  __IO uint32_t  PREFIX0;                           /*!< Prefixes bytes for logical addresses 0 to 3.                          */
+  __IO uint32_t  PREFIX1;                           /*!< Prefixes bytes for logical addresses 4 to 7.                          */
+  __IO uint32_t  TXADDRESS;                         /*!< Transmit address select.                                              */
+  __IO uint32_t  RXADDRESSES;                       /*!< Receive address select.                                               */
+  __IO uint32_t  CRCCNF;                            /*!< CRC configuration.                                                    */
+  __IO uint32_t  CRCPOLY;                           /*!< CRC polynomial.                                                       */
+  __IO uint32_t  CRCINIT;                           /*!< CRC initial value.                                                    */
+  __IO uint32_t  TEST;                              /*!< Test features enable register.                                        */
+  __IO uint32_t  TIFS;                              /*!< Inter Frame Spacing in microseconds.                                  */
+  __I  uint32_t  RSSISAMPLE;                        /*!< RSSI sample.                                                          */
+  __I  uint32_t  RESERVED7;
+  __I  uint32_t  STATE;                             /*!< Current radio state.                                                  */
+  __IO uint32_t  DATAWHITEIV;                       /*!< Data whitening initial value.                                         */
+  __I  uint32_t  RESERVED8[2];
+  __IO uint32_t  BCC;                               /*!< Bit counter compare.                                                  */
+  __I  uint32_t  RESERVED9[39];
+  __IO uint32_t  DAB[8];                            /*!< Device address base segment.                                          */
+  __IO uint32_t  DAP[8];                            /*!< Device address prefix.                                                */
+  __IO uint32_t  DACNF;                             /*!< Device address match configuration.                                   */
+  __I  uint32_t  RESERVED10[56];
+  __IO uint32_t  OVERRIDE0;                         /*!< Trim value override register 0.                                       */
+  __IO uint32_t  OVERRIDE1;                         /*!< Trim value override register 1.                                       */
+  __IO uint32_t  OVERRIDE2;                         /*!< Trim value override register 2.                                       */
+  __IO uint32_t  OVERRIDE3;                         /*!< Trim value override register 3.                                       */
+  __IO uint32_t  OVERRIDE4;                         /*!< Trim value override register 4.                                       */
+  __I  uint32_t  RESERVED11[561];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RADIO_Type;
+
+
+/* ================================================================================ */
+/* ================                      UART                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Universal Asynchronous Receiver/Transmitter. (UART)
+  */
+
+typedef struct {                                    /*!< UART Structure                                                        */
+  __O  uint32_t  TASKS_STARTRX;                     /*!< Start UART receiver.                                                  */
+  __O  uint32_t  TASKS_STOPRX;                      /*!< Stop UART receiver.                                                   */
+  __O  uint32_t  TASKS_STARTTX;                     /*!< Start UART transmitter.                                               */
+  __O  uint32_t  TASKS_STOPTX;                      /*!< Stop UART transmitter.                                                */
+  __I  uint32_t  RESERVED0[3];
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend UART.                                                         */
+  __I  uint32_t  RESERVED1[56];
+  __IO uint32_t  EVENTS_CTS;                        /*!< CTS activated.                                                        */
+  __IO uint32_t  EVENTS_NCTS;                       /*!< CTS deactivated.                                                      */
+  __IO uint32_t  EVENTS_RXDRDY;                     /*!< Data received in RXD.                                                 */
+  __I  uint32_t  RESERVED2[4];
+  __IO uint32_t  EVENTS_TXDRDY;                     /*!< Data sent from TXD.                                                   */
+  __I  uint32_t  RESERVED3;
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Error detected.                                                       */
+  __I  uint32_t  RESERVED4[7];
+  __IO uint32_t  EVENTS_RXTO;                       /*!< Receiver timeout.                                                     */
+  __I  uint32_t  RESERVED5[46];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for UART.                                                   */
+  __I  uint32_t  RESERVED6[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED7[93];
+  __IO uint32_t  ERRORSRC;                          /*!< Error source. Write error field to 1 to clear error.                  */
+  __I  uint32_t  RESERVED8[31];
+  __IO uint32_t  ENABLE;                            /*!< Enable UART and acquire IOs.                                          */
+  __I  uint32_t  RESERVED9;
+  __IO uint32_t  PSELRTS;                           /*!< Pin select for RTS.                                                   */
+  __IO uint32_t  PSELTXD;                           /*!< Pin select for TXD.                                                   */
+  __IO uint32_t  PSELCTS;                           /*!< Pin select for CTS.                                                   */
+  __IO uint32_t  PSELRXD;                           /*!< Pin select for RXD.                                                   */
+  __I  uint32_t  RXD;                               /*!< RXD register. On read action the buffer pointer is displaced.
+                                                         Once read the character is consumed. If read when no character
+                                                          available, the UART will stop working.                               */
+  __O  uint32_t  TXD;                               /*!< TXD register.                                                         */
+  __I  uint32_t  RESERVED10;
+  __IO uint32_t  BAUDRATE;                          /*!< UART Baudrate.                                                        */
+  __I  uint32_t  RESERVED11[17];
+  __IO uint32_t  CONFIG;                            /*!< Configuration of parity and hardware flow control register.           */
+  __I  uint32_t  RESERVED12[675];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_UART_Type;
+
+
+/* ================================================================================ */
+/* ================                       SPI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI master 0. (SPI)
+  */
+
+typedef struct {                                    /*!< SPI Structure                                                         */
+  __I  uint32_t  RESERVED0[66];
+  __IO uint32_t  EVENTS_READY;                      /*!< TXD byte sent and RXD byte received.                                  */
+  __I  uint32_t  RESERVED1[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPI.                                                           */
+  __I  uint32_t  RESERVED3;
+  __IO uint32_t  PSELSCK;                           /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  PSELMOSI;                          /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  PSELMISO;                          /*!< Pin select for MISO.                                                  */
+  __I  uint32_t  RESERVED4;
+  __I  uint32_t  RXD;                               /*!< RX data.                                                              */
+  __IO uint32_t  TXD;                               /*!< TX data.                                                              */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  FREQUENCY;                         /*!< SPI frequency                                                         */
+  __I  uint32_t  RESERVED6[11];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED7[681];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPI_Type;
+
+
+/* ================================================================================ */
+/* ================                       TWI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Two-wire interface master 0. (TWI)
+  */
+
+typedef struct {                                    /*!< TWI Structure                                                         */
+  __O  uint32_t  TASKS_STARTRX;                     /*!< Start 2-Wire master receive sequence.                                 */
+  __I  uint32_t  RESERVED0;
+  __O  uint32_t  TASKS_STARTTX;                     /*!< Start 2-Wire master transmit sequence.                                */
+  __I  uint32_t  RESERVED1[2];
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop 2-Wire transaction.                                              */
+  __I  uint32_t  RESERVED2;
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend 2-Wire transaction.                                           */
+  __O  uint32_t  TASKS_RESUME;                      /*!< Resume 2-Wire transaction.                                            */
+  __I  uint32_t  RESERVED3[56];
+  __IO uint32_t  EVENTS_STOPPED;                    /*!< Two-wire stopped.                                                     */
+  __IO uint32_t  EVENTS_RXDREADY;                   /*!< Two-wire ready to deliver new RXD byte received.                      */
+  __I  uint32_t  RESERVED4[4];
+  __IO uint32_t  EVENTS_TXDSENT;                    /*!< Two-wire finished sending last TXD byte.                              */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Two-wire error detected.                                              */
+  __I  uint32_t  RESERVED6[4];
+  __IO uint32_t  EVENTS_BB;                         /*!< Two-wire byte boundary.                                               */
+  __I  uint32_t  RESERVED7[3];
+  __IO uint32_t  EVENTS_SUSPENDED;                  /*!< Two-wire suspended.                                                   */
+  __I  uint32_t  RESERVED8[45];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for TWI.                                                    */
+  __I  uint32_t  RESERVED9[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED10[110];
+  __IO uint32_t  ERRORSRC;                          /*!< Two-wire error source. Write error field to 1 to clear error.         */
+  __I  uint32_t  RESERVED11[14];
+  __IO uint32_t  ENABLE;                            /*!< Enable two-wire master.                                               */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  PSELSCL;                           /*!< Pin select for SCL.                                                   */
+  __IO uint32_t  PSELSDA;                           /*!< Pin select for SDA.                                                   */
+  __I  uint32_t  RESERVED13[2];
+  __I  uint32_t  RXD;                               /*!< RX data register.                                                     */
+  __IO uint32_t  TXD;                               /*!< TX data register.                                                     */
+  __I  uint32_t  RESERVED14;
+  __IO uint32_t  FREQUENCY;                         /*!< Two-wire frequency.                                                   */
+  __I  uint32_t  RESERVED15[24];
+  __IO uint32_t  ADDRESS;                           /*!< Address used in the two-wire transfer.                                */
+  __I  uint32_t  RESERVED16[668];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TWI_Type;
+
+
+/* ================================================================================ */
+/* ================                      SPIS                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI slave 1. (SPIS)
+  */
+
+typedef struct {                                    /*!< SPIS Structure                                                        */
+  __I  uint32_t  RESERVED0[9];
+  __O  uint32_t  TASKS_ACQUIRE;                     /*!< Acquire SPI semaphore.                                                */
+  __O  uint32_t  TASKS_RELEASE;                     /*!< Release SPI semaphore.                                                */
+  __I  uint32_t  RESERVED1[54];
+  __IO uint32_t  EVENTS_END;                        /*!< Granted transaction completed.                                        */
+  __I  uint32_t  RESERVED2[2];
+  __IO uint32_t  EVENTS_ENDRX;                      /*!< End of RXD buffer reached                                             */
+  __I  uint32_t  RESERVED3[5];
+  __IO uint32_t  EVENTS_ACQUIRED;                   /*!< Semaphore acquired.                                                   */
+  __I  uint32_t  RESERVED4[53];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for SPIS.                                                   */
+  __I  uint32_t  RESERVED5[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED6[61];
+  __I  uint32_t  SEMSTAT;                           /*!< Semaphore status.                                                     */
+  __I  uint32_t  RESERVED7[15];
+  __IO uint32_t  STATUS;                            /*!< Status from last transaction.                                         */
+  __I  uint32_t  RESERVED8[47];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPIS.                                                          */
+  __I  uint32_t  RESERVED9;
+  __IO uint32_t  PSELSCK;                           /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  PSELMISO;                          /*!< Pin select for MISO.                                                  */
+  __IO uint32_t  PSELMOSI;                          /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  PSELCSN;                           /*!< Pin select for CSN.                                                   */
+  __I  uint32_t  RESERVED10[7];
+  __IO uint32_t  RXDPTR;                            /*!< RX data pointer.                                                      */
+  __IO uint32_t  MAXRX;                             /*!< Maximum number of bytes in the receive buffer.                        */
+  __I  uint32_t  AMOUNTRX;                          /*!< Number of bytes received in last granted transaction.                 */
+  __I  uint32_t  RESERVED11;
+  __IO uint32_t  TXDPTR;                            /*!< TX data pointer.                                                      */
+  __IO uint32_t  MAXTX;                             /*!< Maximum number of bytes in the transmit buffer.                       */
+  __I  uint32_t  AMOUNTTX;                          /*!< Number of bytes transmitted in last granted transaction.              */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED13;
+  __IO uint32_t  DEF;                               /*!< Default character.                                                    */
+  __I  uint32_t  RESERVED14[24];
+  __IO uint32_t  ORC;                               /*!< Over-read character.                                                  */
+  __I  uint32_t  RESERVED15[654];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPIS_Type;
+
+
+/* ================================================================================ */
+/* ================                      SPIM                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI master with easyDMA 1. (SPIM)
+  */
+
+typedef struct {                                    /*!< SPIM Structure                                                        */
+  __I  uint32_t  RESERVED0[4];
+  __O  uint32_t  TASKS_START;                       /*!< Start SPI transaction.                                                */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop SPI transaction.                                                 */
+  __I  uint32_t  RESERVED1;
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend SPI transaction.                                              */
+  __O  uint32_t  TASKS_RESUME;                      /*!< Resume SPI transaction.                                               */
+  __I  uint32_t  RESERVED2[56];
+  __IO uint32_t  EVENTS_STOPPED;                    /*!< SPI transaction has stopped.                                          */
+  __I  uint32_t  RESERVED3[2];
+  __IO uint32_t  EVENTS_ENDRX;                      /*!< End of RXD buffer reached.                                            */
+  __I  uint32_t  RESERVED4[3];
+  __IO uint32_t  EVENTS_ENDTX;                      /*!< End of TXD buffer reached.                                            */
+  __I  uint32_t  RESERVED5[10];
+  __IO uint32_t  EVENTS_STARTED;                    /*!< Transaction started.                                                  */
+  __I  uint32_t  RESERVED6[109];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED7[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPIM.                                                          */
+  __I  uint32_t  RESERVED8;
+  SPIM_PSEL_Type PSEL;                              /*!< Pin select configuration.                                             */
+  __I  uint32_t  RESERVED9[4];
+  __IO uint32_t  FREQUENCY;                         /*!< SPI frequency.                                                        */
+  __I  uint32_t  RESERVED10[3];
+  SPIM_RXD_Type RXD;                                /*!< RXD EasyDMA configuration and status.                                 */
+  __I  uint32_t  RESERVED11;
+  SPIM_TXD_Type TXD;                                /*!< TXD EasyDMA configuration and status.                                 */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED13[26];
+  __IO uint32_t  ORC;                               /*!< Over-read character.                                                  */
+  __I  uint32_t  RESERVED14[654];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPIM_Type;
+
+
+/* ================================================================================ */
+/* ================                     GPIOTE                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief GPIO tasks and events. (GPIOTE)
+  */
+
+typedef struct {                                    /*!< GPIOTE Structure                                                      */
+  __O  uint32_t  TASKS_OUT[4];                      /*!< Tasks asssociated with GPIOTE channels.                               */
+  __I  uint32_t  RESERVED0[60];
+  __IO uint32_t  EVENTS_IN[4];                      /*!< Tasks asssociated with GPIOTE channels.                               */
+  __I  uint32_t  RESERVED1[27];
+  __IO uint32_t  EVENTS_PORT;                       /*!< Event generated from multiple pins.                                   */
+  __I  uint32_t  RESERVED2[97];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[129];
+  __IO uint32_t  CONFIG[4];                         /*!< Channel configuration registers.                                      */
+  __I  uint32_t  RESERVED4[695];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_GPIOTE_Type;
+
+
+/* ================================================================================ */
+/* ================                       ADC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Analog to digital converter. (ADC)
+  */
+
+typedef struct {                                    /*!< ADC Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start an ADC conversion.                                              */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop ADC.                                                             */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_END;                        /*!< ADC conversion complete.                                              */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[61];
+  __I  uint32_t  BUSY;                              /*!< ADC busy register.                                                    */
+  __I  uint32_t  RESERVED3[63];
+  __IO uint32_t  ENABLE;                            /*!< ADC enable.                                                           */
+  __IO uint32_t  CONFIG;                            /*!< ADC configuration register.                                           */
+  __I  uint32_t  RESULT;                            /*!< Result of ADC conversion.                                             */
+  __I  uint32_t  RESERVED4[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_ADC_Type;
+
+
+/* ================================================================================ */
+/* ================                      TIMER                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Timer 0. (TIMER)
+  */
+
+typedef struct {                                    /*!< TIMER Structure                                                       */
+  __O  uint32_t  TASKS_START;                       /*!< Start Timer.                                                          */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop Timer.                                                           */
+  __O  uint32_t  TASKS_COUNT;                       /*!< Increment Timer (In counter mode).                                    */
+  __O  uint32_t  TASKS_CLEAR;                       /*!< Clear timer.                                                          */
+  __O  uint32_t  TASKS_SHUTDOWN;                    /*!< Shutdown timer.                                                       */
+  __I  uint32_t  RESERVED0[11];
+  __O  uint32_t  TASKS_CAPTURE[4];                  /*!< Capture Timer value to CC[n] registers.                               */
+  __I  uint32_t  RESERVED1[60];
+  __IO uint32_t  EVENTS_COMPARE[4];                 /*!< Compare event on CC[n] match.                                         */
+  __I  uint32_t  RESERVED2[44];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for Timer.                                                  */
+  __I  uint32_t  RESERVED3[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED4[126];
+  __IO uint32_t  MODE;                              /*!< Timer Mode selection.                                                 */
+  __IO uint32_t  BITMODE;                           /*!< Sets timer behaviour.                                                 */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  PRESCALER;                         /*!< 4-bit prescaler to source clock frequency (max value 9). Source
+                                                         clock frequency is divided by 2^SCALE.                                */
+  __I  uint32_t  RESERVED6[11];
+  __IO uint32_t  CC[4];                             /*!< Capture/compare registers.                                            */
+  __I  uint32_t  RESERVED7[683];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TIMER_Type;
+
+
+/* ================================================================================ */
+/* ================                       RTC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Real time counter 0. (RTC)
+  */
+
+typedef struct {                                    /*!< RTC Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start RTC Counter.                                                    */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop RTC Counter.                                                     */
+  __O  uint32_t  TASKS_CLEAR;                       /*!< Clear RTC Counter.                                                    */
+  __O  uint32_t  TASKS_TRIGOVRFLW;                  /*!< Set COUNTER to 0xFFFFFFF0.                                            */
+  __I  uint32_t  RESERVED0[60];
+  __IO uint32_t  EVENTS_TICK;                       /*!< Event on COUNTER increment.                                           */
+  __IO uint32_t  EVENTS_OVRFLW;                     /*!< Event on COUNTER overflow.                                            */
+  __I  uint32_t  RESERVED1[14];
+  __IO uint32_t  EVENTS_COMPARE[4];                 /*!< Compare event on CC[n] match.                                         */
+  __I  uint32_t  RESERVED2[109];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[13];
+  __IO uint32_t  EVTEN;                             /*!< Configures event enable routing to PPI for each RTC event.            */
+  __IO uint32_t  EVTENSET;                          /*!< Enable events routing to PPI. The reading of this register gives
+                                                         the value of EVTEN.                                                   */
+  __IO uint32_t  EVTENCLR;                          /*!< Disable events routing to PPI. The reading of this register
+                                                         gives the value of EVTEN.                                             */
+  __I  uint32_t  RESERVED4[110];
+  __I  uint32_t  COUNTER;                           /*!< Current COUNTER value.                                                */
+  __IO uint32_t  PRESCALER;                         /*!< 12-bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+                                                         Must be written when RTC is STOPed.                                   */
+  __I  uint32_t  RESERVED5[13];
+  __IO uint32_t  CC[4];                             /*!< Capture/compare registers.                                            */
+  __I  uint32_t  RESERVED6[683];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RTC_Type;
+
+
+/* ================================================================================ */
+/* ================                      TEMP                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Temperature Sensor. (TEMP)
+  */
+
+typedef struct {                                    /*!< TEMP Structure                                                        */
+  __O  uint32_t  TASKS_START;                       /*!< Start temperature measurement.                                        */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop temperature measurement.                                         */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_DATARDY;                    /*!< Temperature measurement complete, data ready event.                   */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[127];
+  __I  int32_t   TEMP;                              /*!< Die temperature in degC, 2's complement format, 0.25 degC pecision.   */
+  __I  uint32_t  RESERVED3[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TEMP_Type;
+
+
+/* ================================================================================ */
+/* ================                       RNG                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Random Number Generator. (RNG)
+  */
+
+typedef struct {                                    /*!< RNG Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start the random number generator.                                    */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the random number generator.                                     */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_VALRDY;                     /*!< New random number generated and written to VALUE register.            */
+  __I  uint32_t  RESERVED1[63];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the RNG.                                                */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register                                         */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register                                       */
+  __I  uint32_t  RESERVED3[126];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  VALUE;                             /*!< RNG random number.                                                    */
+  __I  uint32_t  RESERVED4[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RNG_Type;
+
+
+/* ================================================================================ */
+/* ================                       ECB                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AES ECB Mode Encryption. (ECB)
+  */
+
+typedef struct {                                    /*!< ECB Structure                                                         */
+  __O  uint32_t  TASKS_STARTECB;                    /*!< Start ECB block encrypt. If a crypto operation is running, this
+                                                         will not initiate a new encryption and the ERRORECB event will
+                                                          be triggered.                                                        */
+  __O  uint32_t  TASKS_STOPECB;                     /*!< Stop current ECB encryption. If a crypto operation is running,
+                                                         this will will trigger the ERRORECB event.                            */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_ENDECB;                     /*!< ECB block encrypt complete.                                           */
+  __IO uint32_t  EVENTS_ERRORECB;                   /*!< ECB block encrypt aborted due to a STOPECB task or due to an
+                                                         error.                                                                */
+  __I  uint32_t  RESERVED1[127];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  ECBDATAPTR;                        /*!< ECB block encrypt memory pointer.                                     */
+  __I  uint32_t  RESERVED3[701];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_ECB_Type;
+
+
+/* ================================================================================ */
+/* ================                       AAR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Accelerated Address Resolver. (AAR)
+  */
+
+typedef struct {                                    /*!< AAR Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start resolving addresses based on IRKs specified in the IRK
+                                                         data structure.                                                       */
+  __I  uint32_t  RESERVED0;
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop resolving addresses.                                             */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  EVENTS_END;                        /*!< Address resolution procedure completed.                               */
+  __IO uint32_t  EVENTS_RESOLVED;                   /*!< Address resolved.                                                     */
+  __IO uint32_t  EVENTS_NOTRESOLVED;                /*!< Address not resolved.                                                 */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  STATUS;                            /*!< Resolution status.                                                    */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< Enable AAR.                                                           */
+  __IO uint32_t  NIRK;                              /*!< Number of Identity root Keys in the IRK data structure.               */
+  __IO uint32_t  IRKPTR;                            /*!< Pointer to the IRK data structure.                                    */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  ADDRPTR;                           /*!< Pointer to the resolvable address (6 bytes).                          */
+  __IO uint32_t  SCRATCHPTR;                        /*!< Pointer to a "scratch" data area used for temporary storage
+                                                         during resolution. A minimum of 3 bytes must be reserved.             */
+  __I  uint32_t  RESERVED6[697];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_AAR_Type;
+
+
+/* ================================================================================ */
+/* ================                       CCM                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AES CCM Mode Encryption. (CCM)
+  */
+
+typedef struct {                                    /*!< CCM Structure                                                         */
+  __O  uint32_t  TASKS_KSGEN;                       /*!< Start generation of key-stream. This operation will stop by
+                                                         itself when completed.                                                */
+  __O  uint32_t  TASKS_CRYPT;                       /*!< Start encrypt/decrypt. This operation will stop by itself when
+                                                         completed.                                                            */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop encrypt/decrypt.                                                 */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_ENDKSGEN;                   /*!< Keystream generation completed.                                       */
+  __IO uint32_t  EVENTS_ENDCRYPT;                   /*!< Encrypt/decrypt completed.                                            */
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Error happened.                                                       */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the CCM.                                                */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  MICSTATUS;                         /*!< CCM RX MIC check result.                                              */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< CCM enable.                                                           */
+  __IO uint32_t  MODE;                              /*!< Operation mode.                                                       */
+  __IO uint32_t  CNFPTR;                            /*!< Pointer to a data structure holding AES key and NONCE vector.         */
+  __IO uint32_t  INPTR;                             /*!< Pointer to the input packet.                                          */
+  __IO uint32_t  OUTPTR;                            /*!< Pointer to the output packet.                                         */
+  __IO uint32_t  SCRATCHPTR;                        /*!< Pointer to a "scratch" data area used for temporary storage
+                                                         during resolution. A minimum of 43 bytes must be reserved.            */
+  __I  uint32_t  RESERVED5[697];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_CCM_Type;
+
+
+/* ================================================================================ */
+/* ================                       WDT                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Watchdog Timer. (WDT)
+  */
+
+typedef struct {                                    /*!< WDT Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start the watchdog.                                                   */
+  __I  uint32_t  RESERVED0[63];
+  __IO uint32_t  EVENTS_TIMEOUT;                    /*!< Watchdog timeout.                                                     */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[61];
+  __I  uint32_t  RUNSTATUS;                         /*!< Watchdog running status.                                              */
+  __I  uint32_t  REQSTATUS;                         /*!< Request status.                                                       */
+  __I  uint32_t  RESERVED3[63];
+  __IO uint32_t  CRV;                               /*!< Counter reload value in number of 32kiHz clock cycles.                */
+  __IO uint32_t  RREN;                              /*!< Reload request enable.                                                */
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED4[60];
+  __O  uint32_t  RR[8];                             /*!< Reload requests registers.                                            */
+  __I  uint32_t  RESERVED5[631];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_WDT_Type;
+
+
+/* ================================================================================ */
+/* ================                      QDEC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Rotary decoder. (QDEC)
+  */
+
+typedef struct {                                    /*!< QDEC Structure                                                        */
+  __O  uint32_t  TASKS_START;                       /*!< Start the quadrature decoder.                                         */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the quadrature decoder.                                          */
+  __O  uint32_t  TASKS_READCLRACC;                  /*!< Transfers the content from ACC registers to ACCREAD registers,
+                                                         and clears the ACC registers.                                         */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_SAMPLERDY;                  /*!< A new sample is written to the sample register.                       */
+  __IO uint32_t  EVENTS_REPORTRDY;                  /*!< REPORTPER number of samples accumulated in ACC register, and
+                                                         ACC register different than zero.                                     */
+  __IO uint32_t  EVENTS_ACCOF;                      /*!< ACC or ACCDBL register overflow.                                      */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the QDEC.                                               */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable the QDEC.                                                      */
+  __IO uint32_t  LEDPOL;                            /*!< LED output pin polarity.                                              */
+  __IO uint32_t  SAMPLEPER;                         /*!< Sample period.                                                        */
+  __I  int32_t   SAMPLE;                            /*!< Motion sample value.                                                  */
+  __IO uint32_t  REPORTPER;                         /*!< Number of samples to generate an EVENT_REPORTRDY.                     */
+  __I  int32_t   ACC;                               /*!< Accumulated valid transitions register.                               */
+  __I  int32_t   ACCREAD;                           /*!< Snapshot of ACC register. Value generated by the TASKS_READCLEACC
+                                                         task.                                                                 */
+  __IO uint32_t  PSELLED;                           /*!< Pin select for LED output.                                            */
+  __IO uint32_t  PSELA;                             /*!< Pin select for phase A input.                                         */
+  __IO uint32_t  PSELB;                             /*!< Pin select for phase B input.                                         */
+  __IO uint32_t  DBFEN;                             /*!< Enable debouncer input filters.                                       */
+  __I  uint32_t  RESERVED4[5];
+  __IO uint32_t  LEDPRE;                            /*!< Time LED is switched ON before the sample.                            */
+  __I  uint32_t  ACCDBL;                            /*!< Accumulated double (error) transitions register.                      */
+  __I  uint32_t  ACCDBLREAD;                        /*!< Snapshot of ACCDBL register. Value generated by the TASKS_READCLEACC
+                                                         task.                                                                 */
+  __I  uint32_t  RESERVED5[684];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_QDEC_Type;
+
+
+/* ================================================================================ */
+/* ================                     LPCOMP                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Low power comparator. (LPCOMP)
+  */
+
+typedef struct {                                    /*!< LPCOMP Structure                                                      */
+  __O  uint32_t  TASKS_START;                       /*!< Start the comparator.                                                 */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the comparator.                                                  */
+  __O  uint32_t  TASKS_SAMPLE;                      /*!< Sample comparator value.                                              */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_READY;                      /*!< LPCOMP is ready and output is valid.                                  */
+  __IO uint32_t  EVENTS_DOWN;                       /*!< Input voltage crossed the threshold going down.                       */
+  __IO uint32_t  EVENTS_UP;                         /*!< Input voltage crossed the threshold going up.                         */
+  __IO uint32_t  EVENTS_CROSS;                      /*!< Input voltage crossed the threshold in any direction.                 */
+  __I  uint32_t  RESERVED1[60];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the LPCOMP.                                             */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  RESULT;                            /*!< Result of last compare.                                               */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< Enable the LPCOMP.                                                    */
+  __IO uint32_t  PSEL;                              /*!< Input pin select.                                                     */
+  __IO uint32_t  REFSEL;                            /*!< Reference select.                                                     */
+  __IO uint32_t  EXTREFSEL;                         /*!< External reference select.                                            */
+  __I  uint32_t  RESERVED5[4];
+  __IO uint32_t  ANADETECT;                         /*!< Analog detect configuration.                                          */
+  __I  uint32_t  RESERVED6[694];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_LPCOMP_Type;
+
+
+/* ================================================================================ */
+/* ================                       SWI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SW Interrupts. (SWI)
+  */
+
+typedef struct {                                    /*!< SWI Structure                                                         */
+  __I  uint32_t  UNUSED;                            /*!< Unused.                                                               */
+} NRF_SWI_Type;
+
+
+/* ================================================================================ */
+/* ================                      NVMC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Non Volatile Memory Controller. (NVMC)
+  */
+
+typedef struct {                                    /*!< NVMC Structure                                                        */
+  __I  uint32_t  RESERVED0[256];
+  __I  uint32_t  READY;                             /*!< Ready flag.                                                           */
+  __I  uint32_t  RESERVED1[64];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  
+  union {
+    __IO uint32_t  ERASEPCR1;                       /*!< Register for erasing a non-protected non-volatile memory page.        */
+    __IO uint32_t  ERASEPAGE;                       /*!< Register for erasing a non-protected non-volatile memory page.        */
+  };
+  __IO uint32_t  ERASEALL;                          /*!< Register for erasing all non-volatile user memory.                    */
+  __IO uint32_t  ERASEPCR0;                         /*!< Register for erasing a protected non-volatile memory page.            */
+  __IO uint32_t  ERASEUICR;                         /*!< Register for start erasing User Information Congfiguration Registers. */
+} NRF_NVMC_Type;
+
+
+/* ================================================================================ */
+/* ================                       PPI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief PPI controller. (PPI)
+  */
+
+typedef struct {                                    /*!< PPI Structure                                                         */
+  PPI_TASKS_CHG_Type TASKS_CHG[4];                  /*!< Channel group tasks.                                                  */
+  __I  uint32_t  RESERVED0[312];
+  __IO uint32_t  CHEN;                              /*!< Channel enable.                                                       */
+  __IO uint32_t  CHENSET;                           /*!< Channel enable set.                                                   */
+  __IO uint32_t  CHENCLR;                           /*!< Channel enable clear.                                                 */
+  __I  uint32_t  RESERVED1;
+  PPI_CH_Type CH[16];                               /*!< PPI Channel.                                                          */
+  __I  uint32_t  RESERVED2[156];
+  __IO uint32_t  CHG[4];                            /*!< Channel group configuration.                                          */
+} NRF_PPI_Type;
+
+
+/* ================================================================================ */
+/* ================                      FICR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Factory Information Configuration. (FICR)
+  */
+
+typedef struct {                                    /*!< FICR Structure                                                        */
+  __I  uint32_t  RESERVED0[4];
+  __I  uint32_t  CODEPAGESIZE;                      /*!< Code memory page size in bytes.                                       */
+  __I  uint32_t  CODESIZE;                          /*!< Code memory size in pages.                                            */
+  __I  uint32_t  RESERVED1[4];
+  __I  uint32_t  CLENR0;                            /*!< Length of code region 0 in bytes.                                     */
+  __I  uint32_t  PPFC;                              /*!< Pre-programmed factory code present.                                  */
+  __I  uint32_t  RESERVED2;
+  __I  uint32_t  NUMRAMBLOCK;                       /*!< Number of individualy controllable RAM blocks.                        */
+  
+  union {
+    __I  uint32_t  SIZERAMBLOCK[4];                 /*!< Deprecated array of size of RAM block in bytes. This name is
+                                                         kept for backward compatinility purposes. Use SIZERAMBLOCKS
+                                                          instead.                                                             */
+    __I  uint32_t  SIZERAMBLOCKS;                   /*!< Size of RAM blocks in bytes.                                          */
+  };
+  __I  uint32_t  RESERVED3[5];
+  __I  uint32_t  CONFIGID;                          /*!< Configuration identifier.                                             */
+  __I  uint32_t  DEVICEID[2];                       /*!< Device identifier.                                                    */
+  __I  uint32_t  RESERVED4[6];
+  __I  uint32_t  ER[4];                             /*!< Encryption root.                                                      */
+  __I  uint32_t  IR[4];                             /*!< Identity root.                                                        */
+  __I  uint32_t  DEVICEADDRTYPE;                    /*!< Device address type.                                                  */
+  __I  uint32_t  DEVICEADDR[2];                     /*!< Device address.                                                       */
+  __I  uint32_t  OVERRIDEEN;                        /*!< Radio calibration override enable.                                    */
+  __I  uint32_t  NRF_1MBIT[5];                      /*!< Override values for the OVERRIDEn registers in RADIO for NRF_1Mbit
+                                                         mode.                                                                 */
+  __I  uint32_t  RESERVED5[10];
+  __I  uint32_t  BLE_1MBIT[5];                      /*!< Override values for the OVERRIDEn registers in RADIO for BLE_1Mbit
+                                                         mode.                                                                 */
+} NRF_FICR_Type;
+
+
+/* ================================================================================ */
+/* ================                      UICR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief User Information Configuration. (UICR)
+  */
+
+typedef struct {                                    /*!< UICR Structure                                                        */
+  __IO uint32_t  CLENR0;                            /*!< Length of code region 0.                                              */
+  __IO uint32_t  RBPCONF;                           /*!< Readback protection configuration.                                    */
+  __IO uint32_t  XTALFREQ;                          /*!< Reset value for CLOCK XTALFREQ register.                              */
+  __I  uint32_t  RESERVED0;
+  __I  uint32_t  FWID;                              /*!< Firmware ID.                                                          */
+  
+  union {
+    __IO uint32_t  NRFFW[15];                       /*!< Reserved for Nordic firmware design.                                  */
+    __IO uint32_t  BOOTLOADERADDR;                  /*!< Bootloader start address.                                             */
+  };
+  __IO uint32_t  NRFHW[12];                         /*!< Reserved for Nordic hardware design.                                  */
+  __IO uint32_t  CUSTOMER[32];                      /*!< Reserved for customer.                                                */
+} NRF_UICR_Type;
+
+
+/* ================================================================================ */
+/* ================                      GPIO                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief General purpose input and output. (GPIO)
+  */
+
+typedef struct {                                    /*!< GPIO Structure                                                        */
+  __I  uint32_t  RESERVED0[321];
+  __IO uint32_t  OUT;                               /*!< Write GPIO port.                                                      */
+  __IO uint32_t  OUTSET;                            /*!< Set individual bits in GPIO port.                                     */
+  __IO uint32_t  OUTCLR;                            /*!< Clear individual bits in GPIO port.                                   */
+  __I  uint32_t  IN;                                /*!< Read GPIO port.                                                       */
+  __IO uint32_t  DIR;                               /*!< Direction of GPIO pins.                                               */
+  __IO uint32_t  DIRSET;                            /*!< DIR set register.                                                     */
+  __IO uint32_t  DIRCLR;                            /*!< DIR clear register.                                                   */
+  __I  uint32_t  RESERVED1[120];
+  __IO uint32_t  PIN_CNF[32];                       /*!< Configuration of GPIO pins.                                           */
+} NRF_GPIO_Type;
+
+
+/* --------------------  End of section using anonymous unions  ------------------- */
+#if defined(__CC_ARM)
+  #pragma pop
+#elif defined(__ICCARM__)
+  /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TMS470__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TASKING__)
+  #pragma warning restore
+#else
+  #warning Not supported compiler type
+#endif
+
+
+
+
+/* ================================================================================ */
+/* ================              Peripheral memory map             ================ */
+/* ================================================================================ */
+
+#define NRF_POWER_BASE                  0x40000000UL
+#define NRF_CLOCK_BASE                  0x40000000UL
+#define NRF_MPU_BASE                    0x40000000UL
+#define NRF_AMLI_BASE                   0x40000000UL
+#define NRF_RADIO_BASE                  0x40001000UL
+#define NRF_UART0_BASE                  0x40002000UL
+#define NRF_SPI0_BASE                   0x40003000UL
+#define NRF_TWI0_BASE                   0x40003000UL
+#define NRF_SPI1_BASE                   0x40004000UL
+#define NRF_TWI1_BASE                   0x40004000UL
+#define NRF_SPIS1_BASE                  0x40004000UL
+#define NRF_SPIM1_BASE                  0x40004000UL
+#define NRF_GPIOTE_BASE                 0x40006000UL
+#define NRF_ADC_BASE                    0x40007000UL
+#define NRF_TIMER0_BASE                 0x40008000UL
+#define NRF_TIMER1_BASE                 0x40009000UL
+#define NRF_TIMER2_BASE                 0x4000A000UL
+#define NRF_RTC0_BASE                   0x4000B000UL
+#define NRF_TEMP_BASE                   0x4000C000UL
+#define NRF_RNG_BASE                    0x4000D000UL
+#define NRF_ECB_BASE                    0x4000E000UL
+#define NRF_AAR_BASE                    0x4000F000UL
+#define NRF_CCM_BASE                    0x4000F000UL
+#define NRF_WDT_BASE                    0x40010000UL
+#define NRF_RTC1_BASE                   0x40011000UL
+#define NRF_QDEC_BASE                   0x40012000UL
+#define NRF_LPCOMP_BASE                 0x40013000UL
+#define NRF_SWI_BASE                    0x40014000UL
+#define NRF_NVMC_BASE                   0x4001E000UL
+#define NRF_PPI_BASE                    0x4001F000UL
+#define NRF_FICR_BASE                   0x10000000UL
+#define NRF_UICR_BASE                   0x10001000UL
+#define NRF_GPIO_BASE                   0x50000000UL
+
+
+/* ================================================================================ */
+/* ================             Peripheral declaration             ================ */
+/* ================================================================================ */
+
+#define NRF_POWER                       ((NRF_POWER_Type          *) NRF_POWER_BASE)
+#define NRF_CLOCK                       ((NRF_CLOCK_Type          *) NRF_CLOCK_BASE)
+#define NRF_MPU                         ((NRF_MPU_Type            *) NRF_MPU_BASE)
+#define NRF_AMLI                        ((NRF_AMLI_Type           *) NRF_AMLI_BASE)
+#define NRF_RADIO                       ((NRF_RADIO_Type          *) NRF_RADIO_BASE)
+#define NRF_UART0                       ((NRF_UART_Type           *) NRF_UART0_BASE)
+#define NRF_SPI0                        ((NRF_SPI_Type            *) NRF_SPI0_BASE)
+#define NRF_TWI0                        ((NRF_TWI_Type            *) NRF_TWI0_BASE)
+#define NRF_SPI1                        ((NRF_SPI_Type            *) NRF_SPI1_BASE)
+#define NRF_TWI1                        ((NRF_TWI_Type            *) NRF_TWI1_BASE)
+#define NRF_SPIS1                       ((NRF_SPIS_Type           *) NRF_SPIS1_BASE)
+#define NRF_SPIM1                       ((NRF_SPIM_Type           *) NRF_SPIM1_BASE)
+#define NRF_GPIOTE                      ((NRF_GPIOTE_Type         *) NRF_GPIOTE_BASE)
+#define NRF_ADC                         ((NRF_ADC_Type            *) NRF_ADC_BASE)
+#define NRF_TIMER0                      ((NRF_TIMER_Type          *) NRF_TIMER0_BASE)
+#define NRF_TIMER1                      ((NRF_TIMER_Type          *) NRF_TIMER1_BASE)
+#define NRF_TIMER2                      ((NRF_TIMER_Type          *) NRF_TIMER2_BASE)
+#define NRF_RTC0                        ((NRF_RTC_Type            *) NRF_RTC0_BASE)
+#define NRF_TEMP                        ((NRF_TEMP_Type           *) NRF_TEMP_BASE)
+#define NRF_RNG                         ((NRF_RNG_Type            *) NRF_RNG_BASE)
+#define NRF_ECB                         ((NRF_ECB_Type            *) NRF_ECB_BASE)
+#define NRF_AAR                         ((NRF_AAR_Type            *) NRF_AAR_BASE)
+#define NRF_CCM                         ((NRF_CCM_Type            *) NRF_CCM_BASE)
+#define NRF_WDT                         ((NRF_WDT_Type            *) NRF_WDT_BASE)
+#define NRF_RTC1                        ((NRF_RTC_Type            *) NRF_RTC1_BASE)
+#define NRF_QDEC                        ((NRF_QDEC_Type           *) NRF_QDEC_BASE)
+#define NRF_LPCOMP                      ((NRF_LPCOMP_Type         *) NRF_LPCOMP_BASE)
+#define NRF_SWI                         ((NRF_SWI_Type            *) NRF_SWI_BASE)
+#define NRF_NVMC                        ((NRF_NVMC_Type           *) NRF_NVMC_BASE)
+#define NRF_PPI                         ((NRF_PPI_Type            *) NRF_PPI_BASE)
+#define NRF_FICR                        ((NRF_FICR_Type           *) NRF_FICR_BASE)
+#define NRF_UICR                        ((NRF_UICR_Type           *) NRF_UICR_BASE)
+#define NRF_GPIO                        ((NRF_GPIO_Type           *) NRF_GPIO_BASE)
+
+
+/** @} */ /* End of group Device_Peripheral_Registers */
+/** @} */ /* End of group nrf51 */
+/** @} */ /* End of group Nordic Semiconductor */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif  /* nrf51_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf51_bitfields.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,7135 @@
+/* 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:
+ *
+ *   * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (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 __NRF51_BITS_H
+#define __NRF51_BITS_H
+
+/*lint ++flb "Enter library region */
+
+#include <core_cm0.h>
+
+/* Peripheral: AAR */
+/* Description: Accelerated Address Resolver. */
+
+/* Register: AAR_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on NOTRESOLVED event. */
+#define AAR_INTENSET_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */
+#define AAR_INTENSET_NOTRESOLVED_Msk (0x1UL << AAR_INTENSET_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */
+#define AAR_INTENSET_NOTRESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_NOTRESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_NOTRESOLVED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on RESOLVED event. */
+#define AAR_INTENSET_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */
+#define AAR_INTENSET_RESOLVED_Msk (0x1UL << AAR_INTENSET_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */
+#define AAR_INTENSET_RESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_RESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_RESOLVED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on END event. */
+#define AAR_INTENSET_END_Pos (0UL) /*!< Position of END field. */
+#define AAR_INTENSET_END_Msk (0x1UL << AAR_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define AAR_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: AAR_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on NOTRESOLVED event. */
+#define AAR_INTENCLR_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */
+#define AAR_INTENCLR_NOTRESOLVED_Msk (0x1UL << AAR_INTENCLR_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */
+#define AAR_INTENCLR_NOTRESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_NOTRESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_NOTRESOLVED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on RESOLVED event. */
+#define AAR_INTENCLR_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */
+#define AAR_INTENCLR_RESOLVED_Msk (0x1UL << AAR_INTENCLR_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */
+#define AAR_INTENCLR_RESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_RESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_RESOLVED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDKSGEN event. */
+#define AAR_INTENCLR_END_Pos (0UL) /*!< Position of END field. */
+#define AAR_INTENCLR_END_Msk (0x1UL << AAR_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define AAR_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: AAR_STATUS */
+/* Description: Resolution status. */
+
+/* Bits 3..0 : The IRK used last time an address was resolved. */
+#define AAR_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define AAR_STATUS_STATUS_Msk (0xFUL << AAR_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */
+
+/* Register: AAR_ENABLE */
+/* Description: Enable AAR. */
+
+/* Bits 1..0 : Enable AAR. */
+#define AAR_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define AAR_ENABLE_ENABLE_Msk (0x3UL << AAR_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define AAR_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled AAR. */
+#define AAR_ENABLE_ENABLE_Enabled (0x03UL) /*!< Enable AAR. */
+
+/* Register: AAR_NIRK */
+/* Description: Number of Identity root Keys in the IRK data structure. */
+
+/* Bits 4..0 : Number of Identity root Keys in the IRK data structure. */
+#define AAR_NIRK_NIRK_Pos (0UL) /*!< Position of NIRK field. */
+#define AAR_NIRK_NIRK_Msk (0x1FUL << AAR_NIRK_NIRK_Pos) /*!< Bit mask of NIRK field. */
+
+/* Register: AAR_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define AAR_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define AAR_POWER_POWER_Msk (0x1UL << AAR_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define AAR_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define AAR_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: ADC */
+/* Description: Analog to digital converter. */
+
+/* Register: ADC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on END event. */
+#define ADC_INTENSET_END_Pos (0UL) /*!< Position of END field. */
+#define ADC_INTENSET_END_Msk (0x1UL << ADC_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define ADC_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define ADC_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define ADC_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: ADC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on END event. */
+#define ADC_INTENCLR_END_Pos (0UL) /*!< Position of END field. */
+#define ADC_INTENCLR_END_Msk (0x1UL << ADC_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define ADC_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define ADC_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define ADC_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: ADC_BUSY */
+/* Description: ADC busy register. */
+
+/* Bit 0 : ADC busy register. */
+#define ADC_BUSY_BUSY_Pos (0UL) /*!< Position of BUSY field. */
+#define ADC_BUSY_BUSY_Msk (0x1UL << ADC_BUSY_BUSY_Pos) /*!< Bit mask of BUSY field. */
+#define ADC_BUSY_BUSY_Ready (0UL) /*!< No ongoing ADC conversion is taking place. ADC is ready. */
+#define ADC_BUSY_BUSY_Busy (1UL) /*!< An ADC conversion is taking place. ADC is busy. */
+
+/* Register: ADC_ENABLE */
+/* Description: ADC enable. */
+
+/* Bits 1..0 : ADC enable. */
+#define ADC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define ADC_ENABLE_ENABLE_Msk (0x3UL << ADC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define ADC_ENABLE_ENABLE_Disabled (0x00UL) /*!< ADC is disabled. */
+#define ADC_ENABLE_ENABLE_Enabled (0x01UL) /*!< ADC is enabled. If an analog input pin is selected as source of the conversion, the selected pin is configured as an analog input. */
+
+/* Register: ADC_CONFIG */
+/* Description: ADC configuration register. */
+
+/* Bits 17..16 : ADC external reference pin selection. */
+#define ADC_CONFIG_EXTREFSEL_Pos (16UL) /*!< Position of EXTREFSEL field. */
+#define ADC_CONFIG_EXTREFSEL_Msk (0x3UL << ADC_CONFIG_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */
+#define ADC_CONFIG_EXTREFSEL_None (0UL) /*!< Analog external reference inputs disabled. */
+#define ADC_CONFIG_EXTREFSEL_AnalogReference0 (1UL) /*!< Use analog reference 0 as reference. */
+#define ADC_CONFIG_EXTREFSEL_AnalogReference1 (2UL) /*!< Use analog reference 1 as reference. */
+
+/* Bits 15..8 : ADC analog pin selection. */
+#define ADC_CONFIG_PSEL_Pos (8UL) /*!< Position of PSEL field. */
+#define ADC_CONFIG_PSEL_Msk (0xFFUL << ADC_CONFIG_PSEL_Pos) /*!< Bit mask of PSEL field. */
+#define ADC_CONFIG_PSEL_Disabled (0UL) /*!< Analog input pins disabled. */
+#define ADC_CONFIG_PSEL_AnalogInput0 (1UL) /*!< Use analog input 0 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput1 (2UL) /*!< Use analog input 1 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput2 (4UL) /*!< Use analog input 2 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput3 (8UL) /*!< Use analog input 3 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput4 (16UL) /*!< Use analog input 4 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput5 (32UL) /*!< Use analog input 5 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput6 (64UL) /*!< Use analog input 6 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput7 (128UL) /*!< Use analog input 7 as analog input. */
+
+/* Bits 6..5 : ADC reference selection. */
+#define ADC_CONFIG_REFSEL_Pos (5UL) /*!< Position of REFSEL field. */
+#define ADC_CONFIG_REFSEL_Msk (0x3UL << ADC_CONFIG_REFSEL_Pos) /*!< Bit mask of REFSEL field. */
+#define ADC_CONFIG_REFSEL_VBG (0x00UL) /*!< Use internal 1.2V bandgap voltage as reference for conversion. */
+#define ADC_CONFIG_REFSEL_External (0x01UL) /*!< Use external source configured by EXTREFSEL as reference for conversion. */
+#define ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling (0x02UL) /*!< Use supply voltage with 1/2 prescaling as reference for conversion. Only usable when supply voltage is between 1.7V and 2.6V. */
+#define ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling (0x03UL) /*!< Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V. */
+
+/* Bits 4..2 : ADC input selection. */
+#define ADC_CONFIG_INPSEL_Pos (2UL) /*!< Position of INPSEL field. */
+#define ADC_CONFIG_INPSEL_Msk (0x7UL << ADC_CONFIG_INPSEL_Pos) /*!< Bit mask of INPSEL field. */
+#define ADC_CONFIG_INPSEL_AnalogInputNoPrescaling (0x00UL) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling (0x01UL) /*!< Analog input specified by PSEL with 2/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling (0x02UL) /*!< Analog input specified by PSEL with 1/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling (0x05UL) /*!< Supply voltage with 2/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling (0x06UL) /*!< Supply voltage with 1/3 prescaling used as input for the conversion. */
+
+/* Bits 1..0 : ADC resolution. */
+#define ADC_CONFIG_RES_Pos (0UL) /*!< Position of RES field. */
+#define ADC_CONFIG_RES_Msk (0x3UL << ADC_CONFIG_RES_Pos) /*!< Bit mask of RES field. */
+#define ADC_CONFIG_RES_8bit (0x00UL) /*!< 8bit ADC resolution. */
+#define ADC_CONFIG_RES_9bit (0x01UL) /*!< 9bit ADC resolution. */
+#define ADC_CONFIG_RES_10bit (0x02UL) /*!< 10bit ADC resolution. */
+
+/* Register: ADC_RESULT */
+/* Description: Result of ADC conversion. */
+
+/* Bits 9..0 : Result of ADC conversion. */
+#define ADC_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */
+#define ADC_RESULT_RESULT_Msk (0x3FFUL << ADC_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */
+
+/* Register: ADC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define ADC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define ADC_POWER_POWER_Msk (0x1UL << ADC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define ADC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define ADC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: AMLI */
+/* Description: AHB Multi-Layer Interface. */
+
+/* Register: AMLI_RAMPRI_CPU0 */
+/* Description: Configurable priority configuration register for CPU0. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_CPU0_RAM7_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_CPU0_RAM6_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_CPU0_RAM5_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_CPU0_RAM4_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_CPU0_RAM3_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_CPU0_RAM2_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_CPU0_RAM1_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_CPU0_RAM0_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_SPIS1 */
+/* Description: Configurable priority configuration register for SPIS1. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_RADIO */
+/* Description: Configurable priority configuration register for RADIO. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_RADIO_RAM7_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_RADIO_RAM6_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_RADIO_RAM5_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_RADIO_RAM4_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_RADIO_RAM3_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_RADIO_RAM2_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_RADIO_RAM1_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_RADIO_RAM0_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_ECB */
+/* Description: Configurable priority configuration register for ECB. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_ECB_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_ECB_RAM7_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_ECB_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_ECB_RAM6_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_ECB_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_ECB_RAM5_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_ECB_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_ECB_RAM4_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_ECB_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_ECB_RAM3_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_ECB_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_ECB_RAM2_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_ECB_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_ECB_RAM1_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_ECB_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_ECB_RAM0_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_CCM */
+/* Description: Configurable priority configuration register for CCM. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_CCM_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_CCM_RAM7_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_CCM_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_CCM_RAM6_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_CCM_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_CCM_RAM5_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_CCM_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_CCM_RAM4_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_CCM_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_CCM_RAM3_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_CCM_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_CCM_RAM2_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_CCM_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_CCM_RAM1_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_CCM_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_CCM_RAM0_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_AAR */
+/* Description: Configurable priority configuration register for AAR. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_AAR_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_AAR_RAM7_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_AAR_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_AAR_RAM6_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_AAR_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_AAR_RAM5_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_AAR_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_AAR_RAM4_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_AAR_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_AAR_RAM3_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_AAR_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_AAR_RAM2_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_AAR_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_AAR_RAM1_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_AAR_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_AAR_RAM0_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Peripheral: CCM */
+/* Description: AES CCM Mode Encryption. */
+
+/* Register: CCM_SHORTS */
+/* Description: Shortcuts for the CCM. */
+
+/* Bit 0 : Shortcut between ENDKSGEN event and CRYPT task. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Pos (0UL) /*!< Position of ENDKSGEN_CRYPT field. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Msk (0x1UL << CCM_SHORTS_ENDKSGEN_CRYPT_Pos) /*!< Bit mask of ENDKSGEN_CRYPT field. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Disabled (0UL) /*!< Shortcut disabled. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: CCM_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on ERROR event. */
+#define CCM_INTENSET_ERROR_Pos (2UL) /*!< Position of ERROR field. */
+#define CCM_INTENSET_ERROR_Msk (0x1UL << CCM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define CCM_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on ENDCRYPT event. */
+#define CCM_INTENSET_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */
+#define CCM_INTENSET_ENDCRYPT_Msk (0x1UL << CCM_INTENSET_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */
+#define CCM_INTENSET_ENDCRYPT_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ENDCRYPT_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ENDCRYPT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on ENDKSGEN event. */
+#define CCM_INTENSET_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */
+#define CCM_INTENSET_ENDKSGEN_Msk (0x1UL << CCM_INTENSET_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */
+#define CCM_INTENSET_ENDKSGEN_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ENDKSGEN_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ENDKSGEN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: CCM_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on ERROR event. */
+#define CCM_INTENCLR_ERROR_Pos (2UL) /*!< Position of ERROR field. */
+#define CCM_INTENCLR_ERROR_Msk (0x1UL << CCM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define CCM_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on ENDCRYPT event. */
+#define CCM_INTENCLR_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */
+#define CCM_INTENCLR_ENDCRYPT_Msk (0x1UL << CCM_INTENCLR_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */
+#define CCM_INTENCLR_ENDCRYPT_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ENDCRYPT_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ENDCRYPT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDKSGEN event. */
+#define CCM_INTENCLR_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */
+#define CCM_INTENCLR_ENDKSGEN_Msk (0x1UL << CCM_INTENCLR_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */
+#define CCM_INTENCLR_ENDKSGEN_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ENDKSGEN_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ENDKSGEN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: CCM_MICSTATUS */
+/* Description: CCM RX MIC check result. */
+
+/* Bit 0 : Result of the MIC check performed during the previous CCM RX STARTCRYPT */
+#define CCM_MICSTATUS_MICSTATUS_Pos (0UL) /*!< Position of MICSTATUS field. */
+#define CCM_MICSTATUS_MICSTATUS_Msk (0x1UL << CCM_MICSTATUS_MICSTATUS_Pos) /*!< Bit mask of MICSTATUS field. */
+#define CCM_MICSTATUS_MICSTATUS_CheckFailed (0UL) /*!< MIC check failed. */
+#define CCM_MICSTATUS_MICSTATUS_CheckPassed (1UL) /*!< MIC check passed. */
+
+/* Register: CCM_ENABLE */
+/* Description: CCM enable. */
+
+/* Bits 1..0 : CCM enable. */
+#define CCM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define CCM_ENABLE_ENABLE_Msk (0x3UL << CCM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define CCM_ENABLE_ENABLE_Disabled (0x00UL) /*!< CCM is disabled. */
+#define CCM_ENABLE_ENABLE_Enabled (0x02UL) /*!< CCM is enabled. */
+
+/* Register: CCM_MODE */
+/* Description: Operation mode. */
+
+/* Bit 0 : CCM mode operation. */
+#define CCM_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define CCM_MODE_MODE_Msk (0x1UL << CCM_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define CCM_MODE_MODE_Encryption (0UL) /*!< CCM mode TX */
+#define CCM_MODE_MODE_Decryption (1UL) /*!< CCM mode TX */
+
+/* Register: CCM_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define CCM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define CCM_POWER_POWER_Msk (0x1UL << CCM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define CCM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define CCM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: CLOCK */
+/* Description: Clock control. */
+
+/* Register: CLOCK_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 4 : Enable interrupt on CTTO event. */
+#define CLOCK_INTENSET_CTTO_Pos (4UL) /*!< Position of CTTO field. */
+#define CLOCK_INTENSET_CTTO_Msk (0x1UL << CLOCK_INTENSET_CTTO_Pos) /*!< Bit mask of CTTO field. */
+#define CLOCK_INTENSET_CTTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_CTTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_CTTO_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on DONE event. */
+#define CLOCK_INTENSET_DONE_Pos (3UL) /*!< Position of DONE field. */
+#define CLOCK_INTENSET_DONE_Msk (0x1UL << CLOCK_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */
+#define CLOCK_INTENSET_DONE_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_DONE_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_DONE_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on LFCLKSTARTED event. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on HFCLKSTARTED event. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: CLOCK_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 4 : Disable interrupt on CTTO event. */
+#define CLOCK_INTENCLR_CTTO_Pos (4UL) /*!< Position of CTTO field. */
+#define CLOCK_INTENCLR_CTTO_Msk (0x1UL << CLOCK_INTENCLR_CTTO_Pos) /*!< Bit mask of CTTO field. */
+#define CLOCK_INTENCLR_CTTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_CTTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_CTTO_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on DONE event. */
+#define CLOCK_INTENCLR_DONE_Pos (3UL) /*!< Position of DONE field. */
+#define CLOCK_INTENCLR_DONE_Msk (0x1UL << CLOCK_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */
+#define CLOCK_INTENCLR_DONE_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_DONE_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_DONE_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on LFCLKSTARTED event. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on HFCLKSTARTED event. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: CLOCK_HFCLKRUN */
+/* Description: Task HFCLKSTART trigger status. */
+
+/* Bit 0 : Task HFCLKSTART trigger status. */
+#define CLOCK_HFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define CLOCK_HFCLKRUN_STATUS_Msk (0x1UL << CLOCK_HFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */
+#define CLOCK_HFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task HFCLKSTART has not been triggered. */
+#define CLOCK_HFCLKRUN_STATUS_Triggered (1UL) /*!< Task HFCLKSTART has been triggered. */
+
+/* Register: CLOCK_HFCLKSTAT */
+/* Description: High frequency clock status. */
+
+/* Bit 16 : State for the HFCLK. */
+#define CLOCK_HFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */
+#define CLOCK_HFCLKSTAT_STATE_Msk (0x1UL << CLOCK_HFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */
+#define CLOCK_HFCLKSTAT_STATE_NotRunning (0UL) /*!< HFCLK clock not running. */
+#define CLOCK_HFCLKSTAT_STATE_Running (1UL) /*!< HFCLK clock running. */
+
+/* Bit 0 : Active clock source for the HF clock. */
+#define CLOCK_HFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_HFCLKSTAT_SRC_Msk (0x1UL << CLOCK_HFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_HFCLKSTAT_SRC_RC (0UL) /*!< Internal 16MHz RC oscillator running and generating the HFCLK clock. */
+#define CLOCK_HFCLKSTAT_SRC_Xtal (1UL) /*!< External 16MHz/32MHz crystal oscillator running and generating the HFCLK clock. */
+
+/* Register: CLOCK_LFCLKRUN */
+/* Description: Task LFCLKSTART triggered status. */
+
+/* Bit 0 : Task LFCLKSTART triggered status. */
+#define CLOCK_LFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define CLOCK_LFCLKRUN_STATUS_Msk (0x1UL << CLOCK_LFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */
+#define CLOCK_LFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task LFCLKSTART has not been triggered. */
+#define CLOCK_LFCLKRUN_STATUS_Triggered (1UL) /*!< Task LFCLKSTART has been triggered. */
+
+/* Register: CLOCK_LFCLKSTAT */
+/* Description: Low frequency clock status. */
+
+/* Bit 16 : State for the LF clock. */
+#define CLOCK_LFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */
+#define CLOCK_LFCLKSTAT_STATE_Msk (0x1UL << CLOCK_LFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */
+#define CLOCK_LFCLKSTAT_STATE_NotRunning (0UL) /*!< LFCLK clock not running. */
+#define CLOCK_LFCLKSTAT_STATE_Running (1UL) /*!< LFCLK clock running. */
+
+/* Bits 1..0 : Active clock source for the LF clock. */
+#define CLOCK_LFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSTAT_SRC_Msk (0x3UL << CLOCK_LFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSTAT_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator running and generating the LFCLK clock. */
+#define CLOCK_LFCLKSTAT_SRC_Xtal (1UL) /*!< External 32KiHz crystal oscillator running and generating the LFCLK clock. */
+#define CLOCK_LFCLKSTAT_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from the HFCLK running and generating the LFCLK clock. */
+
+/* Register: CLOCK_LFCLKSRCCOPY */
+/* Description: Clock source for the LFCLK clock, set when task LKCLKSTART is triggered. */
+
+/* Bits 1..0 : Clock source for the LFCLK clock, set when task LKCLKSTART is triggered. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Msk (0x3UL << CLOCK_LFCLKSRCCOPY_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSRCCOPY_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Xtal (1UL) /*!< External 32KiHz crystal. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from HFCLK system clock. */
+
+/* Register: CLOCK_LFCLKSRC */
+/* Description: Clock source for the LFCLK clock. */
+
+/* Bits 1..0 : Clock source. */
+#define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSRC_SRC_Msk (0x3UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSRC_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator. */
+#define CLOCK_LFCLKSRC_SRC_Xtal (1UL) /*!< External 32KiHz crystal. */
+#define CLOCK_LFCLKSRC_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from HFCLK system clock. */
+
+/* Register: CLOCK_CTIV */
+/* Description: Calibration timer interval. */
+
+/* Bits 6..0 : Calibration timer interval in 0.25s resolution. */
+#define CLOCK_CTIV_CTIV_Pos (0UL) /*!< Position of CTIV field. */
+#define CLOCK_CTIV_CTIV_Msk (0x7FUL << CLOCK_CTIV_CTIV_Pos) /*!< Bit mask of CTIV field. */
+
+/* Register: CLOCK_XTALFREQ */
+/* Description: Crystal frequency. */
+
+/* Bits 7..0 : External Xtal frequency selection. */
+#define CLOCK_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
+#define CLOCK_XTALFREQ_XTALFREQ_Msk (0xFFUL << CLOCK_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
+#define CLOCK_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz xtal is used as source for the HFCLK oscillator. */
+#define CLOCK_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz xtal is used as source for the HFCLK oscillator. */
+
+
+/* Peripheral: ECB */
+/* Description: AES ECB Mode Encryption. */
+
+/* Register: ECB_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 1 : Enable interrupt on ERRORECB event. */
+#define ECB_INTENSET_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */
+#define ECB_INTENSET_ERRORECB_Msk (0x1UL << ECB_INTENSET_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */
+#define ECB_INTENSET_ERRORECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENSET_ERRORECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENSET_ERRORECB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on ENDECB event. */
+#define ECB_INTENSET_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */
+#define ECB_INTENSET_ENDECB_Msk (0x1UL << ECB_INTENSET_ENDECB_Pos) /*!< Bit mask of ENDECB field. */
+#define ECB_INTENSET_ENDECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENSET_ENDECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENSET_ENDECB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: ECB_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 1 : Disable interrupt on ERRORECB event. */
+#define ECB_INTENCLR_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */
+#define ECB_INTENCLR_ERRORECB_Msk (0x1UL << ECB_INTENCLR_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */
+#define ECB_INTENCLR_ERRORECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENCLR_ERRORECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENCLR_ERRORECB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDECB event. */
+#define ECB_INTENCLR_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */
+#define ECB_INTENCLR_ENDECB_Msk (0x1UL << ECB_INTENCLR_ENDECB_Pos) /*!< Bit mask of ENDECB field. */
+#define ECB_INTENCLR_ENDECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENCLR_ENDECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENCLR_ENDECB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: ECB_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define ECB_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define ECB_POWER_POWER_Msk (0x1UL << ECB_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define ECB_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define ECB_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: FICR */
+/* Description: Factory Information Configuration. */
+
+/* Register: FICR_PPFC */
+/* Description: Pre-programmed factory code present. */
+
+/* Bits 7..0 : Pre-programmed factory code present. */
+#define FICR_PPFC_PPFC_Pos (0UL) /*!< Position of PPFC field. */
+#define FICR_PPFC_PPFC_Msk (0xFFUL << FICR_PPFC_PPFC_Pos) /*!< Bit mask of PPFC field. */
+#define FICR_PPFC_PPFC_NotPresent (0xFFUL) /*!< Not present. */
+#define FICR_PPFC_PPFC_Present (0x00UL) /*!< Present. */
+
+/* Register: FICR_CONFIGID */
+/* Description: Configuration identifier. */
+
+/* Bits 31..16 : Firmware Identification Number pre-loaded into the flash. */
+#define FICR_CONFIGID_FWID_Pos (16UL) /*!< Position of FWID field. */
+#define FICR_CONFIGID_FWID_Msk (0xFFFFUL << FICR_CONFIGID_FWID_Pos) /*!< Bit mask of FWID field. */
+
+/* Bits 15..0 : Hardware Identification Number. */
+#define FICR_CONFIGID_HWID_Pos (0UL) /*!< Position of HWID field. */
+#define FICR_CONFIGID_HWID_Msk (0xFFFFUL << FICR_CONFIGID_HWID_Pos) /*!< Bit mask of HWID field. */
+
+/* Register: FICR_DEVICEADDRTYPE */
+/* Description: Device address type. */
+
+/* Bit 0 : Device address type. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos (0UL) /*!< Position of DEVICEADDRTYPE field. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Msk (0x1UL << FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos) /*!< Bit mask of DEVICEADDRTYPE field. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Public (0UL) /*!< Public address. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Random (1UL) /*!< Random address. */
+
+/* Register: FICR_OVERRIDEEN */
+/* Description: Radio calibration override enable. */
+
+/* Bit 3 : Override default values for BLE_1Mbit mode. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Pos (3UL) /*!< Position of BLE_1MBIT field. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Msk (0x1UL << FICR_OVERRIDEEN_BLE_1MBIT_Pos) /*!< Bit mask of BLE_1MBIT field. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Override (0UL) /*!< Override the default values for BLE_1Mbit mode. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_NotOverride (1UL) /*!< Do not override the default values for BLE_1Mbit mode. */
+
+/* Bit 0 : Override default values for NRF_1Mbit mode. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Pos (0UL) /*!< Position of NRF_1MBIT field. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Msk (0x1UL << FICR_OVERRIDEEN_NRF_1MBIT_Pos) /*!< Bit mask of NRF_1MBIT field. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Override (0UL) /*!< Override the default values for NRF_1Mbit mode. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_NotOverride (1UL) /*!< Do not override the default values for NRF_1Mbit mode. */
+
+/* Register: FICR_INFO_PART */
+/* Description: Part code */
+
+/* Bits 31..0 : Part code */
+#define FICR_INFO_PART_PART_Pos (0UL) /*!< Position of PART field. */
+#define FICR_INFO_PART_PART_Msk (0xFFFFFFFFUL << FICR_INFO_PART_PART_Pos) /*!< Bit mask of PART field. */
+#define FICR_INFO_PART_PART_N51822 (0x51822UL) /*!< nRF51822 */
+#define FICR_INFO_PART_PART_N51422 (0x51422UL) /*!< nRF51422 */
+#define FICR_INFO_PART_PART_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
+
+/* Register: FICR_INFO_VARIANT */
+/* Description: Part variant */
+
+/* Bits 31..0 : Part variant */
+#define FICR_INFO_VARIANT_VARIANT_Pos (0UL) /*!< Position of VARIANT field. */
+#define FICR_INFO_VARIANT_VARIANT_Msk (0xFFFFFFFFUL << FICR_INFO_VARIANT_VARIANT_Pos) /*!< Bit mask of VARIANT field. */
+#define FICR_INFO_VARIANT_VARIANT_nRF51C (0x1002UL) /*!< nRF51-C (XLR3) */
+#define FICR_INFO_VARIANT_VARIANT_nRF51D (0x1003UL) /*!< nRF51-D (L3) */
+#define FICR_INFO_VARIANT_VARIANT_nRF51E (0x1004UL) /*!< nRF51-E (XLR3P) */
+#define FICR_INFO_VARIANT_VARIANT_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
+
+/* Register: FICR_INFO_PACKAGE */
+/* Description: Package option */
+
+/* Bits 31..0 : Package option */
+#define FICR_INFO_PACKAGE_PACKAGE_Pos (0UL) /*!< Position of PACKAGE field. */
+#define FICR_INFO_PACKAGE_PACKAGE_Msk (0xFFFFFFFFUL << FICR_INFO_PACKAGE_PACKAGE_Pos) /*!< Bit mask of PACKAGE field. */
+#define FICR_INFO_PACKAGE_PACKAGE_QFN48 (0x0000UL) /*!< 48-pin QFN with 31 GPIO */
+#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP56A (0x1000UL) /*!< nRF51x22 CDxx - WLCSP 56 balls */
+#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62A (0x1001UL) /*!< nRF51x22 CExx - WLCSP 62 balls */
+#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62B (0x1002UL) /*!< nRF51x22 CFxx - WLCSP 62 balls */
+#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62C (0x1003UL) /*!< nRF51x22 CTxx - WLCSP 62 balls */
+#define FICR_INFO_PACKAGE_PACKAGE_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
+
+/* Register: FICR_INFO_RAM */
+/* Description: RAM variant */
+
+/* Bits 31..0 : RAM variant */
+#define FICR_INFO_RAM_RAM_Pos (0UL) /*!< Position of RAM field. */
+#define FICR_INFO_RAM_RAM_Msk (0xFFFFFFFFUL << FICR_INFO_RAM_RAM_Pos) /*!< Bit mask of RAM field. */
+#define FICR_INFO_RAM_RAM_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
+#define FICR_INFO_RAM_RAM_K16 (16UL) /*!< 16 kByte RAM. */
+#define FICR_INFO_RAM_RAM_K32 (32UL) /*!< 32 kByte RAM. */
+
+/* Register: FICR_INFO_FLASH */
+/* Description: Flash variant */
+
+/* Bits 31..0 : Flash variant */
+#define FICR_INFO_FLASH_FLASH_Pos (0UL) /*!< Position of FLASH field. */
+#define FICR_INFO_FLASH_FLASH_Msk (0xFFFFFFFFUL << FICR_INFO_FLASH_FLASH_Pos) /*!< Bit mask of FLASH field. */
+#define FICR_INFO_FLASH_FLASH_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */
+#define FICR_INFO_FLASH_FLASH_K128 (128UL) /*!< 128 kByte FLASH. */
+#define FICR_INFO_FLASH_FLASH_K256 (256UL) /*!< 256 kByte FLASH. */
+
+
+/* Peripheral: GPIO */
+/* Description: General purpose input and output. */
+
+/* Register: GPIO_OUT */
+/* Description: Write GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN0_High (1UL) /*!< Pin driver is high. */
+
+/* Register: GPIO_OUTSET */
+/* Description: Set individual bits in GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUTSET_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN31_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN31_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUTSET_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN30_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN30_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUTSET_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN29_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN29_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUTSET_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN28_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN28_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUTSET_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN27_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN27_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUTSET_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN26_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN26_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUTSET_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN25_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN25_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUTSET_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN24_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN24_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUTSET_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN23_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN23_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUTSET_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN22_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN22_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUTSET_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN21_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN21_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUTSET_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN20_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN20_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUTSET_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN19_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN19_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUTSET_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN18_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN18_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUTSET_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN17_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN17_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUTSET_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN16_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN16_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUTSET_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN15_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN15_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUTSET_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN14_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN14_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUTSET_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN13_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN13_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUTSET_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN12_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN12_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUTSET_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN11_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN11_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUTSET_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN10_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN10_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUTSET_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN9_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN9_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUTSET_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN8_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN8_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUTSET_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN7_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN7_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUTSET_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN6_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN6_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUTSET_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN5_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN5_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUTSET_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN4_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN4_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUTSET_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN3_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN3_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUTSET_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN2_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN2_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUTSET_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN1_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN1_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUTSET_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN0_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN0_Set (1UL) /*!< Set pin driver high. */
+
+/* Register: GPIO_OUTCLR */
+/* Description: Clear individual bits in GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN31_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN30_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN29_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN28_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN27_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN26_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN25_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN24_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN23_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN22_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN21_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN20_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN19_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN18_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN17_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN16_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN15_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN14_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN13_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN12_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN11_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN10_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN9_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN8_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN7_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN6_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN5_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN4_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN3_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN2_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN1_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN0_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN0_Clear (1UL) /*!< Set pin driver low. */
+
+/* Register: GPIO_IN */
+/* Description: Read GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN0_High (1UL) /*!< Pin input is high. */
+
+/* Register: GPIO_DIR */
+/* Description: Direction of GPIO pins. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN0_Output (1UL) /*!< Pin set as output. */
+
+/* Register: GPIO_DIRSET */
+/* Description: DIR set register. */
+
+/* Bit 31 : Set as output pin 31. */
+#define GPIO_DIRSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIRSET_PIN31_Msk (0x1UL << GPIO_DIRSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIRSET_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN31_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN31_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 30 : Set as output pin 30. */
+#define GPIO_DIRSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIRSET_PIN30_Msk (0x1UL << GPIO_DIRSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIRSET_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN30_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN30_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 29 : Set as output pin 29. */
+#define GPIO_DIRSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIRSET_PIN29_Msk (0x1UL << GPIO_DIRSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIRSET_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN29_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN29_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 28 : Set as output pin 28. */
+#define GPIO_DIRSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIRSET_PIN28_Msk (0x1UL << GPIO_DIRSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIRSET_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN28_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN28_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 27 : Set as output pin 27. */
+#define GPIO_DIRSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIRSET_PIN27_Msk (0x1UL << GPIO_DIRSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIRSET_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN27_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN27_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 26 : Set as output pin 26. */
+#define GPIO_DIRSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIRSET_PIN26_Msk (0x1UL << GPIO_DIRSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIRSET_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN26_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN26_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 25 : Set as output pin 25. */
+#define GPIO_DIRSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIRSET_PIN25_Msk (0x1UL << GPIO_DIRSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIRSET_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN25_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN25_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 24 : Set as output pin 24. */
+#define GPIO_DIRSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIRSET_PIN24_Msk (0x1UL << GPIO_DIRSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIRSET_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN24_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN24_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 23 : Set as output pin 23. */
+#define GPIO_DIRSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIRSET_PIN23_Msk (0x1UL << GPIO_DIRSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIRSET_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN23_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN23_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 22 : Set as output pin 22. */
+#define GPIO_DIRSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIRSET_PIN22_Msk (0x1UL << GPIO_DIRSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIRSET_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN22_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN22_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 21 : Set as output pin 21. */
+#define GPIO_DIRSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIRSET_PIN21_Msk (0x1UL << GPIO_DIRSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIRSET_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN21_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN21_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 20 : Set as output pin 20. */
+#define GPIO_DIRSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIRSET_PIN20_Msk (0x1UL << GPIO_DIRSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIRSET_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN20_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN20_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 19 : Set as output pin 19. */
+#define GPIO_DIRSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIRSET_PIN19_Msk (0x1UL << GPIO_DIRSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIRSET_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN19_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN19_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 18 : Set as output pin 18. */
+#define GPIO_DIRSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIRSET_PIN18_Msk (0x1UL << GPIO_DIRSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIRSET_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN18_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN18_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 17 : Set as output pin 17. */
+#define GPIO_DIRSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIRSET_PIN17_Msk (0x1UL << GPIO_DIRSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIRSET_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN17_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN17_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 16 : Set as output pin 16. */
+#define GPIO_DIRSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIRSET_PIN16_Msk (0x1UL << GPIO_DIRSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIRSET_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN16_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN16_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 15 : Set as output pin 15. */
+#define GPIO_DIRSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIRSET_PIN15_Msk (0x1UL << GPIO_DIRSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIRSET_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN15_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN15_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 14 : Set as output pin 14. */
+#define GPIO_DIRSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIRSET_PIN14_Msk (0x1UL << GPIO_DIRSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIRSET_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN14_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN14_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 13 : Set as output pin 13. */
+#define GPIO_DIRSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIRSET_PIN13_Msk (0x1UL << GPIO_DIRSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIRSET_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN13_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN13_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 12 : Set as output pin 12. */
+#define GPIO_DIRSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIRSET_PIN12_Msk (0x1UL << GPIO_DIRSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIRSET_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN12_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN12_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 11 : Set as output pin 11. */
+#define GPIO_DIRSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIRSET_PIN11_Msk (0x1UL << GPIO_DIRSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIRSET_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN11_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN11_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 10 : Set as output pin 10. */
+#define GPIO_DIRSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIRSET_PIN10_Msk (0x1UL << GPIO_DIRSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIRSET_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN10_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN10_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 9 : Set as output pin 9. */
+#define GPIO_DIRSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIRSET_PIN9_Msk (0x1UL << GPIO_DIRSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIRSET_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN9_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN9_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 8 : Set as output pin 8. */
+#define GPIO_DIRSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIRSET_PIN8_Msk (0x1UL << GPIO_DIRSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIRSET_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN8_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN8_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 7 : Set as output pin 7. */
+#define GPIO_DIRSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIRSET_PIN7_Msk (0x1UL << GPIO_DIRSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIRSET_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN7_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN7_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 6 : Set as output pin 6. */
+#define GPIO_DIRSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIRSET_PIN6_Msk (0x1UL << GPIO_DIRSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIRSET_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN6_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN6_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 5 : Set as output pin 5. */
+#define GPIO_DIRSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIRSET_PIN5_Msk (0x1UL << GPIO_DIRSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIRSET_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN5_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN5_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 4 : Set as output pin 4. */
+#define GPIO_DIRSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIRSET_PIN4_Msk (0x1UL << GPIO_DIRSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIRSET_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN4_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN4_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 3 : Set as output pin 3. */
+#define GPIO_DIRSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIRSET_PIN3_Msk (0x1UL << GPIO_DIRSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIRSET_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN3_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN3_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 2 : Set as output pin 2. */
+#define GPIO_DIRSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIRSET_PIN2_Msk (0x1UL << GPIO_DIRSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIRSET_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN2_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN2_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 1 : Set as output pin 1. */
+#define GPIO_DIRSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIRSET_PIN1_Msk (0x1UL << GPIO_DIRSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIRSET_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN1_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN1_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 0 : Set as output pin 0. */
+#define GPIO_DIRSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIRSET_PIN0_Msk (0x1UL << GPIO_DIRSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIRSET_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN0_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN0_Set (1UL) /*!< Set pin as output. */
+
+/* Register: GPIO_DIRCLR */
+/* Description: DIR clear register. */
+
+/* Bit 31 : Set as input pin 31. */
+#define GPIO_DIRCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIRCLR_PIN31_Msk (0x1UL << GPIO_DIRCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIRCLR_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN31_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN31_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 30 : Set as input pin 30. */
+#define GPIO_DIRCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIRCLR_PIN30_Msk (0x1UL << GPIO_DIRCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIRCLR_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN30_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN30_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 29 : Set as input pin 29. */
+#define GPIO_DIRCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIRCLR_PIN29_Msk (0x1UL << GPIO_DIRCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIRCLR_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN29_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN29_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 28 : Set as input pin 28. */
+#define GPIO_DIRCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIRCLR_PIN28_Msk (0x1UL << GPIO_DIRCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIRCLR_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN28_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN28_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 27 : Set as input pin 27. */
+#define GPIO_DIRCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIRCLR_PIN27_Msk (0x1UL << GPIO_DIRCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIRCLR_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN27_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN27_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 26 : Set as input pin 26. */
+#define GPIO_DIRCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIRCLR_PIN26_Msk (0x1UL << GPIO_DIRCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIRCLR_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN26_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN26_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 25 : Set as input pin 25. */
+#define GPIO_DIRCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIRCLR_PIN25_Msk (0x1UL << GPIO_DIRCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIRCLR_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN25_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN25_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 24 : Set as input pin 24. */
+#define GPIO_DIRCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIRCLR_PIN24_Msk (0x1UL << GPIO_DIRCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIRCLR_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN24_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN24_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 23 : Set as input pin 23. */
+#define GPIO_DIRCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIRCLR_PIN23_Msk (0x1UL << GPIO_DIRCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIRCLR_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN23_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN23_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 22 : Set as input pin 22. */
+#define GPIO_DIRCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIRCLR_PIN22_Msk (0x1UL << GPIO_DIRCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIRCLR_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN22_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN22_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 21 : Set as input pin 21. */
+#define GPIO_DIRCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIRCLR_PIN21_Msk (0x1UL << GPIO_DIRCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIRCLR_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN21_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN21_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 20 : Set as input pin 20. */
+#define GPIO_DIRCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIRCLR_PIN20_Msk (0x1UL << GPIO_DIRCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIRCLR_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN20_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN20_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 19 : Set as input pin 19. */
+#define GPIO_DIRCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIRCLR_PIN19_Msk (0x1UL << GPIO_DIRCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIRCLR_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN19_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN19_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 18 : Set as input pin 18. */
+#define GPIO_DIRCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIRCLR_PIN18_Msk (0x1UL << GPIO_DIRCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIRCLR_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN18_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN18_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 17 : Set as input pin 17. */
+#define GPIO_DIRCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIRCLR_PIN17_Msk (0x1UL << GPIO_DIRCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIRCLR_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN17_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN17_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 16 : Set as input pin 16. */
+#define GPIO_DIRCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIRCLR_PIN16_Msk (0x1UL << GPIO_DIRCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIRCLR_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN16_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN16_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 15 : Set as input pin 15. */
+#define GPIO_DIRCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIRCLR_PIN15_Msk (0x1UL << GPIO_DIRCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIRCLR_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN15_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN15_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 14 : Set as input pin 14. */
+#define GPIO_DIRCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIRCLR_PIN14_Msk (0x1UL << GPIO_DIRCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIRCLR_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN14_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN14_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 13 : Set as input pin 13. */
+#define GPIO_DIRCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIRCLR_PIN13_Msk (0x1UL << GPIO_DIRCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIRCLR_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN13_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN13_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 12 : Set as input pin 12. */
+#define GPIO_DIRCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIRCLR_PIN12_Msk (0x1UL << GPIO_DIRCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIRCLR_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN12_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN12_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 11 : Set as input pin 11. */
+#define GPIO_DIRCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIRCLR_PIN11_Msk (0x1UL << GPIO_DIRCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIRCLR_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN11_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN11_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 10 : Set as input pin 10. */
+#define GPIO_DIRCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIRCLR_PIN10_Msk (0x1UL << GPIO_DIRCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIRCLR_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN10_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN10_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 9 : Set as input pin 9. */
+#define GPIO_DIRCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIRCLR_PIN9_Msk (0x1UL << GPIO_DIRCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIRCLR_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN9_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN9_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 8 : Set as input pin 8. */
+#define GPIO_DIRCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIRCLR_PIN8_Msk (0x1UL << GPIO_DIRCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIRCLR_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN8_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN8_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 7 : Set as input pin 7. */
+#define GPIO_DIRCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIRCLR_PIN7_Msk (0x1UL << GPIO_DIRCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIRCLR_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN7_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN7_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 6 : Set as input pin 6. */
+#define GPIO_DIRCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIRCLR_PIN6_Msk (0x1UL << GPIO_DIRCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIRCLR_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN6_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN6_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 5 : Set as input pin 5. */
+#define GPIO_DIRCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIRCLR_PIN5_Msk (0x1UL << GPIO_DIRCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIRCLR_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN5_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN5_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 4 : Set as input pin 4. */
+#define GPIO_DIRCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIRCLR_PIN4_Msk (0x1UL << GPIO_DIRCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIRCLR_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN4_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN4_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 3 : Set as input pin 3. */
+#define GPIO_DIRCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIRCLR_PIN3_Msk (0x1UL << GPIO_DIRCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIRCLR_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN3_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN3_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 2 : Set as input pin 2. */
+#define GPIO_DIRCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIRCLR_PIN2_Msk (0x1UL << GPIO_DIRCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIRCLR_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN2_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN2_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 1 : Set as input pin 1. */
+#define GPIO_DIRCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIRCLR_PIN1_Msk (0x1UL << GPIO_DIRCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIRCLR_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN1_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN1_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 0 : Set as input pin 0. */
+#define GPIO_DIRCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIRCLR_PIN0_Msk (0x1UL << GPIO_DIRCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIRCLR_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN0_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Set pin as input. */
+
+/* Register: GPIO_PIN_CNF */
+/* Description: Configuration of GPIO pins. */
+
+/* Bits 17..16 : Pin sensing mechanism. */
+#define GPIO_PIN_CNF_SENSE_Pos (16UL) /*!< Position of SENSE field. */
+#define GPIO_PIN_CNF_SENSE_Msk (0x3UL << GPIO_PIN_CNF_SENSE_Pos) /*!< Bit mask of SENSE field. */
+#define GPIO_PIN_CNF_SENSE_Disabled (0x00UL) /*!< Disabled. */
+#define GPIO_PIN_CNF_SENSE_High (0x02UL) /*!< Wakeup on high level. */
+#define GPIO_PIN_CNF_SENSE_Low (0x03UL) /*!< Wakeup on low level. */
+
+/* Bits 10..8 : Drive configuration. */
+#define GPIO_PIN_CNF_DRIVE_Pos (8UL) /*!< Position of DRIVE field. */
+#define GPIO_PIN_CNF_DRIVE_Msk (0x7UL << GPIO_PIN_CNF_DRIVE_Pos) /*!< Bit mask of DRIVE field. */
+#define GPIO_PIN_CNF_DRIVE_S0S1 (0x00UL) /*!< Standard '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0S1 (0x01UL) /*!< High '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_S0H1 (0x02UL) /*!< Standard '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0H1 (0x03UL) /*!< High '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_D0S1 (0x04UL) /*!< Disconnected '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_D0H1 (0x05UL) /*!< Disconnected '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_S0D1 (0x06UL) /*!< Standard '0', Disconnected '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0D1 (0x07UL) /*!< High '0', Disconnected '1'. */
+
+/* Bits 3..2 : Pull-up or -down configuration. */
+#define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */
+#define GPIO_PIN_CNF_PULL_Msk (0x3UL << GPIO_PIN_CNF_PULL_Pos) /*!< Bit mask of PULL field. */
+#define GPIO_PIN_CNF_PULL_Disabled (0x00UL) /*!< No pull. */
+#define GPIO_PIN_CNF_PULL_Pulldown (0x01UL) /*!< Pulldown on pin. */
+#define GPIO_PIN_CNF_PULL_Pullup (0x03UL) /*!< Pullup on pin. */
+
+/* Bit 1 : Connect or disconnect input path. */
+#define GPIO_PIN_CNF_INPUT_Pos (1UL) /*!< Position of INPUT field. */
+#define GPIO_PIN_CNF_INPUT_Msk (0x1UL << GPIO_PIN_CNF_INPUT_Pos) /*!< Bit mask of INPUT field. */
+#define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input pin. */
+#define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input pin. */
+
+/* Bit 0 : Pin direction. */
+#define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */
+#define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */
+#define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin. */
+#define GPIO_PIN_CNF_DIR_Output (1UL) /*!< Configure pin as an output pin. */
+
+
+/* Peripheral: GPIOTE */
+/* Description: GPIO tasks and events. */
+
+/* Register: GPIOTE_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 31 : Enable interrupt on PORT event. */
+#define GPIOTE_INTENSET_PORT_Pos (31UL) /*!< Position of PORT field. */
+#define GPIOTE_INTENSET_PORT_Msk (0x1UL << GPIOTE_INTENSET_PORT_Pos) /*!< Bit mask of PORT field. */
+#define GPIOTE_INTENSET_PORT_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_PORT_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_PORT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on IN[3] event. */
+#define GPIOTE_INTENSET_IN3_Pos (3UL) /*!< Position of IN3 field. */
+#define GPIOTE_INTENSET_IN3_Msk (0x1UL << GPIOTE_INTENSET_IN3_Pos) /*!< Bit mask of IN3 field. */
+#define GPIOTE_INTENSET_IN3_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN3_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on IN[2] event. */
+#define GPIOTE_INTENSET_IN2_Pos (2UL) /*!< Position of IN2 field. */
+#define GPIOTE_INTENSET_IN2_Msk (0x1UL << GPIOTE_INTENSET_IN2_Pos) /*!< Bit mask of IN2 field. */
+#define GPIOTE_INTENSET_IN2_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN2_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on IN[1] event. */
+#define GPIOTE_INTENSET_IN1_Pos (1UL) /*!< Position of IN1 field. */
+#define GPIOTE_INTENSET_IN1_Msk (0x1UL << GPIOTE_INTENSET_IN1_Pos) /*!< Bit mask of IN1 field. */
+#define GPIOTE_INTENSET_IN1_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN1_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on IN[0] event. */
+#define GPIOTE_INTENSET_IN0_Pos (0UL) /*!< Position of IN0 field. */
+#define GPIOTE_INTENSET_IN0_Msk (0x1UL << GPIOTE_INTENSET_IN0_Pos) /*!< Bit mask of IN0 field. */
+#define GPIOTE_INTENSET_IN0_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN0_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: GPIOTE_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 31 : Disable interrupt on PORT event. */
+#define GPIOTE_INTENCLR_PORT_Pos (31UL) /*!< Position of PORT field. */
+#define GPIOTE_INTENCLR_PORT_Msk (0x1UL << GPIOTE_INTENCLR_PORT_Pos) /*!< Bit mask of PORT field. */
+#define GPIOTE_INTENCLR_PORT_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_PORT_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_PORT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on IN[3] event. */
+#define GPIOTE_INTENCLR_IN3_Pos (3UL) /*!< Position of IN3 field. */
+#define GPIOTE_INTENCLR_IN3_Msk (0x1UL << GPIOTE_INTENCLR_IN3_Pos) /*!< Bit mask of IN3 field. */
+#define GPIOTE_INTENCLR_IN3_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN3_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on IN[2] event. */
+#define GPIOTE_INTENCLR_IN2_Pos (2UL) /*!< Position of IN2 field. */
+#define GPIOTE_INTENCLR_IN2_Msk (0x1UL << GPIOTE_INTENCLR_IN2_Pos) /*!< Bit mask of IN2 field. */
+#define GPIOTE_INTENCLR_IN2_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN2_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on IN[1] event. */
+#define GPIOTE_INTENCLR_IN1_Pos (1UL) /*!< Position of IN1 field. */
+#define GPIOTE_INTENCLR_IN1_Msk (0x1UL << GPIOTE_INTENCLR_IN1_Pos) /*!< Bit mask of IN1 field. */
+#define GPIOTE_INTENCLR_IN1_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN1_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on IN[0] event. */
+#define GPIOTE_INTENCLR_IN0_Pos (0UL) /*!< Position of IN0 field. */
+#define GPIOTE_INTENCLR_IN0_Msk (0x1UL << GPIOTE_INTENCLR_IN0_Pos) /*!< Bit mask of IN0 field. */
+#define GPIOTE_INTENCLR_IN0_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN0_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: GPIOTE_CONFIG */
+/* Description: Channel configuration registers. */
+
+/* Bit 20 : Initial value of the output when the GPIOTE channel is configured as a Task. */
+#define GPIOTE_CONFIG_OUTINIT_Pos (20UL) /*!< Position of OUTINIT field. */
+#define GPIOTE_CONFIG_OUTINIT_Msk (0x1UL << GPIOTE_CONFIG_OUTINIT_Pos) /*!< Bit mask of OUTINIT field. */
+#define GPIOTE_CONFIG_OUTINIT_Low (0UL) /*!< Initial low output when in task mode. */
+#define GPIOTE_CONFIG_OUTINIT_High (1UL) /*!< Initial high output when in task mode. */
+
+/* Bits 17..16 : Effects on output when in Task mode, or events on input that generates an event. */
+#define GPIOTE_CONFIG_POLARITY_Pos (16UL) /*!< Position of POLARITY field. */
+#define GPIOTE_CONFIG_POLARITY_Msk (0x3UL << GPIOTE_CONFIG_POLARITY_Pos) /*!< Bit mask of POLARITY field. */
+#define GPIOTE_CONFIG_POLARITY_LoToHi (0x01UL) /*!< Low to high. */
+#define GPIOTE_CONFIG_POLARITY_HiToLo (0x02UL) /*!< High to low. */
+#define GPIOTE_CONFIG_POLARITY_Toggle (0x03UL) /*!< Toggle. */
+
+/* Bits 12..8 : Pin select. */
+#define GPIOTE_CONFIG_PSEL_Pos (8UL) /*!< Position of PSEL field. */
+#define GPIOTE_CONFIG_PSEL_Msk (0x1FUL << GPIOTE_CONFIG_PSEL_Pos) /*!< Bit mask of PSEL field. */
+
+/* Bits 1..0 : Mode */
+#define GPIOTE_CONFIG_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define GPIOTE_CONFIG_MODE_Msk (0x3UL << GPIOTE_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */
+#define GPIOTE_CONFIG_MODE_Disabled (0x00UL) /*!< Disabled. */
+#define GPIOTE_CONFIG_MODE_Event (0x01UL) /*!< Channel configure in event mode. */
+#define GPIOTE_CONFIG_MODE_Task (0x03UL) /*!< Channel configure in task mode. */
+
+/* Register: GPIOTE_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define GPIOTE_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define GPIOTE_POWER_POWER_Msk (0x1UL << GPIOTE_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define GPIOTE_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define GPIOTE_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: LPCOMP */
+/* Description: Low power comparator. */
+
+/* Register: LPCOMP_SHORTS */
+/* Description: Shortcuts for the LPCOMP. */
+
+/* Bit 4 : Shortcut between CROSS event and STOP task. */
+#define LPCOMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */
+#define LPCOMP_SHORTS_CROSS_STOP_Msk (0x1UL << LPCOMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */
+#define LPCOMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between UP event and STOP task. */
+#define LPCOMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */
+#define LPCOMP_SHORTS_UP_STOP_Msk (0x1UL << LPCOMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */
+#define LPCOMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between DOWN event and STOP task. */
+#define LPCOMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */
+#define LPCOMP_SHORTS_DOWN_STOP_Msk (0x1UL << LPCOMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */
+#define LPCOMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between RADY event and STOP task. */
+#define LPCOMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */
+#define LPCOMP_SHORTS_READY_STOP_Msk (0x1UL << LPCOMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */
+#define LPCOMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between READY event and SAMPLE task. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Msk (0x1UL << LPCOMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: LPCOMP_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 3 : Enable interrupt on CROSS event. */
+#define LPCOMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */
+#define LPCOMP_INTENSET_CROSS_Msk (0x1UL << LPCOMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */
+#define LPCOMP_INTENSET_CROSS_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_CROSS_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_CROSS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on UP event. */
+#define LPCOMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */
+#define LPCOMP_INTENSET_UP_Msk (0x1UL << LPCOMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */
+#define LPCOMP_INTENSET_UP_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_UP_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_UP_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on DOWN event. */
+#define LPCOMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */
+#define LPCOMP_INTENSET_DOWN_Msk (0x1UL << LPCOMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */
+#define LPCOMP_INTENSET_DOWN_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_DOWN_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_DOWN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on READY event. */
+#define LPCOMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */
+#define LPCOMP_INTENSET_READY_Msk (0x1UL << LPCOMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define LPCOMP_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: LPCOMP_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 3 : Disable interrupt on CROSS event. */
+#define LPCOMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */
+#define LPCOMP_INTENCLR_CROSS_Msk (0x1UL << LPCOMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */
+#define LPCOMP_INTENCLR_CROSS_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_CROSS_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on UP event. */
+#define LPCOMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */
+#define LPCOMP_INTENCLR_UP_Msk (0x1UL << LPCOMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */
+#define LPCOMP_INTENCLR_UP_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_UP_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_UP_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on DOWN event. */
+#define LPCOMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */
+#define LPCOMP_INTENCLR_DOWN_Msk (0x1UL << LPCOMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */
+#define LPCOMP_INTENCLR_DOWN_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_DOWN_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on READY event. */
+#define LPCOMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */
+#define LPCOMP_INTENCLR_READY_Msk (0x1UL << LPCOMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define LPCOMP_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: LPCOMP_RESULT */
+/* Description: Result of last compare. */
+
+/* Bit 0 : Result of last compare. Decision point SAMPLE task. */
+#define LPCOMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */
+#define LPCOMP_RESULT_RESULT_Msk (0x1UL << LPCOMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */
+#define LPCOMP_RESULT_RESULT_Bellow (0UL) /*!< Input voltage is bellow the reference threshold. */
+#define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold. */
+
+/* Register: LPCOMP_ENABLE */
+/* Description: Enable the LPCOMP. */
+
+/* Bits 1..0 : Enable or disable LPCOMP. */
+#define LPCOMP_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define LPCOMP_ENABLE_ENABLE_Msk (0x3UL << LPCOMP_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define LPCOMP_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled LPCOMP. */
+#define LPCOMP_ENABLE_ENABLE_Enabled (0x01UL) /*!< Enable LPCOMP. */
+
+/* Register: LPCOMP_PSEL */
+/* Description: Input pin select. */
+
+/* Bits 2..0 : Analog input pin select. */
+#define LPCOMP_PSEL_PSEL_Pos (0UL) /*!< Position of PSEL field. */
+#define LPCOMP_PSEL_PSEL_Msk (0x7UL << LPCOMP_PSEL_PSEL_Pos) /*!< Bit mask of PSEL field. */
+#define LPCOMP_PSEL_PSEL_AnalogInput0 (0UL) /*!< Use analog input 0 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput1 (1UL) /*!< Use analog input 1 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput2 (2UL) /*!< Use analog input 2 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput3 (3UL) /*!< Use analog input 3 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput4 (4UL) /*!< Use analog input 4 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput5 (5UL) /*!< Use analog input 5 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput6 (6UL) /*!< Use analog input 6 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput7 (7UL) /*!< Use analog input 7 as analog input. */
+
+/* Register: LPCOMP_REFSEL */
+/* Description: Reference select. */
+
+/* Bits 2..0 : Reference select. */
+#define LPCOMP_REFSEL_REFSEL_Pos (0UL) /*!< Position of REFSEL field. */
+#define LPCOMP_REFSEL_REFSEL_Msk (0x7UL << LPCOMP_REFSEL_REFSEL_Pos) /*!< Bit mask of REFSEL field. */
+#define LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling (0UL) /*!< Use supply with a 1/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling (1UL) /*!< Use supply with a 2/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling (2UL) /*!< Use supply with a 3/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling (3UL) /*!< Use supply with a 4/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling (4UL) /*!< Use supply with a 5/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling (5UL) /*!< Use supply with a 6/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling (6UL) /*!< Use supply with a 7/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_ARef (7UL) /*!< Use external analog reference as reference. */
+
+/* Register: LPCOMP_EXTREFSEL */
+/* Description: External reference select. */
+
+/* Bit 0 : External analog reference pin selection. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_Pos (0UL) /*!< Position of EXTREFSEL field. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_Msk (0x1UL << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 (0UL) /*!< Use analog reference 0 as reference. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 (1UL) /*!< Use analog reference 1 as reference. */
+
+/* Register: LPCOMP_ANADETECT */
+/* Description: Analog detect configuration. */
+
+/* Bits 1..0 : Analog detect configuration. */
+#define LPCOMP_ANADETECT_ANADETECT_Pos (0UL) /*!< Position of ANADETECT field. */
+#define LPCOMP_ANADETECT_ANADETECT_Msk (0x3UL << LPCOMP_ANADETECT_ANADETECT_Pos) /*!< Bit mask of ANADETECT field. */
+#define LPCOMP_ANADETECT_ANADETECT_Cross (0UL) /*!< Generate ANADETEC on crossing, both upwards and downwards crossing. */
+#define LPCOMP_ANADETECT_ANADETECT_Up (1UL) /*!< Generate ANADETEC on upwards crossing only. */
+#define LPCOMP_ANADETECT_ANADETECT_Down (2UL) /*!< Generate ANADETEC on downwards crossing only. */
+
+/* Register: LPCOMP_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define LPCOMP_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define LPCOMP_POWER_POWER_Msk (0x1UL << LPCOMP_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define LPCOMP_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define LPCOMP_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: MPU */
+/* Description: Memory Protection Unit. */
+
+/* Register: MPU_PERR0 */
+/* Description: Configuration of peripherals in mpu regions. */
+
+/* Bit 31 : PPI region configuration. */
+#define MPU_PERR0_PPI_Pos (31UL) /*!< Position of PPI field. */
+#define MPU_PERR0_PPI_Msk (0x1UL << MPU_PERR0_PPI_Pos) /*!< Bit mask of PPI field. */
+#define MPU_PERR0_PPI_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_PPI_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 30 : NVMC region configuration. */
+#define MPU_PERR0_NVMC_Pos (30UL) /*!< Position of NVMC field. */
+#define MPU_PERR0_NVMC_Msk (0x1UL << MPU_PERR0_NVMC_Pos) /*!< Bit mask of NVMC field. */
+#define MPU_PERR0_NVMC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_NVMC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 19 : LPCOMP region configuration. */
+#define MPU_PERR0_LPCOMP_Pos (19UL) /*!< Position of LPCOMP field. */
+#define MPU_PERR0_LPCOMP_Msk (0x1UL << MPU_PERR0_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */
+#define MPU_PERR0_LPCOMP_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_LPCOMP_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 18 : QDEC region configuration. */
+#define MPU_PERR0_QDEC_Pos (18UL) /*!< Position of QDEC field. */
+#define MPU_PERR0_QDEC_Msk (0x1UL << MPU_PERR0_QDEC_Pos) /*!< Bit mask of QDEC field. */
+#define MPU_PERR0_QDEC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_QDEC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 17 : RTC1 region configuration. */
+#define MPU_PERR0_RTC1_Pos (17UL) /*!< Position of RTC1 field. */
+#define MPU_PERR0_RTC1_Msk (0x1UL << MPU_PERR0_RTC1_Pos) /*!< Bit mask of RTC1 field. */
+#define MPU_PERR0_RTC1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RTC1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 16 : WDT region configuration. */
+#define MPU_PERR0_WDT_Pos (16UL) /*!< Position of WDT field. */
+#define MPU_PERR0_WDT_Msk (0x1UL << MPU_PERR0_WDT_Pos) /*!< Bit mask of WDT field. */
+#define MPU_PERR0_WDT_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_WDT_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 15 : CCM and AAR region configuration. */
+#define MPU_PERR0_CCM_AAR_Pos (15UL) /*!< Position of CCM_AAR field. */
+#define MPU_PERR0_CCM_AAR_Msk (0x1UL << MPU_PERR0_CCM_AAR_Pos) /*!< Bit mask of CCM_AAR field. */
+#define MPU_PERR0_CCM_AAR_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_CCM_AAR_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 14 : ECB region configuration. */
+#define MPU_PERR0_ECB_Pos (14UL) /*!< Position of ECB field. */
+#define MPU_PERR0_ECB_Msk (0x1UL << MPU_PERR0_ECB_Pos) /*!< Bit mask of ECB field. */
+#define MPU_PERR0_ECB_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_ECB_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 13 : RNG region configuration. */
+#define MPU_PERR0_RNG_Pos (13UL) /*!< Position of RNG field. */
+#define MPU_PERR0_RNG_Msk (0x1UL << MPU_PERR0_RNG_Pos) /*!< Bit mask of RNG field. */
+#define MPU_PERR0_RNG_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RNG_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 12 : TEMP region configuration. */
+#define MPU_PERR0_TEMP_Pos (12UL) /*!< Position of TEMP field. */
+#define MPU_PERR0_TEMP_Msk (0x1UL << MPU_PERR0_TEMP_Pos) /*!< Bit mask of TEMP field. */
+#define MPU_PERR0_TEMP_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TEMP_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 11 : RTC0 region configuration. */
+#define MPU_PERR0_RTC0_Pos (11UL) /*!< Position of RTC0 field. */
+#define MPU_PERR0_RTC0_Msk (0x1UL << MPU_PERR0_RTC0_Pos) /*!< Bit mask of RTC0 field. */
+#define MPU_PERR0_RTC0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RTC0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 10 : TIMER2 region configuration. */
+#define MPU_PERR0_TIMER2_Pos (10UL) /*!< Position of TIMER2 field. */
+#define MPU_PERR0_TIMER2_Msk (0x1UL << MPU_PERR0_TIMER2_Pos) /*!< Bit mask of TIMER2 field. */
+#define MPU_PERR0_TIMER2_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER2_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 9 : TIMER1 region configuration. */
+#define MPU_PERR0_TIMER1_Pos (9UL) /*!< Position of TIMER1 field. */
+#define MPU_PERR0_TIMER1_Msk (0x1UL << MPU_PERR0_TIMER1_Pos) /*!< Bit mask of TIMER1 field. */
+#define MPU_PERR0_TIMER1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 8 : TIMER0 region configuration. */
+#define MPU_PERR0_TIMER0_Pos (8UL) /*!< Position of TIMER0 field. */
+#define MPU_PERR0_TIMER0_Msk (0x1UL << MPU_PERR0_TIMER0_Pos) /*!< Bit mask of TIMER0 field. */
+#define MPU_PERR0_TIMER0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 7 : ADC region configuration. */
+#define MPU_PERR0_ADC_Pos (7UL) /*!< Position of ADC field. */
+#define MPU_PERR0_ADC_Msk (0x1UL << MPU_PERR0_ADC_Pos) /*!< Bit mask of ADC field. */
+#define MPU_PERR0_ADC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_ADC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 6 : GPIOTE region configuration. */
+#define MPU_PERR0_GPIOTE_Pos (6UL) /*!< Position of GPIOTE field. */
+#define MPU_PERR0_GPIOTE_Msk (0x1UL << MPU_PERR0_GPIOTE_Pos) /*!< Bit mask of GPIOTE field. */
+#define MPU_PERR0_GPIOTE_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_GPIOTE_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 4 : SPI1 and TWI1 region configuration. */
+#define MPU_PERR0_SPI1_TWI1_Pos (4UL) /*!< Position of SPI1_TWI1 field. */
+#define MPU_PERR0_SPI1_TWI1_Msk (0x1UL << MPU_PERR0_SPI1_TWI1_Pos) /*!< Bit mask of SPI1_TWI1 field. */
+#define MPU_PERR0_SPI1_TWI1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_SPI1_TWI1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 3 : SPI0 and TWI0 region configuration. */
+#define MPU_PERR0_SPI0_TWI0_Pos (3UL) /*!< Position of SPI0_TWI0 field. */
+#define MPU_PERR0_SPI0_TWI0_Msk (0x1UL << MPU_PERR0_SPI0_TWI0_Pos) /*!< Bit mask of SPI0_TWI0 field. */
+#define MPU_PERR0_SPI0_TWI0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_SPI0_TWI0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 2 : UART0 region configuration. */
+#define MPU_PERR0_UART0_Pos (2UL) /*!< Position of UART0 field. */
+#define MPU_PERR0_UART0_Msk (0x1UL << MPU_PERR0_UART0_Pos) /*!< Bit mask of UART0 field. */
+#define MPU_PERR0_UART0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_UART0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 1 : RADIO region configuration. */
+#define MPU_PERR0_RADIO_Pos (1UL) /*!< Position of RADIO field. */
+#define MPU_PERR0_RADIO_Msk (0x1UL << MPU_PERR0_RADIO_Pos) /*!< Bit mask of RADIO field. */
+#define MPU_PERR0_RADIO_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RADIO_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 0 : POWER_CLOCK region configuration. */
+#define MPU_PERR0_POWER_CLOCK_Pos (0UL) /*!< Position of POWER_CLOCK field. */
+#define MPU_PERR0_POWER_CLOCK_Msk (0x1UL << MPU_PERR0_POWER_CLOCK_Pos) /*!< Bit mask of POWER_CLOCK field. */
+#define MPU_PERR0_POWER_CLOCK_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_POWER_CLOCK_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Register: MPU_PROTENSET0 */
+/* Description: Erase and write protection bit enable set register. */
+
+/* Bit 31 : Protection enable for region 31. */
+#define MPU_PROTENSET0_PROTREG31_Pos (31UL) /*!< Position of PROTREG31 field. */
+#define MPU_PROTENSET0_PROTREG31_Msk (0x1UL << MPU_PROTENSET0_PROTREG31_Pos) /*!< Bit mask of PROTREG31 field. */
+#define MPU_PROTENSET0_PROTREG31_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG31_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG31_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 30 : Protection enable for region 30. */
+#define MPU_PROTENSET0_PROTREG30_Pos (30UL) /*!< Position of PROTREG30 field. */
+#define MPU_PROTENSET0_PROTREG30_Msk (0x1UL << MPU_PROTENSET0_PROTREG30_Pos) /*!< Bit mask of PROTREG30 field. */
+#define MPU_PROTENSET0_PROTREG30_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG30_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG30_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 29 : Protection enable for region 29. */
+#define MPU_PROTENSET0_PROTREG29_Pos (29UL) /*!< Position of PROTREG29 field. */
+#define MPU_PROTENSET0_PROTREG29_Msk (0x1UL << MPU_PROTENSET0_PROTREG29_Pos) /*!< Bit mask of PROTREG29 field. */
+#define MPU_PROTENSET0_PROTREG29_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG29_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG29_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 28 : Protection enable for region 28. */
+#define MPU_PROTENSET0_PROTREG28_Pos (28UL) /*!< Position of PROTREG28 field. */
+#define MPU_PROTENSET0_PROTREG28_Msk (0x1UL << MPU_PROTENSET0_PROTREG28_Pos) /*!< Bit mask of PROTREG28 field. */
+#define MPU_PROTENSET0_PROTREG28_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG28_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG28_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 27 : Protection enable for region 27. */
+#define MPU_PROTENSET0_PROTREG27_Pos (27UL) /*!< Position of PROTREG27 field. */
+#define MPU_PROTENSET0_PROTREG27_Msk (0x1UL << MPU_PROTENSET0_PROTREG27_Pos) /*!< Bit mask of PROTREG27 field. */
+#define MPU_PROTENSET0_PROTREG27_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG27_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG27_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 26 : Protection enable for region 26. */
+#define MPU_PROTENSET0_PROTREG26_Pos (26UL) /*!< Position of PROTREG26 field. */
+#define MPU_PROTENSET0_PROTREG26_Msk (0x1UL << MPU_PROTENSET0_PROTREG26_Pos) /*!< Bit mask of PROTREG26 field. */
+#define MPU_PROTENSET0_PROTREG26_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG26_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG26_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 25 : Protection enable for region 25. */
+#define MPU_PROTENSET0_PROTREG25_Pos (25UL) /*!< Position of PROTREG25 field. */
+#define MPU_PROTENSET0_PROTREG25_Msk (0x1UL << MPU_PROTENSET0_PROTREG25_Pos) /*!< Bit mask of PROTREG25 field. */
+#define MPU_PROTENSET0_PROTREG25_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG25_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG25_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 24 : Protection enable for region 24. */
+#define MPU_PROTENSET0_PROTREG24_Pos (24UL) /*!< Position of PROTREG24 field. */
+#define MPU_PROTENSET0_PROTREG24_Msk (0x1UL << MPU_PROTENSET0_PROTREG24_Pos) /*!< Bit mask of PROTREG24 field. */
+#define MPU_PROTENSET0_PROTREG24_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG24_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG24_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 23 : Protection enable for region 23. */
+#define MPU_PROTENSET0_PROTREG23_Pos (23UL) /*!< Position of PROTREG23 field. */
+#define MPU_PROTENSET0_PROTREG23_Msk (0x1UL << MPU_PROTENSET0_PROTREG23_Pos) /*!< Bit mask of PROTREG23 field. */
+#define MPU_PROTENSET0_PROTREG23_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG23_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG23_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 22 : Protection enable for region 22. */
+#define MPU_PROTENSET0_PROTREG22_Pos (22UL) /*!< Position of PROTREG22 field. */
+#define MPU_PROTENSET0_PROTREG22_Msk (0x1UL << MPU_PROTENSET0_PROTREG22_Pos) /*!< Bit mask of PROTREG22 field. */
+#define MPU_PROTENSET0_PROTREG22_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG22_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG22_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 21 : Protection enable for region 21. */
+#define MPU_PROTENSET0_PROTREG21_Pos (21UL) /*!< Position of PROTREG21 field. */
+#define MPU_PROTENSET0_PROTREG21_Msk (0x1UL << MPU_PROTENSET0_PROTREG21_Pos) /*!< Bit mask of PROTREG21 field. */
+#define MPU_PROTENSET0_PROTREG21_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG21_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG21_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 20 : Protection enable for region 20. */
+#define MPU_PROTENSET0_PROTREG20_Pos (20UL) /*!< Position of PROTREG20 field. */
+#define MPU_PROTENSET0_PROTREG20_Msk (0x1UL << MPU_PROTENSET0_PROTREG20_Pos) /*!< Bit mask of PROTREG20 field. */
+#define MPU_PROTENSET0_PROTREG20_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG20_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG20_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 19 : Protection enable for region 19. */
+#define MPU_PROTENSET0_PROTREG19_Pos (19UL) /*!< Position of PROTREG19 field. */
+#define MPU_PROTENSET0_PROTREG19_Msk (0x1UL << MPU_PROTENSET0_PROTREG19_Pos) /*!< Bit mask of PROTREG19 field. */
+#define MPU_PROTENSET0_PROTREG19_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG19_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG19_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 18 : Protection enable for region 18. */
+#define MPU_PROTENSET0_PROTREG18_Pos (18UL) /*!< Position of PROTREG18 field. */
+#define MPU_PROTENSET0_PROTREG18_Msk (0x1UL << MPU_PROTENSET0_PROTREG18_Pos) /*!< Bit mask of PROTREG18 field. */
+#define MPU_PROTENSET0_PROTREG18_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG18_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG18_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 17 : Protection enable for region 17. */
+#define MPU_PROTENSET0_PROTREG17_Pos (17UL) /*!< Position of PROTREG17 field. */
+#define MPU_PROTENSET0_PROTREG17_Msk (0x1UL << MPU_PROTENSET0_PROTREG17_Pos) /*!< Bit mask of PROTREG17 field. */
+#define MPU_PROTENSET0_PROTREG17_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG17_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG17_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 16 : Protection enable for region 16. */
+#define MPU_PROTENSET0_PROTREG16_Pos (16UL) /*!< Position of PROTREG16 field. */
+#define MPU_PROTENSET0_PROTREG16_Msk (0x1UL << MPU_PROTENSET0_PROTREG16_Pos) /*!< Bit mask of PROTREG16 field. */
+#define MPU_PROTENSET0_PROTREG16_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG16_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG16_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 15 : Protection enable for region 15. */
+#define MPU_PROTENSET0_PROTREG15_Pos (15UL) /*!< Position of PROTREG15 field. */
+#define MPU_PROTENSET0_PROTREG15_Msk (0x1UL << MPU_PROTENSET0_PROTREG15_Pos) /*!< Bit mask of PROTREG15 field. */
+#define MPU_PROTENSET0_PROTREG15_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG15_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG15_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 14 : Protection enable for region 14. */
+#define MPU_PROTENSET0_PROTREG14_Pos (14UL) /*!< Position of PROTREG14 field. */
+#define MPU_PROTENSET0_PROTREG14_Msk (0x1UL << MPU_PROTENSET0_PROTREG14_Pos) /*!< Bit mask of PROTREG14 field. */
+#define MPU_PROTENSET0_PROTREG14_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG14_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG14_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 13 : Protection enable for region 13. */
+#define MPU_PROTENSET0_PROTREG13_Pos (13UL) /*!< Position of PROTREG13 field. */
+#define MPU_PROTENSET0_PROTREG13_Msk (0x1UL << MPU_PROTENSET0_PROTREG13_Pos) /*!< Bit mask of PROTREG13 field. */
+#define MPU_PROTENSET0_PROTREG13_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG13_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG13_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 12 : Protection enable for region 12. */
+#define MPU_PROTENSET0_PROTREG12_Pos (12UL) /*!< Position of PROTREG12 field. */
+#define MPU_PROTENSET0_PROTREG12_Msk (0x1UL << MPU_PROTENSET0_PROTREG12_Pos) /*!< Bit mask of PROTREG12 field. */
+#define MPU_PROTENSET0_PROTREG12_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG12_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG12_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 11 : Protection enable for region 11. */
+#define MPU_PROTENSET0_PROTREG11_Pos (11UL) /*!< Position of PROTREG11 field. */
+#define MPU_PROTENSET0_PROTREG11_Msk (0x1UL << MPU_PROTENSET0_PROTREG11_Pos) /*!< Bit mask of PROTREG11 field. */
+#define MPU_PROTENSET0_PROTREG11_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG11_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG11_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 10 : Protection enable for region 10. */
+#define MPU_PROTENSET0_PROTREG10_Pos (10UL) /*!< Position of PROTREG10 field. */
+#define MPU_PROTENSET0_PROTREG10_Msk (0x1UL << MPU_PROTENSET0_PROTREG10_Pos) /*!< Bit mask of PROTREG10 field. */
+#define MPU_PROTENSET0_PROTREG10_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG10_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG10_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 9 : Protection enable for region 9. */
+#define MPU_PROTENSET0_PROTREG9_Pos (9UL) /*!< Position of PROTREG9 field. */
+#define MPU_PROTENSET0_PROTREG9_Msk (0x1UL << MPU_PROTENSET0_PROTREG9_Pos) /*!< Bit mask of PROTREG9 field. */
+#define MPU_PROTENSET0_PROTREG9_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG9_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG9_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 8 : Protection enable for region 8. */
+#define MPU_PROTENSET0_PROTREG8_Pos (8UL) /*!< Position of PROTREG8 field. */
+#define MPU_PROTENSET0_PROTREG8_Msk (0x1UL << MPU_PROTENSET0_PROTREG8_Pos) /*!< Bit mask of PROTREG8 field. */
+#define MPU_PROTENSET0_PROTREG8_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG8_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG8_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 7 : Protection enable for region 7. */
+#define MPU_PROTENSET0_PROTREG7_Pos (7UL) /*!< Position of PROTREG7 field. */
+#define MPU_PROTENSET0_PROTREG7_Msk (0x1UL << MPU_PROTENSET0_PROTREG7_Pos) /*!< Bit mask of PROTREG7 field. */
+#define MPU_PROTENSET0_PROTREG7_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG7_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG7_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 6 : Protection enable for region 6. */
+#define MPU_PROTENSET0_PROTREG6_Pos (6UL) /*!< Position of PROTREG6 field. */
+#define MPU_PROTENSET0_PROTREG6_Msk (0x1UL << MPU_PROTENSET0_PROTREG6_Pos) /*!< Bit mask of PROTREG6 field. */
+#define MPU_PROTENSET0_PROTREG6_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG6_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG6_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 5 : Protection enable for region 5. */
+#define MPU_PROTENSET0_PROTREG5_Pos (5UL) /*!< Position of PROTREG5 field. */
+#define MPU_PROTENSET0_PROTREG5_Msk (0x1UL << MPU_PROTENSET0_PROTREG5_Pos) /*!< Bit mask of PROTREG5 field. */
+#define MPU_PROTENSET0_PROTREG5_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG5_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG5_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 4 : Protection enable for region 4. */
+#define MPU_PROTENSET0_PROTREG4_Pos (4UL) /*!< Position of PROTREG4 field. */
+#define MPU_PROTENSET0_PROTREG4_Msk (0x1UL << MPU_PROTENSET0_PROTREG4_Pos) /*!< Bit mask of PROTREG4 field. */
+#define MPU_PROTENSET0_PROTREG4_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG4_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG4_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 3 : Protection enable for region 3. */
+#define MPU_PROTENSET0_PROTREG3_Pos (3UL) /*!< Position of PROTREG3 field. */
+#define MPU_PROTENSET0_PROTREG3_Msk (0x1UL << MPU_PROTENSET0_PROTREG3_Pos) /*!< Bit mask of PROTREG3 field. */
+#define MPU_PROTENSET0_PROTREG3_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG3_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG3_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 2 : Protection enable for region 2. */
+#define MPU_PROTENSET0_PROTREG2_Pos (2UL) /*!< Position of PROTREG2 field. */
+#define MPU_PROTENSET0_PROTREG2_Msk (0x1UL << MPU_PROTENSET0_PROTREG2_Pos) /*!< Bit mask of PROTREG2 field. */
+#define MPU_PROTENSET0_PROTREG2_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG2_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG2_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 1 : Protection enable for region 1. */
+#define MPU_PROTENSET0_PROTREG1_Pos (1UL) /*!< Position of PROTREG1 field. */
+#define MPU_PROTENSET0_PROTREG1_Msk (0x1UL << MPU_PROTENSET0_PROTREG1_Pos) /*!< Bit mask of PROTREG1 field. */
+#define MPU_PROTENSET0_PROTREG1_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG1_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG1_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 0 : Protection enable for region 0. */
+#define MPU_PROTENSET0_PROTREG0_Pos (0UL) /*!< Position of PROTREG0 field. */
+#define MPU_PROTENSET0_PROTREG0_Msk (0x1UL << MPU_PROTENSET0_PROTREG0_Pos) /*!< Bit mask of PROTREG0 field. */
+#define MPU_PROTENSET0_PROTREG0_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG0_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG0_Set (1UL) /*!< Enable protection on write. */
+
+/* Register: MPU_PROTENSET1 */
+/* Description: Erase and write protection bit enable set register. */
+
+/* Bit 31 : Protection enable for region 63. */
+#define MPU_PROTENSET1_PROTREG63_Pos (31UL) /*!< Position of PROTREG63 field. */
+#define MPU_PROTENSET1_PROTREG63_Msk (0x1UL << MPU_PROTENSET1_PROTREG63_Pos) /*!< Bit mask of PROTREG63 field. */
+#define MPU_PROTENSET1_PROTREG63_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG63_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG63_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 30 : Protection enable for region 62. */
+#define MPU_PROTENSET1_PROTREG62_Pos (30UL) /*!< Position of PROTREG62 field. */
+#define MPU_PROTENSET1_PROTREG62_Msk (0x1UL << MPU_PROTENSET1_PROTREG62_Pos) /*!< Bit mask of PROTREG62 field. */
+#define MPU_PROTENSET1_PROTREG62_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG62_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG62_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 29 : Protection enable for region 61. */
+#define MPU_PROTENSET1_PROTREG61_Pos (29UL) /*!< Position of PROTREG61 field. */
+#define MPU_PROTENSET1_PROTREG61_Msk (0x1UL << MPU_PROTENSET1_PROTREG61_Pos) /*!< Bit mask of PROTREG61 field. */
+#define MPU_PROTENSET1_PROTREG61_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG61_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG61_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 28 : Protection enable for region 60. */
+#define MPU_PROTENSET1_PROTREG60_Pos (28UL) /*!< Position of PROTREG60 field. */
+#define MPU_PROTENSET1_PROTREG60_Msk (0x1UL << MPU_PROTENSET1_PROTREG60_Pos) /*!< Bit mask of PROTREG60 field. */
+#define MPU_PROTENSET1_PROTREG60_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG60_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG60_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 27 : Protection enable for region 59. */
+#define MPU_PROTENSET1_PROTREG59_Pos (27UL) /*!< Position of PROTREG59 field. */
+#define MPU_PROTENSET1_PROTREG59_Msk (0x1UL << MPU_PROTENSET1_PROTREG59_Pos) /*!< Bit mask of PROTREG59 field. */
+#define MPU_PROTENSET1_PROTREG59_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG59_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG59_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 26 : Protection enable for region 58. */
+#define MPU_PROTENSET1_PROTREG58_Pos (26UL) /*!< Position of PROTREG58 field. */
+#define MPU_PROTENSET1_PROTREG58_Msk (0x1UL << MPU_PROTENSET1_PROTREG58_Pos) /*!< Bit mask of PROTREG58 field. */
+#define MPU_PROTENSET1_PROTREG58_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG58_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG58_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 25 : Protection enable for region 57. */
+#define MPU_PROTENSET1_PROTREG57_Pos (25UL) /*!< Position of PROTREG57 field. */
+#define MPU_PROTENSET1_PROTREG57_Msk (0x1UL << MPU_PROTENSET1_PROTREG57_Pos) /*!< Bit mask of PROTREG57 field. */
+#define MPU_PROTENSET1_PROTREG57_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG57_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG57_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 24 : Protection enable for region 56. */
+#define MPU_PROTENSET1_PROTREG56_Pos (24UL) /*!< Position of PROTREG56 field. */
+#define MPU_PROTENSET1_PROTREG56_Msk (0x1UL << MPU_PROTENSET1_PROTREG56_Pos) /*!< Bit mask of PROTREG56 field. */
+#define MPU_PROTENSET1_PROTREG56_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG56_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG56_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 23 : Protection enable for region 55. */
+#define MPU_PROTENSET1_PROTREG55_Pos (23UL) /*!< Position of PROTREG55 field. */
+#define MPU_PROTENSET1_PROTREG55_Msk (0x1UL << MPU_PROTENSET1_PROTREG55_Pos) /*!< Bit mask of PROTREG55 field. */
+#define MPU_PROTENSET1_PROTREG55_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG55_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG55_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 22 : Protection enable for region 54. */
+#define MPU_PROTENSET1_PROTREG54_Pos (22UL) /*!< Position of PROTREG54 field. */
+#define MPU_PROTENSET1_PROTREG54_Msk (0x1UL << MPU_PROTENSET1_PROTREG54_Pos) /*!< Bit mask of PROTREG54 field. */
+#define MPU_PROTENSET1_PROTREG54_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG54_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG54_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 21 : Protection enable for region 53. */
+#define MPU_PROTENSET1_PROTREG53_Pos (21UL) /*!< Position of PROTREG53 field. */
+#define MPU_PROTENSET1_PROTREG53_Msk (0x1UL << MPU_PROTENSET1_PROTREG53_Pos) /*!< Bit mask of PROTREG53 field. */
+#define MPU_PROTENSET1_PROTREG53_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG53_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG53_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 20 : Protection enable for region 52. */
+#define MPU_PROTENSET1_PROTREG52_Pos (20UL) /*!< Position of PROTREG52 field. */
+#define MPU_PROTENSET1_PROTREG52_Msk (0x1UL << MPU_PROTENSET1_PROTREG52_Pos) /*!< Bit mask of PROTREG52 field. */
+#define MPU_PROTENSET1_PROTREG52_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG52_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG52_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 19 : Protection enable for region 51. */
+#define MPU_PROTENSET1_PROTREG51_Pos (19UL) /*!< Position of PROTREG51 field. */
+#define MPU_PROTENSET1_PROTREG51_Msk (0x1UL << MPU_PROTENSET1_PROTREG51_Pos) /*!< Bit mask of PROTREG51 field. */
+#define MPU_PROTENSET1_PROTREG51_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG51_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG51_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 18 : Protection enable for region 50. */
+#define MPU_PROTENSET1_PROTREG50_Pos (18UL) /*!< Position of PROTREG50 field. */
+#define MPU_PROTENSET1_PROTREG50_Msk (0x1UL << MPU_PROTENSET1_PROTREG50_Pos) /*!< Bit mask of PROTREG50 field. */
+#define MPU_PROTENSET1_PROTREG50_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG50_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG50_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 17 : Protection enable for region 49. */
+#define MPU_PROTENSET1_PROTREG49_Pos (17UL) /*!< Position of PROTREG49 field. */
+#define MPU_PROTENSET1_PROTREG49_Msk (0x1UL << MPU_PROTENSET1_PROTREG49_Pos) /*!< Bit mask of PROTREG49 field. */
+#define MPU_PROTENSET1_PROTREG49_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG49_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG49_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 16 : Protection enable for region 48. */
+#define MPU_PROTENSET1_PROTREG48_Pos (16UL) /*!< Position of PROTREG48 field. */
+#define MPU_PROTENSET1_PROTREG48_Msk (0x1UL << MPU_PROTENSET1_PROTREG48_Pos) /*!< Bit mask of PROTREG48 field. */
+#define MPU_PROTENSET1_PROTREG48_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG48_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG48_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 15 : Protection enable for region 47. */
+#define MPU_PROTENSET1_PROTREG47_Pos (15UL) /*!< Position of PROTREG47 field. */
+#define MPU_PROTENSET1_PROTREG47_Msk (0x1UL << MPU_PROTENSET1_PROTREG47_Pos) /*!< Bit mask of PROTREG47 field. */
+#define MPU_PROTENSET1_PROTREG47_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG47_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG47_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 14 : Protection enable for region 46. */
+#define MPU_PROTENSET1_PROTREG46_Pos (14UL) /*!< Position of PROTREG46 field. */
+#define MPU_PROTENSET1_PROTREG46_Msk (0x1UL << MPU_PROTENSET1_PROTREG46_Pos) /*!< Bit mask of PROTREG46 field. */
+#define MPU_PROTENSET1_PROTREG46_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG46_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG46_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 13 : Protection enable for region 45. */
+#define MPU_PROTENSET1_PROTREG45_Pos (13UL) /*!< Position of PROTREG45 field. */
+#define MPU_PROTENSET1_PROTREG45_Msk (0x1UL << MPU_PROTENSET1_PROTREG45_Pos) /*!< Bit mask of PROTREG45 field. */
+#define MPU_PROTENSET1_PROTREG45_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG45_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG45_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 12 : Protection enable for region 44. */
+#define MPU_PROTENSET1_PROTREG44_Pos (12UL) /*!< Position of PROTREG44 field. */
+#define MPU_PROTENSET1_PROTREG44_Msk (0x1UL << MPU_PROTENSET1_PROTREG44_Pos) /*!< Bit mask of PROTREG44 field. */
+#define MPU_PROTENSET1_PROTREG44_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG44_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG44_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 11 : Protection enable for region 43. */
+#define MPU_PROTENSET1_PROTREG43_Pos (11UL) /*!< Position of PROTREG43 field. */
+#define MPU_PROTENSET1_PROTREG43_Msk (0x1UL << MPU_PROTENSET1_PROTREG43_Pos) /*!< Bit mask of PROTREG43 field. */
+#define MPU_PROTENSET1_PROTREG43_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG43_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG43_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 10 : Protection enable for region 42. */
+#define MPU_PROTENSET1_PROTREG42_Pos (10UL) /*!< Position of PROTREG42 field. */
+#define MPU_PROTENSET1_PROTREG42_Msk (0x1UL << MPU_PROTENSET1_PROTREG42_Pos) /*!< Bit mask of PROTREG42 field. */
+#define MPU_PROTENSET1_PROTREG42_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG42_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG42_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 9 : Protection enable for region 41. */
+#define MPU_PROTENSET1_PROTREG41_Pos (9UL) /*!< Position of PROTREG41 field. */
+#define MPU_PROTENSET1_PROTREG41_Msk (0x1UL << MPU_PROTENSET1_PROTREG41_Pos) /*!< Bit mask of PROTREG41 field. */
+#define MPU_PROTENSET1_PROTREG41_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG41_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG41_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 8 : Protection enable for region 40. */
+#define MPU_PROTENSET1_PROTREG40_Pos (8UL) /*!< Position of PROTREG40 field. */
+#define MPU_PROTENSET1_PROTREG40_Msk (0x1UL << MPU_PROTENSET1_PROTREG40_Pos) /*!< Bit mask of PROTREG40 field. */
+#define MPU_PROTENSET1_PROTREG40_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG40_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG40_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 7 : Protection enable for region 39. */
+#define MPU_PROTENSET1_PROTREG39_Pos (7UL) /*!< Position of PROTREG39 field. */
+#define MPU_PROTENSET1_PROTREG39_Msk (0x1UL << MPU_PROTENSET1_PROTREG39_Pos) /*!< Bit mask of PROTREG39 field. */
+#define MPU_PROTENSET1_PROTREG39_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG39_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG39_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 6 : Protection enable for region 38. */
+#define MPU_PROTENSET1_PROTREG38_Pos (6UL) /*!< Position of PROTREG38 field. */
+#define MPU_PROTENSET1_PROTREG38_Msk (0x1UL << MPU_PROTENSET1_PROTREG38_Pos) /*!< Bit mask of PROTREG38 field. */
+#define MPU_PROTENSET1_PROTREG38_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG38_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG38_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 5 : Protection enable for region 37. */
+#define MPU_PROTENSET1_PROTREG37_Pos (5UL) /*!< Position of PROTREG37 field. */
+#define MPU_PROTENSET1_PROTREG37_Msk (0x1UL << MPU_PROTENSET1_PROTREG37_Pos) /*!< Bit mask of PROTREG37 field. */
+#define MPU_PROTENSET1_PROTREG37_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG37_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG37_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 4 : Protection enable for region 36. */
+#define MPU_PROTENSET1_PROTREG36_Pos (4UL) /*!< Position of PROTREG36 field. */
+#define MPU_PROTENSET1_PROTREG36_Msk (0x1UL << MPU_PROTENSET1_PROTREG36_Pos) /*!< Bit mask of PROTREG36 field. */
+#define MPU_PROTENSET1_PROTREG36_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG36_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG36_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 3 : Protection enable for region 35. */
+#define MPU_PROTENSET1_PROTREG35_Pos (3UL) /*!< Position of PROTREG35 field. */
+#define MPU_PROTENSET1_PROTREG35_Msk (0x1UL << MPU_PROTENSET1_PROTREG35_Pos) /*!< Bit mask of PROTREG35 field. */
+#define MPU_PROTENSET1_PROTREG35_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG35_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG35_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 2 : Protection enable for region 34. */
+#define MPU_PROTENSET1_PROTREG34_Pos (2UL) /*!< Position of PROTREG34 field. */
+#define MPU_PROTENSET1_PROTREG34_Msk (0x1UL << MPU_PROTENSET1_PROTREG34_Pos) /*!< Bit mask of PROTREG34 field. */
+#define MPU_PROTENSET1_PROTREG34_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG34_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG34_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 1 : Protection enable for region 33. */
+#define MPU_PROTENSET1_PROTREG33_Pos (1UL) /*!< Position of PROTREG33 field. */
+#define MPU_PROTENSET1_PROTREG33_Msk (0x1UL << MPU_PROTENSET1_PROTREG33_Pos) /*!< Bit mask of PROTREG33 field. */
+#define MPU_PROTENSET1_PROTREG33_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG33_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG33_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 0 : Protection enable for region 32. */
+#define MPU_PROTENSET1_PROTREG32_Pos (0UL) /*!< Position of PROTREG32 field. */
+#define MPU_PROTENSET1_PROTREG32_Msk (0x1UL << MPU_PROTENSET1_PROTREG32_Pos) /*!< Bit mask of PROTREG32 field. */
+#define MPU_PROTENSET1_PROTREG32_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG32_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG32_Set (1UL) /*!< Enable protection on write. */
+
+/* Register: MPU_DISABLEINDEBUG */
+/* Description: Disable erase and write protection mechanism in debug mode. */
+
+/* Bit 0 : Disable protection mechanism in debug mode. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos (0UL) /*!< Position of DISABLEINDEBUG field. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Msk (0x1UL << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos) /*!< Bit mask of DISABLEINDEBUG field. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Enabled (0UL) /*!< Protection enabled. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled (1UL) /*!< Protection disabled. */
+
+/* Register: MPU_PROTBLOCKSIZE */
+/* Description: Erase and write protection block size. */
+
+/* Bits 1..0 : Erase and write protection block size. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Pos (0UL) /*!< Position of PROTBLOCKSIZE field. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Msk (0x3UL << MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Pos) /*!< Bit mask of PROTBLOCKSIZE field. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_4k (0UL) /*!< Erase and write protection block size is 4k. */
+
+
+/* Peripheral: NVMC */
+/* Description: Non Volatile Memory Controller. */
+
+/* Register: NVMC_READY */
+/* Description: Ready flag. */
+
+/* Bit 0 : NVMC ready. */
+#define NVMC_READY_READY_Pos (0UL) /*!< Position of READY field. */
+#define NVMC_READY_READY_Msk (0x1UL << NVMC_READY_READY_Pos) /*!< Bit mask of READY field. */
+#define NVMC_READY_READY_Busy (0UL) /*!< NVMC is busy (on-going write or erase operation). */
+#define NVMC_READY_READY_Ready (1UL) /*!< NVMC is ready. */
+
+/* Register: NVMC_CONFIG */
+/* Description: Configuration register. */
+
+/* Bits 1..0 : Program write enable. */
+#define NVMC_CONFIG_WEN_Pos (0UL) /*!< Position of WEN field. */
+#define NVMC_CONFIG_WEN_Msk (0x3UL << NVMC_CONFIG_WEN_Pos) /*!< Bit mask of WEN field. */
+#define NVMC_CONFIG_WEN_Ren (0x00UL) /*!< Read only access. */
+#define NVMC_CONFIG_WEN_Wen (0x01UL) /*!< Write enabled. */
+#define NVMC_CONFIG_WEN_Een (0x02UL) /*!< Erase enabled. */
+
+/* Register: NVMC_ERASEALL */
+/* Description: Register for erasing all non-volatile user memory. */
+
+/* Bit 0 : Starts the erasing of all user NVM (code region 0/1 and UICR registers). */
+#define NVMC_ERASEALL_ERASEALL_Pos (0UL) /*!< Position of ERASEALL field. */
+#define NVMC_ERASEALL_ERASEALL_Msk (0x1UL << NVMC_ERASEALL_ERASEALL_Pos) /*!< Bit mask of ERASEALL field. */
+#define NVMC_ERASEALL_ERASEALL_NoOperation (0UL) /*!< No operation. */
+#define NVMC_ERASEALL_ERASEALL_Erase (1UL) /*!< Start chip erase. */
+
+/* Register: NVMC_ERASEUICR */
+/* Description: Register for start erasing User Information Congfiguration Registers. */
+
+/* Bit 0 : It can only be used when all contents of code region 1 are erased. */
+#define NVMC_ERASEUICR_ERASEUICR_Pos (0UL) /*!< Position of ERASEUICR field. */
+#define NVMC_ERASEUICR_ERASEUICR_Msk (0x1UL << NVMC_ERASEUICR_ERASEUICR_Pos) /*!< Bit mask of ERASEUICR field. */
+#define NVMC_ERASEUICR_ERASEUICR_NoOperation (0UL) /*!< No operation. */
+#define NVMC_ERASEUICR_ERASEUICR_Erase (1UL) /*!< Start UICR erase. */
+
+
+/* Peripheral: POWER */
+/* Description: Power Control. */
+
+/* Register: POWER_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on POFWARN event. */
+#define POWER_INTENSET_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */
+#define POWER_INTENSET_POFWARN_Msk (0x1UL << POWER_INTENSET_POFWARN_Pos) /*!< Bit mask of POFWARN field. */
+#define POWER_INTENSET_POFWARN_Disabled (0UL) /*!< Interrupt disabled. */
+#define POWER_INTENSET_POFWARN_Enabled (1UL) /*!< Interrupt enabled. */
+#define POWER_INTENSET_POFWARN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: POWER_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on POFWARN event. */
+#define POWER_INTENCLR_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */
+#define POWER_INTENCLR_POFWARN_Msk (0x1UL << POWER_INTENCLR_POFWARN_Pos) /*!< Bit mask of POFWARN field. */
+#define POWER_INTENCLR_POFWARN_Disabled (0UL) /*!< Interrupt disabled. */
+#define POWER_INTENCLR_POFWARN_Enabled (1UL) /*!< Interrupt enabled. */
+#define POWER_INTENCLR_POFWARN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: POWER_RESETREAS */
+/* Description: Reset reason. */
+
+/* Bit 18 : Reset from wake-up from OFF mode detected by entering into debug interface mode. */
+#define POWER_RESETREAS_DIF_Pos (18UL) /*!< Position of DIF field. */
+#define POWER_RESETREAS_DIF_Msk (0x1UL << POWER_RESETREAS_DIF_Pos) /*!< Bit mask of DIF field. */
+
+/* Bit 17 : Reset from wake-up from OFF mode detected by the use of ANADETECT signal from LPCOMP. */
+#define POWER_RESETREAS_LPCOMP_Pos (17UL) /*!< Position of LPCOMP field. */
+#define POWER_RESETREAS_LPCOMP_Msk (0x1UL << POWER_RESETREAS_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */
+
+/* Bit 16 : Reset from wake-up from OFF mode detected by the use of DETECT signal from GPIO. */
+#define POWER_RESETREAS_OFF_Pos (16UL) /*!< Position of OFF field. */
+#define POWER_RESETREAS_OFF_Msk (0x1UL << POWER_RESETREAS_OFF_Pos) /*!< Bit mask of OFF field. */
+
+/* Bit 3 : Reset from CPU lock-up detected. */
+#define POWER_RESETREAS_LOCKUP_Pos (3UL) /*!< Position of LOCKUP field. */
+#define POWER_RESETREAS_LOCKUP_Msk (0x1UL << POWER_RESETREAS_LOCKUP_Pos) /*!< Bit mask of LOCKUP field. */
+
+/* Bit 2 : Reset from AIRCR.SYSRESETREQ detected. */
+#define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */
+#define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */
+
+/* Bit 1 : Reset from watchdog detected. */
+#define POWER_RESETREAS_DOG_Pos (1UL) /*!< Position of DOG field. */
+#define POWER_RESETREAS_DOG_Msk (0x1UL << POWER_RESETREAS_DOG_Pos) /*!< Bit mask of DOG field. */
+
+/* Bit 0 : Reset from pin-reset detected. */
+#define POWER_RESETREAS_RESETPIN_Pos (0UL) /*!< Position of RESETPIN field. */
+#define POWER_RESETREAS_RESETPIN_Msk (0x1UL << POWER_RESETREAS_RESETPIN_Pos) /*!< Bit mask of RESETPIN field. */
+
+/* Register: POWER_RAMSTATUS */
+/* Description: Ram status register. */
+
+/* Bit 3 : RAM block 3 status. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Pos (3UL) /*!< Position of RAMBLOCK3 field. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK3_Pos) /*!< Bit mask of RAMBLOCK3 field. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Off (0UL) /*!< RAM block 3 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK3_On (1UL) /*!< RAM block 3 is on. */
+
+/* Bit 2 : RAM block 2 status. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Pos (2UL) /*!< Position of RAMBLOCK2 field. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK2_Pos) /*!< Bit mask of RAMBLOCK2 field. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Off (0UL) /*!< RAM block 2 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK2_On (1UL) /*!< RAM block 2 is on. */
+
+/* Bit 1 : RAM block 1 status. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Pos (1UL) /*!< Position of RAMBLOCK1 field. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK1_Pos) /*!< Bit mask of RAMBLOCK1 field. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Off (0UL) /*!< RAM block 1 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK1_On (1UL) /*!< RAM block 1 is on. */
+
+/* Bit 0 : RAM block 0 status. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Pos (0UL) /*!< Position of RAMBLOCK0 field. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK0_Pos) /*!< Bit mask of RAMBLOCK0 field. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Off (0UL) /*!< RAM block 0 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK0_On (1UL) /*!< RAM block 0 is on. */
+
+/* Register: POWER_SYSTEMOFF */
+/* Description: System off register. */
+
+/* Bit 0 : Enter system off mode. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Pos (0UL) /*!< Position of SYSTEMOFF field. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Msk (0x1UL << POWER_SYSTEMOFF_SYSTEMOFF_Pos) /*!< Bit mask of SYSTEMOFF field. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Enter (1UL) /*!< Enter system off mode. */
+
+/* Register: POWER_POFCON */
+/* Description: Power failure configuration. */
+
+/* Bits 2..1 : Set threshold level. */
+#define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */
+#define POWER_POFCON_THRESHOLD_Msk (0x3UL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */
+#define POWER_POFCON_THRESHOLD_V21 (0x00UL) /*!< Set threshold to 2.1Volts. */
+#define POWER_POFCON_THRESHOLD_V23 (0x01UL) /*!< Set threshold to 2.3Volts. */
+#define POWER_POFCON_THRESHOLD_V25 (0x02UL) /*!< Set threshold to 2.5Volts. */
+#define POWER_POFCON_THRESHOLD_V27 (0x03UL) /*!< Set threshold to 2.7Volts. */
+
+/* Bit 0 : Power failure comparator enable. */
+#define POWER_POFCON_POF_Pos (0UL) /*!< Position of POF field. */
+#define POWER_POFCON_POF_Msk (0x1UL << POWER_POFCON_POF_Pos) /*!< Bit mask of POF field. */
+#define POWER_POFCON_POF_Disabled (0UL) /*!< Disabled. */
+#define POWER_POFCON_POF_Enabled (1UL) /*!< Enabled. */
+
+/* Register: POWER_GPREGRET */
+/* Description: General purpose retention register. This register is a retained register. */
+
+/* Bits 7..0 : General purpose retention register. */
+#define POWER_GPREGRET_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */
+#define POWER_GPREGRET_GPREGRET_Msk (0xFFUL << POWER_GPREGRET_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */
+
+/* Register: POWER_RAMON */
+/* Description: Ram on/off. */
+
+/* Bit 17 : RAM block 1 behaviour in OFF mode. */
+#define POWER_RAMON_OFFRAM1_Pos (17UL) /*!< Position of OFFRAM1 field. */
+#define POWER_RAMON_OFFRAM1_Msk (0x1UL << POWER_RAMON_OFFRAM1_Pos) /*!< Bit mask of OFFRAM1 field. */
+#define POWER_RAMON_OFFRAM1_RAM1Off (0UL) /*!< RAM block 1 OFF in OFF mode. */
+#define POWER_RAMON_OFFRAM1_RAM1On (1UL) /*!< RAM block 1 ON in OFF mode. */
+
+/* Bit 16 : RAM block 0 behaviour in OFF mode. */
+#define POWER_RAMON_OFFRAM0_Pos (16UL) /*!< Position of OFFRAM0 field. */
+#define POWER_RAMON_OFFRAM0_Msk (0x1UL << POWER_RAMON_OFFRAM0_Pos) /*!< Bit mask of OFFRAM0 field. */
+#define POWER_RAMON_OFFRAM0_RAM0Off (0UL) /*!< RAM block 0 OFF in OFF mode. */
+#define POWER_RAMON_OFFRAM0_RAM0On (1UL) /*!< RAM block 0 ON in OFF mode. */
+
+/* Bit 1 : RAM block 1 behaviour in ON mode. */
+#define POWER_RAMON_ONRAM1_Pos (1UL) /*!< Position of ONRAM1 field. */
+#define POWER_RAMON_ONRAM1_Msk (0x1UL << POWER_RAMON_ONRAM1_Pos) /*!< Bit mask of ONRAM1 field. */
+#define POWER_RAMON_ONRAM1_RAM1Off (0UL) /*!< RAM block 1 OFF in ON mode. */
+#define POWER_RAMON_ONRAM1_RAM1On (1UL) /*!< RAM block 1 ON in ON mode. */
+
+/* Bit 0 : RAM block 0 behaviour in ON mode. */
+#define POWER_RAMON_ONRAM0_Pos (0UL) /*!< Position of ONRAM0 field. */
+#define POWER_RAMON_ONRAM0_Msk (0x1UL << POWER_RAMON_ONRAM0_Pos) /*!< Bit mask of ONRAM0 field. */
+#define POWER_RAMON_ONRAM0_RAM0Off (0UL) /*!< RAM block 0 OFF in ON mode. */
+#define POWER_RAMON_ONRAM0_RAM0On (1UL) /*!< RAM block 0 ON in ON mode. */
+
+/* Register: POWER_RESET */
+/* Description: Pin reset functionality configuration register. This register is a retained register. */
+
+/* Bit 0 : Enable or disable pin reset in debug interface mode. */
+#define POWER_RESET_RESET_Pos (0UL) /*!< Position of RESET field. */
+#define POWER_RESET_RESET_Msk (0x1UL << POWER_RESET_RESET_Pos) /*!< Bit mask of RESET field. */
+#define POWER_RESET_RESET_Disabled (0UL) /*!< Pin reset in debug interface mode disabled. */
+#define POWER_RESET_RESET_Enabled (1UL) /*!< Pin reset in debug interface mode enabled. */
+
+/* Register: POWER_RAMONB */
+/* Description: Ram on/off. */
+
+/* Bit 17 : RAM block 3 behaviour in OFF mode. */
+#define POWER_RAMONB_OFFRAM3_Pos (17UL) /*!< Position of OFFRAM3 field. */
+#define POWER_RAMONB_OFFRAM3_Msk (0x1UL << POWER_RAMONB_OFFRAM3_Pos) /*!< Bit mask of OFFRAM3 field. */
+#define POWER_RAMONB_OFFRAM3_RAM3Off (0UL) /*!< RAM block 3 OFF in OFF mode. */
+#define POWER_RAMONB_OFFRAM3_RAM3On (1UL) /*!< RAM block 3 ON in OFF mode. */
+
+/* Bit 16 : RAM block 2 behaviour in OFF mode. */
+#define POWER_RAMONB_OFFRAM2_Pos (16UL) /*!< Position of OFFRAM2 field. */
+#define POWER_RAMONB_OFFRAM2_Msk (0x1UL << POWER_RAMONB_OFFRAM2_Pos) /*!< Bit mask of OFFRAM2 field. */
+#define POWER_RAMONB_OFFRAM2_RAM2Off (0UL) /*!< RAM block 2 OFF in OFF mode. */
+#define POWER_RAMONB_OFFRAM2_RAM2On (1UL) /*!< RAM block 2 ON in OFF mode. */
+
+/* Bit 1 : RAM block 3 behaviour in ON mode. */
+#define POWER_RAMONB_ONRAM3_Pos (1UL) /*!< Position of ONRAM3 field. */
+#define POWER_RAMONB_ONRAM3_Msk (0x1UL << POWER_RAMONB_ONRAM3_Pos) /*!< Bit mask of ONRAM3 field. */
+#define POWER_RAMONB_ONRAM3_RAM3Off (0UL) /*!< RAM block 33 OFF in ON mode. */
+#define POWER_RAMONB_ONRAM3_RAM3On (1UL) /*!< RAM block 3 ON in ON mode. */
+
+/* Bit 0 : RAM block 2 behaviour in ON mode. */
+#define POWER_RAMONB_ONRAM2_Pos (0UL) /*!< Position of ONRAM2 field. */
+#define POWER_RAMONB_ONRAM2_Msk (0x1UL << POWER_RAMONB_ONRAM2_Pos) /*!< Bit mask of ONRAM2 field. */
+#define POWER_RAMONB_ONRAM2_RAM2Off (0UL) /*!< RAM block 2 OFF in ON mode. */
+#define POWER_RAMONB_ONRAM2_RAM2On (1UL) /*!< RAM block 2 ON in ON mode. */
+
+/* Register: POWER_DCDCEN */
+/* Description: DCDC converter enable configuration register. */
+
+/* Bit 0 : Enable DCDC converter. */
+#define POWER_DCDCEN_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */
+#define POWER_DCDCEN_DCDCEN_Msk (0x1UL << POWER_DCDCEN_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */
+#define POWER_DCDCEN_DCDCEN_Disabled (0UL) /*!< DCDC converter disabled. */
+#define POWER_DCDCEN_DCDCEN_Enabled (1UL) /*!< DCDC converter enabled. */
+
+/* Register: POWER_DCDCFORCE */
+/* Description: DCDC power-up force register. */
+
+/* Bit 1 : DCDC power-up force on. */
+#define POWER_DCDCFORCE_FORCEON_Pos (1UL) /*!< Position of FORCEON field. */
+#define POWER_DCDCFORCE_FORCEON_Msk (0x1UL << POWER_DCDCFORCE_FORCEON_Pos) /*!< Bit mask of FORCEON field. */
+#define POWER_DCDCFORCE_FORCEON_NoForce (0UL) /*!< No force. */
+#define POWER_DCDCFORCE_FORCEON_Force (1UL) /*!< Force. */
+
+/* Bit 0 : DCDC power-up force off. */
+#define POWER_DCDCFORCE_FORCEOFF_Pos (0UL) /*!< Position of FORCEOFF field. */
+#define POWER_DCDCFORCE_FORCEOFF_Msk (0x1UL << POWER_DCDCFORCE_FORCEOFF_Pos) /*!< Bit mask of FORCEOFF field. */
+#define POWER_DCDCFORCE_FORCEOFF_NoForce (0UL) /*!< No force. */
+#define POWER_DCDCFORCE_FORCEOFF_Force (1UL) /*!< Force. */
+
+
+/* Peripheral: PPI */
+/* Description: PPI controller. */
+
+/* Register: PPI_CHEN */
+/* Description: Channel enable. */
+
+/* Bit 31 : Enable PPI channel 31. */
+#define PPI_CHEN_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHEN_CH31_Msk (0x1UL << PPI_CHEN_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHEN_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH31_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 30 : Enable PPI channel 30. */
+#define PPI_CHEN_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHEN_CH30_Msk (0x1UL << PPI_CHEN_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHEN_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH30_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 29 : Enable PPI channel 29. */
+#define PPI_CHEN_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHEN_CH29_Msk (0x1UL << PPI_CHEN_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHEN_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH29_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 28 : Enable PPI channel 28. */
+#define PPI_CHEN_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHEN_CH28_Msk (0x1UL << PPI_CHEN_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHEN_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH28_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 27 : Enable PPI channel 27. */
+#define PPI_CHEN_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHEN_CH27_Msk (0x1UL << PPI_CHEN_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHEN_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH27_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 26 : Enable PPI channel 26. */
+#define PPI_CHEN_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHEN_CH26_Msk (0x1UL << PPI_CHEN_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHEN_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH26_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 25 : Enable PPI channel 25. */
+#define PPI_CHEN_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHEN_CH25_Msk (0x1UL << PPI_CHEN_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHEN_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH25_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 24 : Enable PPI channel 24. */
+#define PPI_CHEN_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHEN_CH24_Msk (0x1UL << PPI_CHEN_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHEN_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH24_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 23 : Enable PPI channel 23. */
+#define PPI_CHEN_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHEN_CH23_Msk (0x1UL << PPI_CHEN_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHEN_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH23_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 22 : Enable PPI channel 22. */
+#define PPI_CHEN_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHEN_CH22_Msk (0x1UL << PPI_CHEN_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHEN_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH22_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 21 : Enable PPI channel 21. */
+#define PPI_CHEN_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHEN_CH21_Msk (0x1UL << PPI_CHEN_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHEN_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH21_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 20 : Enable PPI channel 20. */
+#define PPI_CHEN_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHEN_CH20_Msk (0x1UL << PPI_CHEN_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHEN_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH20_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 15 : Enable PPI channel 15. */
+#define PPI_CHEN_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHEN_CH15_Msk (0x1UL << PPI_CHEN_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHEN_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH15_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 14 : Enable PPI channel 14. */
+#define PPI_CHEN_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHEN_CH14_Msk (0x1UL << PPI_CHEN_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHEN_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH14_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 13 : Enable PPI channel 13. */
+#define PPI_CHEN_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHEN_CH13_Msk (0x1UL << PPI_CHEN_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHEN_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH13_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 12 : Enable PPI channel 12. */
+#define PPI_CHEN_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHEN_CH12_Msk (0x1UL << PPI_CHEN_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHEN_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH12_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 11 : Enable PPI channel 11. */
+#define PPI_CHEN_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHEN_CH11_Msk (0x1UL << PPI_CHEN_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHEN_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH11_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 10 : Enable PPI channel 10. */
+#define PPI_CHEN_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHEN_CH10_Msk (0x1UL << PPI_CHEN_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHEN_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH10_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 9 : Enable PPI channel 9. */
+#define PPI_CHEN_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHEN_CH9_Msk (0x1UL << PPI_CHEN_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHEN_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH9_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 8 : Enable PPI channel 8. */
+#define PPI_CHEN_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHEN_CH8_Msk (0x1UL << PPI_CHEN_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHEN_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH8_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 7 : Enable PPI channel 7. */
+#define PPI_CHEN_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHEN_CH7_Msk (0x1UL << PPI_CHEN_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHEN_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH7_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 6 : Enable PPI channel 6. */
+#define PPI_CHEN_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHEN_CH6_Msk (0x1UL << PPI_CHEN_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHEN_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH6_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 5 : Enable PPI channel 5. */
+#define PPI_CHEN_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHEN_CH5_Msk (0x1UL << PPI_CHEN_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHEN_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH5_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 4 : Enable PPI channel 4. */
+#define PPI_CHEN_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHEN_CH4_Msk (0x1UL << PPI_CHEN_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHEN_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH4_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 3 : Enable PPI channel 3. */
+#define PPI_CHEN_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHEN_CH3_Msk (0x1UL << PPI_CHEN_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHEN_CH3_Disabled (0UL) /*!< Channel disabled */
+#define PPI_CHEN_CH3_Enabled (1UL) /*!< Channel enabled */
+
+/* Bit 2 : Enable PPI channel 2. */
+#define PPI_CHEN_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHEN_CH2_Msk (0x1UL << PPI_CHEN_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHEN_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH2_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 1 : Enable PPI channel 1. */
+#define PPI_CHEN_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHEN_CH1_Msk (0x1UL << PPI_CHEN_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHEN_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH1_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 0 : Enable PPI channel 0. */
+#define PPI_CHEN_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHEN_CH0_Msk (0x1UL << PPI_CHEN_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHEN_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH0_Enabled (1UL) /*!< Channel enabled. */
+
+/* Register: PPI_CHENSET */
+/* Description: Channel enable set. */
+
+/* Bit 31 : Enable PPI channel 31. */
+#define PPI_CHENSET_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHENSET_CH31_Msk (0x1UL << PPI_CHENSET_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHENSET_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH31_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH31_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 30 : Enable PPI channel 30. */
+#define PPI_CHENSET_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHENSET_CH30_Msk (0x1UL << PPI_CHENSET_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHENSET_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH30_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH30_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 29 : Enable PPI channel 29. */
+#define PPI_CHENSET_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHENSET_CH29_Msk (0x1UL << PPI_CHENSET_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHENSET_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH29_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH29_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 28 : Enable PPI channel 28. */
+#define PPI_CHENSET_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHENSET_CH28_Msk (0x1UL << PPI_CHENSET_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHENSET_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH28_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH28_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 27 : Enable PPI channel 27. */
+#define PPI_CHENSET_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHENSET_CH27_Msk (0x1UL << PPI_CHENSET_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHENSET_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH27_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH27_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 26 : Enable PPI channel 26. */
+#define PPI_CHENSET_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHENSET_CH26_Msk (0x1UL << PPI_CHENSET_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHENSET_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH26_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH26_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 25 : Enable PPI channel 25. */
+#define PPI_CHENSET_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHENSET_CH25_Msk (0x1UL << PPI_CHENSET_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHENSET_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH25_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH25_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 24 : Enable PPI channel 24. */
+#define PPI_CHENSET_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHENSET_CH24_Msk (0x1UL << PPI_CHENSET_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHENSET_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH24_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH24_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 23 : Enable PPI channel 23. */
+#define PPI_CHENSET_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHENSET_CH23_Msk (0x1UL << PPI_CHENSET_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHENSET_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH23_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH23_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 22 : Enable PPI channel 22. */
+#define PPI_CHENSET_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHENSET_CH22_Msk (0x1UL << PPI_CHENSET_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHENSET_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH22_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH22_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 21 : Enable PPI channel 21. */
+#define PPI_CHENSET_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHENSET_CH21_Msk (0x1UL << PPI_CHENSET_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHENSET_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH21_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH21_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 20 : Enable PPI channel 20. */
+#define PPI_CHENSET_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHENSET_CH20_Msk (0x1UL << PPI_CHENSET_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHENSET_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH20_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH20_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 15 : Enable PPI channel 15. */
+#define PPI_CHENSET_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHENSET_CH15_Msk (0x1UL << PPI_CHENSET_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHENSET_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH15_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH15_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 14 : Enable PPI channel 14. */
+#define PPI_CHENSET_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHENSET_CH14_Msk (0x1UL << PPI_CHENSET_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHENSET_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH14_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH14_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 13 : Enable PPI channel 13. */
+#define PPI_CHENSET_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHENSET_CH13_Msk (0x1UL << PPI_CHENSET_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHENSET_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH13_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH13_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 12 : Enable PPI channel 12. */
+#define PPI_CHENSET_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHENSET_CH12_Msk (0x1UL << PPI_CHENSET_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHENSET_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH12_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH12_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 11 : Enable PPI channel 11. */
+#define PPI_CHENSET_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHENSET_CH11_Msk (0x1UL << PPI_CHENSET_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHENSET_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH11_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH11_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 10 : Enable PPI channel 10. */
+#define PPI_CHENSET_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHENSET_CH10_Msk (0x1UL << PPI_CHENSET_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHENSET_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH10_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH10_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 9 : Enable PPI channel 9. */
+#define PPI_CHENSET_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHENSET_CH9_Msk (0x1UL << PPI_CHENSET_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHENSET_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH9_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH9_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 8 : Enable PPI channel 8. */
+#define PPI_CHENSET_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHENSET_CH8_Msk (0x1UL << PPI_CHENSET_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHENSET_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH8_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH8_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 7 : Enable PPI channel 7. */
+#define PPI_CHENSET_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHENSET_CH7_Msk (0x1UL << PPI_CHENSET_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHENSET_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH7_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH7_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 6 : Enable PPI channel 6. */
+#define PPI_CHENSET_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHENSET_CH6_Msk (0x1UL << PPI_CHENSET_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHENSET_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH6_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH6_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 5 : Enable PPI channel 5. */
+#define PPI_CHENSET_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHENSET_CH5_Msk (0x1UL << PPI_CHENSET_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHENSET_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH5_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH5_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 4 : Enable PPI channel 4. */
+#define PPI_CHENSET_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHENSET_CH4_Msk (0x1UL << PPI_CHENSET_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHENSET_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH4_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH4_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 3 : Enable PPI channel 3. */
+#define PPI_CHENSET_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHENSET_CH3_Msk (0x1UL << PPI_CHENSET_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHENSET_CH3_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH3_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH3_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 2 : Enable PPI channel 2. */
+#define PPI_CHENSET_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHENSET_CH2_Msk (0x1UL << PPI_CHENSET_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHENSET_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH2_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH2_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 1 : Enable PPI channel 1. */
+#define PPI_CHENSET_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHENSET_CH1_Msk (0x1UL << PPI_CHENSET_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHENSET_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH1_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH1_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 0 : Enable PPI channel 0. */
+#define PPI_CHENSET_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHENSET_CH0_Msk (0x1UL << PPI_CHENSET_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHENSET_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH0_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH0_Set (1UL) /*!< Enable channel on write. */
+
+/* Register: PPI_CHENCLR */
+/* Description: Channel enable clear. */
+
+/* Bit 31 : Disable PPI channel 31. */
+#define PPI_CHENCLR_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHENCLR_CH31_Msk (0x1UL << PPI_CHENCLR_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHENCLR_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH31_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH31_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 30 : Disable PPI channel 30. */
+#define PPI_CHENCLR_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHENCLR_CH30_Msk (0x1UL << PPI_CHENCLR_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHENCLR_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH30_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH30_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 29 : Disable PPI channel 29. */
+#define PPI_CHENCLR_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHENCLR_CH29_Msk (0x1UL << PPI_CHENCLR_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHENCLR_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH29_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH29_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 28 : Disable PPI channel 28. */
+#define PPI_CHENCLR_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHENCLR_CH28_Msk (0x1UL << PPI_CHENCLR_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHENCLR_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH28_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH28_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 27 : Disable PPI channel 27. */
+#define PPI_CHENCLR_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHENCLR_CH27_Msk (0x1UL << PPI_CHENCLR_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHENCLR_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH27_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH27_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 26 : Disable PPI channel 26. */
+#define PPI_CHENCLR_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHENCLR_CH26_Msk (0x1UL << PPI_CHENCLR_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHENCLR_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH26_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH26_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 25 : Disable PPI channel 25. */
+#define PPI_CHENCLR_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHENCLR_CH25_Msk (0x1UL << PPI_CHENCLR_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHENCLR_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH25_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH25_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 24 : Disable PPI channel 24. */
+#define PPI_CHENCLR_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHENCLR_CH24_Msk (0x1UL << PPI_CHENCLR_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHENCLR_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH24_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH24_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 23 : Disable PPI channel 23. */
+#define PPI_CHENCLR_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHENCLR_CH23_Msk (0x1UL << PPI_CHENCLR_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHENCLR_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH23_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH23_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 22 : Disable PPI channel 22. */
+#define PPI_CHENCLR_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHENCLR_CH22_Msk (0x1UL << PPI_CHENCLR_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHENCLR_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH22_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH22_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 21 : Disable PPI channel 21. */
+#define PPI_CHENCLR_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHENCLR_CH21_Msk (0x1UL << PPI_CHENCLR_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHENCLR_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH21_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH21_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 20 : Disable PPI channel 20. */
+#define PPI_CHENCLR_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHENCLR_CH20_Msk (0x1UL << PPI_CHENCLR_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHENCLR_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH20_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH20_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 15 : Disable PPI channel 15. */
+#define PPI_CHENCLR_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHENCLR_CH15_Msk (0x1UL << PPI_CHENCLR_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHENCLR_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH15_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH15_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 14 : Disable PPI channel 14. */
+#define PPI_CHENCLR_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHENCLR_CH14_Msk (0x1UL << PPI_CHENCLR_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHENCLR_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH14_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH14_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 13 : Disable PPI channel 13. */
+#define PPI_CHENCLR_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHENCLR_CH13_Msk (0x1UL << PPI_CHENCLR_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHENCLR_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH13_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH13_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 12 : Disable PPI channel 12. */
+#define PPI_CHENCLR_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHENCLR_CH12_Msk (0x1UL << PPI_CHENCLR_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHENCLR_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH12_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH12_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 11 : Disable PPI channel 11. */
+#define PPI_CHENCLR_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHENCLR_CH11_Msk (0x1UL << PPI_CHENCLR_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHENCLR_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH11_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH11_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 10 : Disable PPI channel 10. */
+#define PPI_CHENCLR_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHENCLR_CH10_Msk (0x1UL << PPI_CHENCLR_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHENCLR_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH10_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH10_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 9 : Disable PPI channel 9. */
+#define PPI_CHENCLR_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHENCLR_CH9_Msk (0x1UL << PPI_CHENCLR_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHENCLR_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH9_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH9_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 8 : Disable PPI channel 8. */
+#define PPI_CHENCLR_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHENCLR_CH8_Msk (0x1UL << PPI_CHENCLR_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHENCLR_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH8_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH8_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 7 : Disable PPI channel 7. */
+#define PPI_CHENCLR_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHENCLR_CH7_Msk (0x1UL << PPI_CHENCLR_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHENCLR_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH7_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH7_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 6 : Disable PPI channel 6. */
+#define PPI_CHENCLR_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHENCLR_CH6_Msk (0x1UL << PPI_CHENCLR_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHENCLR_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH6_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH6_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 5 : Disable PPI channel 5. */
+#define PPI_CHENCLR_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHENCLR_CH5_Msk (0x1UL << PPI_CHENCLR_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHENCLR_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH5_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH5_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 4 : Disable PPI channel 4. */
+#define PPI_CHENCLR_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHENCLR_CH4_Msk (0x1UL << PPI_CHENCLR_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHENCLR_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH4_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH4_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 3 : Disable PPI channel 3. */
+#define PPI_CHENCLR_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHENCLR_CH3_Msk (0x1UL << PPI_CHENCLR_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHENCLR_CH3_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH3_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH3_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 2 : Disable PPI channel 2. */
+#define PPI_CHENCLR_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHENCLR_CH2_Msk (0x1UL << PPI_CHENCLR_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHENCLR_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH2_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH2_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 1 : Disable PPI channel 1. */
+#define PPI_CHENCLR_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHENCLR_CH1_Msk (0x1UL << PPI_CHENCLR_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHENCLR_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH1_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH1_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 0 : Disable PPI channel 0. */
+#define PPI_CHENCLR_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHENCLR_CH0_Msk (0x1UL << PPI_CHENCLR_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHENCLR_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH0_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH0_Clear (1UL) /*!< Disable channel on write. */
+
+/* Register: PPI_CHG */
+/* Description: Channel group configuration. */
+
+/* Bit 31 : Include CH31 in channel group. */
+#define PPI_CHG_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHG_CH31_Msk (0x1UL << PPI_CHG_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHG_CH31_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH31_Included (1UL) /*!< Channel included. */
+
+/* Bit 30 : Include CH30 in channel group. */
+#define PPI_CHG_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHG_CH30_Msk (0x1UL << PPI_CHG_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHG_CH30_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH30_Included (1UL) /*!< Channel included. */
+
+/* Bit 29 : Include CH29 in channel group. */
+#define PPI_CHG_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHG_CH29_Msk (0x1UL << PPI_CHG_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHG_CH29_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH29_Included (1UL) /*!< Channel included. */
+
+/* Bit 28 : Include CH28 in channel group. */
+#define PPI_CHG_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHG_CH28_Msk (0x1UL << PPI_CHG_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHG_CH28_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH28_Included (1UL) /*!< Channel included. */
+
+/* Bit 27 : Include CH27 in channel group. */
+#define PPI_CHG_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHG_CH27_Msk (0x1UL << PPI_CHG_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHG_CH27_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH27_Included (1UL) /*!< Channel included. */
+
+/* Bit 26 : Include CH26 in channel group. */
+#define PPI_CHG_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHG_CH26_Msk (0x1UL << PPI_CHG_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHG_CH26_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH26_Included (1UL) /*!< Channel included. */
+
+/* Bit 25 : Include CH25 in channel group. */
+#define PPI_CHG_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHG_CH25_Msk (0x1UL << PPI_CHG_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHG_CH25_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH25_Included (1UL) /*!< Channel included. */
+
+/* Bit 24 : Include CH24 in channel group. */
+#define PPI_CHG_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHG_CH24_Msk (0x1UL << PPI_CHG_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHG_CH24_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH24_Included (1UL) /*!< Channel included. */
+
+/* Bit 23 : Include CH23 in channel group. */
+#define PPI_CHG_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHG_CH23_Msk (0x1UL << PPI_CHG_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHG_CH23_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH23_Included (1UL) /*!< Channel included. */
+
+/* Bit 22 : Include CH22 in channel group. */
+#define PPI_CHG_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHG_CH22_Msk (0x1UL << PPI_CHG_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHG_CH22_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH22_Included (1UL) /*!< Channel included. */
+
+/* Bit 21 : Include CH21 in channel group. */
+#define PPI_CHG_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHG_CH21_Msk (0x1UL << PPI_CHG_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHG_CH21_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH21_Included (1UL) /*!< Channel included. */
+
+/* Bit 20 : Include CH20 in channel group. */
+#define PPI_CHG_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHG_CH20_Msk (0x1UL << PPI_CHG_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHG_CH20_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH20_Included (1UL) /*!< Channel included. */
+
+/* Bit 15 : Include CH15 in channel group. */
+#define PPI_CHG_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHG_CH15_Msk (0x1UL << PPI_CHG_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHG_CH15_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH15_Included (1UL) /*!< Channel included. */
+
+/* Bit 14 : Include CH14 in channel group. */
+#define PPI_CHG_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHG_CH14_Msk (0x1UL << PPI_CHG_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHG_CH14_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH14_Included (1UL) /*!< Channel included. */
+
+/* Bit 13 : Include CH13 in channel group. */
+#define PPI_CHG_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHG_CH13_Msk (0x1UL << PPI_CHG_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHG_CH13_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH13_Included (1UL) /*!< Channel included. */
+
+/* Bit 12 : Include CH12 in channel group. */
+#define PPI_CHG_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHG_CH12_Msk (0x1UL << PPI_CHG_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHG_CH12_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH12_Included (1UL) /*!< Channel included. */
+
+/* Bit 11 : Include CH11 in channel group. */
+#define PPI_CHG_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHG_CH11_Msk (0x1UL << PPI_CHG_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHG_CH11_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH11_Included (1UL) /*!< Channel included. */
+
+/* Bit 10 : Include CH10 in channel group. */
+#define PPI_CHG_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHG_CH10_Msk (0x1UL << PPI_CHG_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHG_CH10_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH10_Included (1UL) /*!< Channel included. */
+
+/* Bit 9 : Include CH9 in channel group. */
+#define PPI_CHG_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHG_CH9_Msk (0x1UL << PPI_CHG_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHG_CH9_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH9_Included (1UL) /*!< Channel included. */
+
+/* Bit 8 : Include CH8 in channel group. */
+#define PPI_CHG_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHG_CH8_Msk (0x1UL << PPI_CHG_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHG_CH8_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH8_Included (1UL) /*!< Channel included. */
+
+/* Bit 7 : Include CH7 in channel group. */
+#define PPI_CHG_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHG_CH7_Msk (0x1UL << PPI_CHG_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHG_CH7_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH7_Included (1UL) /*!< Channel included. */
+
+/* Bit 6 : Include CH6 in channel group. */
+#define PPI_CHG_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHG_CH6_Msk (0x1UL << PPI_CHG_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHG_CH6_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH6_Included (1UL) /*!< Channel included. */
+
+/* Bit 5 : Include CH5 in channel group. */
+#define PPI_CHG_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHG_CH5_Msk (0x1UL << PPI_CHG_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHG_CH5_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH5_Included (1UL) /*!< Channel included. */
+
+/* Bit 4 : Include CH4 in channel group. */
+#define PPI_CHG_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHG_CH4_Msk (0x1UL << PPI_CHG_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHG_CH4_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH4_Included (1UL) /*!< Channel included. */
+
+/* Bit 3 : Include CH3 in channel group. */
+#define PPI_CHG_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHG_CH3_Msk (0x1UL << PPI_CHG_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHG_CH3_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH3_Included (1UL) /*!< Channel included. */
+
+/* Bit 2 : Include CH2 in channel group. */
+#define PPI_CHG_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHG_CH2_Msk (0x1UL << PPI_CHG_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHG_CH2_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH2_Included (1UL) /*!< Channel included. */
+
+/* Bit 1 : Include CH1 in channel group. */
+#define PPI_CHG_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHG_CH1_Msk (0x1UL << PPI_CHG_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHG_CH1_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH1_Included (1UL) /*!< Channel included. */
+
+/* Bit 0 : Include CH0 in channel group. */
+#define PPI_CHG_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHG_CH0_Msk (0x1UL << PPI_CHG_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHG_CH0_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH0_Included (1UL) /*!< Channel included. */
+
+
+/* Peripheral: PU */
+/* Description: Patch unit. */
+
+/* Register: PU_PATCHADDR */
+/* Description: Relative address of patch instructions. */
+
+/* Bits 24..0 : Relative address of patch instructions. */
+#define PU_PATCHADDR_PATCHADDR_Pos (0UL) /*!< Position of PATCHADDR field. */
+#define PU_PATCHADDR_PATCHADDR_Msk (0x1FFFFFFUL << PU_PATCHADDR_PATCHADDR_Pos) /*!< Bit mask of PATCHADDR field. */
+
+/* Register: PU_PATCHEN */
+/* Description: Patch enable register. */
+
+/* Bit 7 : Patch 7 enabled. */
+#define PU_PATCHEN_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
+#define PU_PATCHEN_PATCH7_Msk (0x1UL << PU_PATCHEN_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
+#define PU_PATCHEN_PATCH7_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH7_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 6 : Patch 6 enabled. */
+#define PU_PATCHEN_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
+#define PU_PATCHEN_PATCH6_Msk (0x1UL << PU_PATCHEN_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
+#define PU_PATCHEN_PATCH6_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH6_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 5 : Patch 5 enabled. */
+#define PU_PATCHEN_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
+#define PU_PATCHEN_PATCH5_Msk (0x1UL << PU_PATCHEN_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
+#define PU_PATCHEN_PATCH5_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH5_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 4 : Patch 4 enabled. */
+#define PU_PATCHEN_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
+#define PU_PATCHEN_PATCH4_Msk (0x1UL << PU_PATCHEN_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
+#define PU_PATCHEN_PATCH4_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH4_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 3 : Patch 3 enabled. */
+#define PU_PATCHEN_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
+#define PU_PATCHEN_PATCH3_Msk (0x1UL << PU_PATCHEN_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
+#define PU_PATCHEN_PATCH3_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH3_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 2 : Patch 2 enabled. */
+#define PU_PATCHEN_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
+#define PU_PATCHEN_PATCH2_Msk (0x1UL << PU_PATCHEN_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
+#define PU_PATCHEN_PATCH2_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH2_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 1 : Patch 1 enabled. */
+#define PU_PATCHEN_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
+#define PU_PATCHEN_PATCH1_Msk (0x1UL << PU_PATCHEN_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
+#define PU_PATCHEN_PATCH1_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH1_Enabled (1UL) /*!< Patch enabled. */
+
+/* Bit 0 : Patch 0 enabled. */
+#define PU_PATCHEN_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
+#define PU_PATCHEN_PATCH0_Msk (0x1UL << PU_PATCHEN_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
+#define PU_PATCHEN_PATCH0_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHEN_PATCH0_Enabled (1UL) /*!< Patch enabled. */
+
+/* Register: PU_PATCHENSET */
+/* Description: Patch enable register. */
+
+/* Bit 7 : Patch 7 enabled. */
+#define PU_PATCHENSET_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
+#define PU_PATCHENSET_PATCH7_Msk (0x1UL << PU_PATCHENSET_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
+#define PU_PATCHENSET_PATCH7_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH7_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH7_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 6 : Patch 6 enabled. */
+#define PU_PATCHENSET_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
+#define PU_PATCHENSET_PATCH6_Msk (0x1UL << PU_PATCHENSET_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
+#define PU_PATCHENSET_PATCH6_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH6_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH6_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 5 : Patch 5 enabled. */
+#define PU_PATCHENSET_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
+#define PU_PATCHENSET_PATCH5_Msk (0x1UL << PU_PATCHENSET_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
+#define PU_PATCHENSET_PATCH5_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH5_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH5_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 4 : Patch 4 enabled. */
+#define PU_PATCHENSET_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
+#define PU_PATCHENSET_PATCH4_Msk (0x1UL << PU_PATCHENSET_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
+#define PU_PATCHENSET_PATCH4_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH4_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH4_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 3 : Patch 3 enabled. */
+#define PU_PATCHENSET_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
+#define PU_PATCHENSET_PATCH3_Msk (0x1UL << PU_PATCHENSET_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
+#define PU_PATCHENSET_PATCH3_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH3_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH3_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 2 : Patch 2 enabled. */
+#define PU_PATCHENSET_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
+#define PU_PATCHENSET_PATCH2_Msk (0x1UL << PU_PATCHENSET_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
+#define PU_PATCHENSET_PATCH2_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH2_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH2_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 1 : Patch 1 enabled. */
+#define PU_PATCHENSET_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
+#define PU_PATCHENSET_PATCH1_Msk (0x1UL << PU_PATCHENSET_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
+#define PU_PATCHENSET_PATCH1_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH1_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH1_Set (1UL) /*!< Enable patch on write. */
+
+/* Bit 0 : Patch 0 enabled. */
+#define PU_PATCHENSET_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
+#define PU_PATCHENSET_PATCH0_Msk (0x1UL << PU_PATCHENSET_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
+#define PU_PATCHENSET_PATCH0_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENSET_PATCH0_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENSET_PATCH0_Set (1UL) /*!< Enable patch on write. */
+
+/* Register: PU_PATCHENCLR */
+/* Description: Patch disable register. */
+
+/* Bit 7 : Patch 7 enabled. */
+#define PU_PATCHENCLR_PATCH7_Pos (7UL) /*!< Position of PATCH7 field. */
+#define PU_PATCHENCLR_PATCH7_Msk (0x1UL << PU_PATCHENCLR_PATCH7_Pos) /*!< Bit mask of PATCH7 field. */
+#define PU_PATCHENCLR_PATCH7_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH7_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH7_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 6 : Patch 6 enabled. */
+#define PU_PATCHENCLR_PATCH6_Pos (6UL) /*!< Position of PATCH6 field. */
+#define PU_PATCHENCLR_PATCH6_Msk (0x1UL << PU_PATCHENCLR_PATCH6_Pos) /*!< Bit mask of PATCH6 field. */
+#define PU_PATCHENCLR_PATCH6_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH6_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH6_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 5 : Patch 5 enabled. */
+#define PU_PATCHENCLR_PATCH5_Pos (5UL) /*!< Position of PATCH5 field. */
+#define PU_PATCHENCLR_PATCH5_Msk (0x1UL << PU_PATCHENCLR_PATCH5_Pos) /*!< Bit mask of PATCH5 field. */
+#define PU_PATCHENCLR_PATCH5_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH5_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH5_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 4 : Patch 4 enabled. */
+#define PU_PATCHENCLR_PATCH4_Pos (4UL) /*!< Position of PATCH4 field. */
+#define PU_PATCHENCLR_PATCH4_Msk (0x1UL << PU_PATCHENCLR_PATCH4_Pos) /*!< Bit mask of PATCH4 field. */
+#define PU_PATCHENCLR_PATCH4_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH4_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH4_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 3 : Patch 3 enabled. */
+#define PU_PATCHENCLR_PATCH3_Pos (3UL) /*!< Position of PATCH3 field. */
+#define PU_PATCHENCLR_PATCH3_Msk (0x1UL << PU_PATCHENCLR_PATCH3_Pos) /*!< Bit mask of PATCH3 field. */
+#define PU_PATCHENCLR_PATCH3_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH3_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH3_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 2 : Patch 2 enabled. */
+#define PU_PATCHENCLR_PATCH2_Pos (2UL) /*!< Position of PATCH2 field. */
+#define PU_PATCHENCLR_PATCH2_Msk (0x1UL << PU_PATCHENCLR_PATCH2_Pos) /*!< Bit mask of PATCH2 field. */
+#define PU_PATCHENCLR_PATCH2_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH2_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH2_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 1 : Patch 1 enabled. */
+#define PU_PATCHENCLR_PATCH1_Pos (1UL) /*!< Position of PATCH1 field. */
+#define PU_PATCHENCLR_PATCH1_Msk (0x1UL << PU_PATCHENCLR_PATCH1_Pos) /*!< Bit mask of PATCH1 field. */
+#define PU_PATCHENCLR_PATCH1_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH1_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH1_Clear (1UL) /*!< Disable patch on write. */
+
+/* Bit 0 : Patch 0 enabled. */
+#define PU_PATCHENCLR_PATCH0_Pos (0UL) /*!< Position of PATCH0 field. */
+#define PU_PATCHENCLR_PATCH0_Msk (0x1UL << PU_PATCHENCLR_PATCH0_Pos) /*!< Bit mask of PATCH0 field. */
+#define PU_PATCHENCLR_PATCH0_Disabled (0UL) /*!< Patch disabled. */
+#define PU_PATCHENCLR_PATCH0_Enabled (1UL) /*!< Patch enabled. */
+#define PU_PATCHENCLR_PATCH0_Clear (1UL) /*!< Disable patch on write. */
+
+
+/* Peripheral: QDEC */
+/* Description: Rotary decoder. */
+
+/* Register: QDEC_SHORTS */
+/* Description: Shortcuts for the QDEC. */
+
+/* Bit 1 : Shortcut between SAMPLERDY event and STOP task. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Pos (1UL) /*!< Position of SAMPLERDY_STOP field. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_STOP_Pos) /*!< Bit mask of SAMPLERDY_STOP field. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between REPORTRDY event and READCLRACC task. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Pos (0UL) /*!< Position of REPORTRDY_READCLRACC field. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_READCLRACC_Pos) /*!< Bit mask of REPORTRDY_READCLRACC field. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Disabled (0UL) /*!< Shortcut disabled. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: QDEC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on ACCOF event. */
+#define QDEC_INTENSET_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */
+#define QDEC_INTENSET_ACCOF_Msk (0x1UL << QDEC_INTENSET_ACCOF_Pos) /*!< Bit mask of ACCOF field. */
+#define QDEC_INTENSET_ACCOF_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_ACCOF_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_ACCOF_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on REPORTRDY event. */
+#define QDEC_INTENSET_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */
+#define QDEC_INTENSET_REPORTRDY_Msk (0x1UL << QDEC_INTENSET_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */
+#define QDEC_INTENSET_REPORTRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_REPORTRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_REPORTRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on SAMPLERDY event. */
+#define QDEC_INTENSET_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */
+#define QDEC_INTENSET_SAMPLERDY_Msk (0x1UL << QDEC_INTENSET_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */
+#define QDEC_INTENSET_SAMPLERDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_SAMPLERDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_SAMPLERDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: QDEC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on ACCOF event. */
+#define QDEC_INTENCLR_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */
+#define QDEC_INTENCLR_ACCOF_Msk (0x1UL << QDEC_INTENCLR_ACCOF_Pos) /*!< Bit mask of ACCOF field. */
+#define QDEC_INTENCLR_ACCOF_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_ACCOF_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_ACCOF_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on REPORTRDY event. */
+#define QDEC_INTENCLR_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */
+#define QDEC_INTENCLR_REPORTRDY_Msk (0x1UL << QDEC_INTENCLR_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */
+#define QDEC_INTENCLR_REPORTRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_REPORTRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_REPORTRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on SAMPLERDY event. */
+#define QDEC_INTENCLR_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */
+#define QDEC_INTENCLR_SAMPLERDY_Msk (0x1UL << QDEC_INTENCLR_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */
+#define QDEC_INTENCLR_SAMPLERDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_SAMPLERDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_SAMPLERDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: QDEC_ENABLE */
+/* Description: Enable the QDEC. */
+
+/* Bit 0 : Enable or disable QDEC. */
+#define QDEC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define QDEC_ENABLE_ENABLE_Msk (0x1UL << QDEC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define QDEC_ENABLE_ENABLE_Disabled (0UL) /*!< Disabled QDEC. */
+#define QDEC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable QDEC. */
+
+/* Register: QDEC_LEDPOL */
+/* Description: LED output pin polarity. */
+
+/* Bit 0 : LED output pin polarity. */
+#define QDEC_LEDPOL_LEDPOL_Pos (0UL) /*!< Position of LEDPOL field. */
+#define QDEC_LEDPOL_LEDPOL_Msk (0x1UL << QDEC_LEDPOL_LEDPOL_Pos) /*!< Bit mask of LEDPOL field. */
+#define QDEC_LEDPOL_LEDPOL_ActiveLow (0UL) /*!< LED output is active low. */
+#define QDEC_LEDPOL_LEDPOL_ActiveHigh (1UL) /*!< LED output is active high. */
+
+/* Register: QDEC_SAMPLEPER */
+/* Description: Sample period. */
+
+/* Bits 2..0 : Sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_Pos (0UL) /*!< Position of SAMPLEPER field. */
+#define QDEC_SAMPLEPER_SAMPLEPER_Msk (0x7UL << QDEC_SAMPLEPER_SAMPLEPER_Pos) /*!< Bit mask of SAMPLEPER field. */
+#define QDEC_SAMPLEPER_SAMPLEPER_128us (0x00UL) /*!< 128us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_256us (0x01UL) /*!< 256us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_512us (0x02UL) /*!< 512us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_1024us (0x03UL) /*!< 1024us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_2048us (0x04UL) /*!< 2048us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_4096us (0x05UL) /*!< 4096us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_8192us (0x06UL) /*!< 8192us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_16384us (0x07UL) /*!< 16384us sample period. */
+
+/* Register: QDEC_SAMPLE */
+/* Description: Motion sample value. */
+
+/* Bits 31..0 : Last sample taken in compliment to 2. */
+#define QDEC_SAMPLE_SAMPLE_Pos (0UL) /*!< Position of SAMPLE field. */
+#define QDEC_SAMPLE_SAMPLE_Msk (0xFFFFFFFFUL << QDEC_SAMPLE_SAMPLE_Pos) /*!< Bit mask of SAMPLE field. */
+
+/* Register: QDEC_REPORTPER */
+/* Description: Number of samples to generate an EVENT_REPORTRDY. */
+
+/* Bits 2..0 : Number of samples to generate an EVENT_REPORTRDY. */
+#define QDEC_REPORTPER_REPORTPER_Pos (0UL) /*!< Position of REPORTPER field. */
+#define QDEC_REPORTPER_REPORTPER_Msk (0x7UL << QDEC_REPORTPER_REPORTPER_Pos) /*!< Bit mask of REPORTPER field. */
+#define QDEC_REPORTPER_REPORTPER_10Smpl (0x00UL) /*!< 10 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_40Smpl (0x01UL) /*!< 40 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_80Smpl (0x02UL) /*!< 80 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_120Smpl (0x03UL) /*!< 120 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_160Smpl (0x04UL) /*!< 160 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_200Smpl (0x05UL) /*!< 200 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_240Smpl (0x06UL) /*!< 240 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_280Smpl (0x07UL) /*!< 280 samples per report. */
+
+/* Register: QDEC_DBFEN */
+/* Description: Enable debouncer input filters. */
+
+/* Bit 0 : Enable debounce input filters. */
+#define QDEC_DBFEN_DBFEN_Pos (0UL) /*!< Position of DBFEN field. */
+#define QDEC_DBFEN_DBFEN_Msk (0x1UL << QDEC_DBFEN_DBFEN_Pos) /*!< Bit mask of DBFEN field. */
+#define QDEC_DBFEN_DBFEN_Disabled (0UL) /*!< Debounce input filters disabled. */
+#define QDEC_DBFEN_DBFEN_Enabled (1UL) /*!< Debounce input filters enabled. */
+
+/* Register: QDEC_LEDPRE */
+/* Description: Time LED is switched ON before the sample. */
+
+/* Bits 8..0 : Period in us the LED in switched on prior to sampling. */
+#define QDEC_LEDPRE_LEDPRE_Pos (0UL) /*!< Position of LEDPRE field. */
+#define QDEC_LEDPRE_LEDPRE_Msk (0x1FFUL << QDEC_LEDPRE_LEDPRE_Pos) /*!< Bit mask of LEDPRE field. */
+
+/* Register: QDEC_ACCDBL */
+/* Description: Accumulated double (error) transitions register. */
+
+/* Bits 3..0 : Accumulated double (error) transitions. */
+#define QDEC_ACCDBL_ACCDBL_Pos (0UL) /*!< Position of ACCDBL field. */
+#define QDEC_ACCDBL_ACCDBL_Msk (0xFUL << QDEC_ACCDBL_ACCDBL_Pos) /*!< Bit mask of ACCDBL field. */
+
+/* Register: QDEC_ACCDBLREAD */
+/* Description: Snapshot of ACCDBL register. Value generated by the TASKS_READCLEACC task. */
+
+/* Bits 3..0 : Snapshot of accumulated double (error) transitions. */
+#define QDEC_ACCDBLREAD_ACCDBLREAD_Pos (0UL) /*!< Position of ACCDBLREAD field. */
+#define QDEC_ACCDBLREAD_ACCDBLREAD_Msk (0xFUL << QDEC_ACCDBLREAD_ACCDBLREAD_Pos) /*!< Bit mask of ACCDBLREAD field. */
+
+/* Register: QDEC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define QDEC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define QDEC_POWER_POWER_Msk (0x1UL << QDEC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define QDEC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define QDEC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RADIO */
+/* Description: The radio. */
+
+/* Register: RADIO_SHORTS */
+/* Description: Shortcuts for the radio. */
+
+/* Bit 8 : Shortcut between DISABLED event and RSSISTOP task. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Pos (8UL) /*!< Position of DISABLED_RSSISTOP field. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Msk (0x1UL << RADIO_SHORTS_DISABLED_RSSISTOP_Pos) /*!< Bit mask of DISABLED_RSSISTOP field. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 6 : Shortcut between ADDRESS event and BCSTART task. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Pos (6UL) /*!< Position of ADDRESS_BCSTART field. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_BCSTART_Pos) /*!< Bit mask of ADDRESS_BCSTART field. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 5 : Shortcut between END event and START task. */
+#define RADIO_SHORTS_END_START_Pos (5UL) /*!< Position of END_START field. */
+#define RADIO_SHORTS_END_START_Msk (0x1UL << RADIO_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */
+#define RADIO_SHORTS_END_START_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_END_START_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 4 : Shortcut between ADDRESS event and RSSISTART task. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Pos (4UL) /*!< Position of ADDRESS_RSSISTART field. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_RSSISTART_Pos) /*!< Bit mask of ADDRESS_RSSISTART field. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between DISABLED event and RXEN task. */
+#define RADIO_SHORTS_DISABLED_RXEN_Pos (3UL) /*!< Position of DISABLED_RXEN field. */
+#define RADIO_SHORTS_DISABLED_RXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_RXEN_Pos) /*!< Bit mask of DISABLED_RXEN field. */
+#define RADIO_SHORTS_DISABLED_RXEN_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_RXEN_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between DISABLED event and TXEN task.  */
+#define RADIO_SHORTS_DISABLED_TXEN_Pos (2UL) /*!< Position of DISABLED_TXEN field. */
+#define RADIO_SHORTS_DISABLED_TXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_TXEN_Pos) /*!< Bit mask of DISABLED_TXEN field. */
+#define RADIO_SHORTS_DISABLED_TXEN_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_TXEN_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between END event and DISABLE task. */
+#define RADIO_SHORTS_END_DISABLE_Pos (1UL) /*!< Position of END_DISABLE field. */
+#define RADIO_SHORTS_END_DISABLE_Msk (0x1UL << RADIO_SHORTS_END_DISABLE_Pos) /*!< Bit mask of END_DISABLE field. */
+#define RADIO_SHORTS_END_DISABLE_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_END_DISABLE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between READY event and START task. */
+#define RADIO_SHORTS_READY_START_Pos (0UL) /*!< Position of READY_START field. */
+#define RADIO_SHORTS_READY_START_Msk (0x1UL << RADIO_SHORTS_READY_START_Pos) /*!< Bit mask of READY_START field. */
+#define RADIO_SHORTS_READY_START_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_READY_START_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: RADIO_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 10 : Enable interrupt on BCMATCH event. */
+#define RADIO_INTENSET_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */
+#define RADIO_INTENSET_BCMATCH_Msk (0x1UL << RADIO_INTENSET_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */
+#define RADIO_INTENSET_BCMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_BCMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_BCMATCH_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on RSSIEND event. */
+#define RADIO_INTENSET_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */
+#define RADIO_INTENSET_RSSIEND_Msk (0x1UL << RADIO_INTENSET_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */
+#define RADIO_INTENSET_RSSIEND_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_RSSIEND_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_RSSIEND_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 6 : Enable interrupt on DEVMISS event. */
+#define RADIO_INTENSET_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */
+#define RADIO_INTENSET_DEVMISS_Msk (0x1UL << RADIO_INTENSET_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */
+#define RADIO_INTENSET_DEVMISS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DEVMISS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DEVMISS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 5 : Enable interrupt on DEVMATCH event. */
+#define RADIO_INTENSET_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */
+#define RADIO_INTENSET_DEVMATCH_Msk (0x1UL << RADIO_INTENSET_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */
+#define RADIO_INTENSET_DEVMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DEVMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DEVMATCH_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 4 : Enable interrupt on DISABLED event. */
+#define RADIO_INTENSET_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */
+#define RADIO_INTENSET_DISABLED_Msk (0x1UL << RADIO_INTENSET_DISABLED_Pos) /*!< Bit mask of DISABLED field. */
+#define RADIO_INTENSET_DISABLED_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DISABLED_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DISABLED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on END event. */
+#define RADIO_INTENSET_END_Pos (3UL) /*!< Position of END field. */
+#define RADIO_INTENSET_END_Msk (0x1UL << RADIO_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define RADIO_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on PAYLOAD event. */
+#define RADIO_INTENSET_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */
+#define RADIO_INTENSET_PAYLOAD_Msk (0x1UL << RADIO_INTENSET_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */
+#define RADIO_INTENSET_PAYLOAD_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_PAYLOAD_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_PAYLOAD_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on ADDRESS event. */
+#define RADIO_INTENSET_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */
+#define RADIO_INTENSET_ADDRESS_Msk (0x1UL << RADIO_INTENSET_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+#define RADIO_INTENSET_ADDRESS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_ADDRESS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_ADDRESS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on READY event. */
+#define RADIO_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */
+#define RADIO_INTENSET_READY_Msk (0x1UL << RADIO_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define RADIO_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RADIO_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 10 : Disable interrupt on BCMATCH event. */
+#define RADIO_INTENCLR_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */
+#define RADIO_INTENCLR_BCMATCH_Msk (0x1UL << RADIO_INTENCLR_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */
+#define RADIO_INTENCLR_BCMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_BCMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_BCMATCH_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on RSSIEND event. */
+#define RADIO_INTENCLR_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */
+#define RADIO_INTENCLR_RSSIEND_Msk (0x1UL << RADIO_INTENCLR_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */
+#define RADIO_INTENCLR_RSSIEND_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_RSSIEND_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_RSSIEND_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 6 : Disable interrupt on DEVMISS event. */
+#define RADIO_INTENCLR_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */
+#define RADIO_INTENCLR_DEVMISS_Msk (0x1UL << RADIO_INTENCLR_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */
+#define RADIO_INTENCLR_DEVMISS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DEVMISS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DEVMISS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 5 : Disable interrupt on DEVMATCH event. */
+#define RADIO_INTENCLR_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */
+#define RADIO_INTENCLR_DEVMATCH_Msk (0x1UL << RADIO_INTENCLR_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */
+#define RADIO_INTENCLR_DEVMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DEVMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DEVMATCH_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 4 : Disable interrupt on DISABLED event. */
+#define RADIO_INTENCLR_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */
+#define RADIO_INTENCLR_DISABLED_Msk (0x1UL << RADIO_INTENCLR_DISABLED_Pos) /*!< Bit mask of DISABLED field. */
+#define RADIO_INTENCLR_DISABLED_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DISABLED_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DISABLED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on END event. */
+#define RADIO_INTENCLR_END_Pos (3UL) /*!< Position of END field. */
+#define RADIO_INTENCLR_END_Msk (0x1UL << RADIO_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define RADIO_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on PAYLOAD event. */
+#define RADIO_INTENCLR_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */
+#define RADIO_INTENCLR_PAYLOAD_Msk (0x1UL << RADIO_INTENCLR_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */
+#define RADIO_INTENCLR_PAYLOAD_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_PAYLOAD_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_PAYLOAD_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on ADDRESS event. */
+#define RADIO_INTENCLR_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */
+#define RADIO_INTENCLR_ADDRESS_Msk (0x1UL << RADIO_INTENCLR_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+#define RADIO_INTENCLR_ADDRESS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_ADDRESS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_ADDRESS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on READY event. */
+#define RADIO_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */
+#define RADIO_INTENCLR_READY_Msk (0x1UL << RADIO_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define RADIO_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RADIO_CRCSTATUS */
+/* Description: CRC status of received packet. */
+
+/* Bit 0 : CRC status of received packet. */
+#define RADIO_CRCSTATUS_CRCSTATUS_Pos (0UL) /*!< Position of CRCSTATUS field. */
+#define RADIO_CRCSTATUS_CRCSTATUS_Msk (0x1UL << RADIO_CRCSTATUS_CRCSTATUS_Pos) /*!< Bit mask of CRCSTATUS field. */
+#define RADIO_CRCSTATUS_CRCSTATUS_CRCError (0UL) /*!< Packet received with CRC error. */
+#define RADIO_CRCSTATUS_CRCSTATUS_CRCOk (1UL) /*!< Packet received with CRC ok. */
+
+/* Register: RADIO_CD */
+/* Description: Carrier detect. */
+
+/* Bit 0 : Carrier detect. */
+#define RADIO_CD_CD_Pos (0UL) /*!< Position of CD field. */
+#define RADIO_CD_CD_Msk (0x1UL << RADIO_CD_CD_Pos) /*!< Bit mask of CD field. */
+
+/* Register: RADIO_RXMATCH */
+/* Description: Received address. */
+
+/* Bits 2..0 : Logical address in which previous packet was received. */
+#define RADIO_RXMATCH_RXMATCH_Pos (0UL) /*!< Position of RXMATCH field. */
+#define RADIO_RXMATCH_RXMATCH_Msk (0x7UL << RADIO_RXMATCH_RXMATCH_Pos) /*!< Bit mask of RXMATCH field. */
+
+/* Register: RADIO_RXCRC */
+/* Description: Received CRC. */
+
+/* Bits 23..0 : CRC field of previously received packet. */
+#define RADIO_RXCRC_RXCRC_Pos (0UL) /*!< Position of RXCRC field. */
+#define RADIO_RXCRC_RXCRC_Msk (0xFFFFFFUL << RADIO_RXCRC_RXCRC_Pos) /*!< Bit mask of RXCRC field. */
+
+/* Register: RADIO_DAI */
+/* Description: Device address match index. */
+
+/* Bits 2..0 : Index (n) of device address (see DAB[n] and DAP[n]) that obtained an address match. */
+#define RADIO_DAI_DAI_Pos (0UL) /*!< Position of DAI field. */
+#define RADIO_DAI_DAI_Msk (0x7UL << RADIO_DAI_DAI_Pos) /*!< Bit mask of DAI field. */
+
+/* Register: RADIO_FREQUENCY */
+/* Description: Frequency. */
+
+/* Bits 6..0 : Radio channel frequency offset in MHz: RF Frequency = 2400 + FREQUENCY (MHz). Decision point: TXEN or RXEN task.  */
+#define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+
+/* Register: RADIO_TXPOWER */
+/* Description: Output power. */
+
+/* Bits 7..0 : Radio output power. Decision point: TXEN task. */
+#define RADIO_TXPOWER_TXPOWER_Pos (0UL) /*!< Position of TXPOWER field. */
+#define RADIO_TXPOWER_TXPOWER_Msk (0xFFUL << RADIO_TXPOWER_TXPOWER_Pos) /*!< Bit mask of TXPOWER field. */
+#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x04UL) /*!< +4dBm. */
+#define RADIO_TXPOWER_TXPOWER_0dBm (0x00UL) /*!< 0dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg30dBm (0xD8UL) /*!< -30dBm. */
+
+/* Register: RADIO_MODE */
+/* Description: Data rate and modulation. */
+
+/* Bits 1..0 : Radio data rate and modulation setting. Decision point: TXEN or RXEN task. */
+#define RADIO_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define RADIO_MODE_MODE_Msk (0x3UL << RADIO_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define RADIO_MODE_MODE_Nrf_1Mbit (0x00UL) /*!< 1Mbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Nrf_2Mbit (0x01UL) /*!< 2Mbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Nrf_250Kbit (0x02UL) /*!< 250kbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Ble_1Mbit (0x03UL) /*!< 1Mbit/s Bluetooth Low Energy */
+
+/* Register: RADIO_PCNF0 */
+/* Description: Packet configuration 0. */
+
+/* Bits 19..16 : Length of S1 field in number of bits. Decision point: START task. */
+#define RADIO_PCNF0_S1LEN_Pos (16UL) /*!< Position of S1LEN field. */
+#define RADIO_PCNF0_S1LEN_Msk (0xFUL << RADIO_PCNF0_S1LEN_Pos) /*!< Bit mask of S1LEN field. */
+
+/* Bit 8 : Length of S0 field in number of bytes. Decision point: START task. */
+#define RADIO_PCNF0_S0LEN_Pos (8UL) /*!< Position of S0LEN field. */
+#define RADIO_PCNF0_S0LEN_Msk (0x1UL << RADIO_PCNF0_S0LEN_Pos) /*!< Bit mask of S0LEN field. */
+
+/* Bits 3..0 : Length of length field in number of bits. Decision point: START task. */
+#define RADIO_PCNF0_LFLEN_Pos (0UL) /*!< Position of LFLEN field. */
+#define RADIO_PCNF0_LFLEN_Msk (0xFUL << RADIO_PCNF0_LFLEN_Pos) /*!< Bit mask of LFLEN field. */
+
+/* Register: RADIO_PCNF1 */
+/* Description: Packet configuration 1. */
+
+/* Bit 25 : Packet whitening enable. */
+#define RADIO_PCNF1_WHITEEN_Pos (25UL) /*!< Position of WHITEEN field. */
+#define RADIO_PCNF1_WHITEEN_Msk (0x1UL << RADIO_PCNF1_WHITEEN_Pos) /*!< Bit mask of WHITEEN field. */
+#define RADIO_PCNF1_WHITEEN_Disabled (0UL) /*!< Whitening disabled. */
+#define RADIO_PCNF1_WHITEEN_Enabled (1UL) /*!< Whitening enabled. */
+
+/* Bit 24 : On air endianness of packet length field. Decision point: START task. */
+#define RADIO_PCNF1_ENDIAN_Pos (24UL) /*!< Position of ENDIAN field. */
+#define RADIO_PCNF1_ENDIAN_Msk (0x1UL << RADIO_PCNF1_ENDIAN_Pos) /*!< Bit mask of ENDIAN field. */
+#define RADIO_PCNF1_ENDIAN_Little (0UL) /*!< Least significant bit on air first */
+#define RADIO_PCNF1_ENDIAN_Big (1UL) /*!< Most significant bit on air first */
+
+/* Bits 18..16 : Base address length in number of bytes. Decision point: START task. */
+#define RADIO_PCNF1_BALEN_Pos (16UL) /*!< Position of BALEN field. */
+#define RADIO_PCNF1_BALEN_Msk (0x7UL << RADIO_PCNF1_BALEN_Pos) /*!< Bit mask of BALEN field. */
+
+/* Bits 15..8 : Static length in number of bytes. Decision point: START task. */
+#define RADIO_PCNF1_STATLEN_Pos (8UL) /*!< Position of STATLEN field. */
+#define RADIO_PCNF1_STATLEN_Msk (0xFFUL << RADIO_PCNF1_STATLEN_Pos) /*!< Bit mask of STATLEN field. */
+
+/* Bits 7..0 : Maximum length of packet payload in number of bytes. */
+#define RADIO_PCNF1_MAXLEN_Pos (0UL) /*!< Position of MAXLEN field. */
+#define RADIO_PCNF1_MAXLEN_Msk (0xFFUL << RADIO_PCNF1_MAXLEN_Pos) /*!< Bit mask of MAXLEN field. */
+
+/* Register: RADIO_PREFIX0 */
+/* Description: Prefixes bytes for logical addresses 0 to 3. */
+
+/* Bits 31..24 : Address prefix 3. Decision point: START task. */
+#define RADIO_PREFIX0_AP3_Pos (24UL) /*!< Position of AP3 field. */
+#define RADIO_PREFIX0_AP3_Msk (0xFFUL << RADIO_PREFIX0_AP3_Pos) /*!< Bit mask of AP3 field. */
+
+/* Bits 23..16 : Address prefix 2. Decision point: START task. */
+#define RADIO_PREFIX0_AP2_Pos (16UL) /*!< Position of AP2 field. */
+#define RADIO_PREFIX0_AP2_Msk (0xFFUL << RADIO_PREFIX0_AP2_Pos) /*!< Bit mask of AP2 field. */
+
+/* Bits 15..8 : Address prefix 1. Decision point: START task. */
+#define RADIO_PREFIX0_AP1_Pos (8UL) /*!< Position of AP1 field. */
+#define RADIO_PREFIX0_AP1_Msk (0xFFUL << RADIO_PREFIX0_AP1_Pos) /*!< Bit mask of AP1 field. */
+
+/* Bits 7..0 : Address prefix 0. Decision point: START task. */
+#define RADIO_PREFIX0_AP0_Pos (0UL) /*!< Position of AP0 field. */
+#define RADIO_PREFIX0_AP0_Msk (0xFFUL << RADIO_PREFIX0_AP0_Pos) /*!< Bit mask of AP0 field. */
+
+/* Register: RADIO_PREFIX1 */
+/* Description: Prefixes bytes for logical addresses 4 to 7. */
+
+/* Bits 31..24 : Address prefix 7. Decision point: START task. */
+#define RADIO_PREFIX1_AP7_Pos (24UL) /*!< Position of AP7 field. */
+#define RADIO_PREFIX1_AP7_Msk (0xFFUL << RADIO_PREFIX1_AP7_Pos) /*!< Bit mask of AP7 field. */
+
+/* Bits 23..16 : Address prefix 6. Decision point: START task. */
+#define RADIO_PREFIX1_AP6_Pos (16UL) /*!< Position of AP6 field. */
+#define RADIO_PREFIX1_AP6_Msk (0xFFUL << RADIO_PREFIX1_AP6_Pos) /*!< Bit mask of AP6 field. */
+
+/* Bits 15..8 : Address prefix 5. Decision point: START task. */
+#define RADIO_PREFIX1_AP5_Pos (8UL) /*!< Position of AP5 field. */
+#define RADIO_PREFIX1_AP5_Msk (0xFFUL << RADIO_PREFIX1_AP5_Pos) /*!< Bit mask of AP5 field. */
+
+/* Bits 7..0 : Address prefix 4. Decision point: START task. */
+#define RADIO_PREFIX1_AP4_Pos (0UL) /*!< Position of AP4 field. */
+#define RADIO_PREFIX1_AP4_Msk (0xFFUL << RADIO_PREFIX1_AP4_Pos) /*!< Bit mask of AP4 field. */
+
+/* Register: RADIO_TXADDRESS */
+/* Description: Transmit address select. */
+
+/* Bits 2..0 : Logical address to be used when transmitting a packet. Decision point: START task. */
+#define RADIO_TXADDRESS_TXADDRESS_Pos (0UL) /*!< Position of TXADDRESS field. */
+#define RADIO_TXADDRESS_TXADDRESS_Msk (0x7UL << RADIO_TXADDRESS_TXADDRESS_Pos) /*!< Bit mask of TXADDRESS field. */
+
+/* Register: RADIO_RXADDRESSES */
+/* Description: Receive address select. */
+
+/* Bit 7 : Enable reception on logical address 7. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR7_Pos (7UL) /*!< Position of ADDR7 field. */
+#define RADIO_RXADDRESSES_ADDR7_Msk (0x1UL << RADIO_RXADDRESSES_ADDR7_Pos) /*!< Bit mask of ADDR7 field. */
+#define RADIO_RXADDRESSES_ADDR7_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR7_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 6 : Enable reception on logical address 6. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR6_Pos (6UL) /*!< Position of ADDR6 field. */
+#define RADIO_RXADDRESSES_ADDR6_Msk (0x1UL << RADIO_RXADDRESSES_ADDR6_Pos) /*!< Bit mask of ADDR6 field. */
+#define RADIO_RXADDRESSES_ADDR6_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR6_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 5 : Enable reception on logical address 5. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR5_Pos (5UL) /*!< Position of ADDR5 field. */
+#define RADIO_RXADDRESSES_ADDR5_Msk (0x1UL << RADIO_RXADDRESSES_ADDR5_Pos) /*!< Bit mask of ADDR5 field. */
+#define RADIO_RXADDRESSES_ADDR5_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR5_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 4 : Enable reception on logical address 4. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR4_Pos (4UL) /*!< Position of ADDR4 field. */
+#define RADIO_RXADDRESSES_ADDR4_Msk (0x1UL << RADIO_RXADDRESSES_ADDR4_Pos) /*!< Bit mask of ADDR4 field. */
+#define RADIO_RXADDRESSES_ADDR4_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR4_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 3 : Enable reception on logical address 3. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR3_Pos (3UL) /*!< Position of ADDR3 field. */
+#define RADIO_RXADDRESSES_ADDR3_Msk (0x1UL << RADIO_RXADDRESSES_ADDR3_Pos) /*!< Bit mask of ADDR3 field. */
+#define RADIO_RXADDRESSES_ADDR3_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR3_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 2 : Enable reception on logical address 2. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR2_Pos (2UL) /*!< Position of ADDR2 field. */
+#define RADIO_RXADDRESSES_ADDR2_Msk (0x1UL << RADIO_RXADDRESSES_ADDR2_Pos) /*!< Bit mask of ADDR2 field. */
+#define RADIO_RXADDRESSES_ADDR2_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR2_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 1 : Enable reception on logical address 1. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR1_Pos (1UL) /*!< Position of ADDR1 field. */
+#define RADIO_RXADDRESSES_ADDR1_Msk (0x1UL << RADIO_RXADDRESSES_ADDR1_Pos) /*!< Bit mask of ADDR1 field. */
+#define RADIO_RXADDRESSES_ADDR1_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR1_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 0 : Enable reception on logical address 0. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR0_Pos (0UL) /*!< Position of ADDR0 field. */
+#define RADIO_RXADDRESSES_ADDR0_Msk (0x1UL << RADIO_RXADDRESSES_ADDR0_Pos) /*!< Bit mask of ADDR0 field. */
+#define RADIO_RXADDRESSES_ADDR0_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR0_Enabled (1UL) /*!< Reception enabled. */
+
+/* Register: RADIO_CRCCNF */
+/* Description: CRC configuration. */
+
+/* Bit 8 : Leave packet address field out of the CRC calculation. Decision point: START task. */
+#define RADIO_CRCCNF_SKIPADDR_Pos (8UL) /*!< Position of SKIPADDR field. */
+#define RADIO_CRCCNF_SKIPADDR_Msk (0x1UL << RADIO_CRCCNF_SKIPADDR_Pos) /*!< Bit mask of SKIPADDR field. */
+#define RADIO_CRCCNF_SKIPADDR_Include (0UL) /*!< Include packet address in CRC calculation. */
+#define RADIO_CRCCNF_SKIPADDR_Skip (1UL) /*!< Packet address is skipped in CRC calculation. The CRC calculation will start at the first byte after the address. */
+
+/* Bits 1..0 : CRC length. Decision point: START task. */
+#define RADIO_CRCCNF_LEN_Pos (0UL) /*!< Position of LEN field. */
+#define RADIO_CRCCNF_LEN_Msk (0x3UL << RADIO_CRCCNF_LEN_Pos) /*!< Bit mask of LEN field. */
+#define RADIO_CRCCNF_LEN_Disabled (0UL) /*!< CRC calculation disabled. */
+#define RADIO_CRCCNF_LEN_One (1UL) /*!< One byte long CRC. */
+#define RADIO_CRCCNF_LEN_Two (2UL) /*!< Two bytes long CRC. */
+#define RADIO_CRCCNF_LEN_Three (3UL) /*!< Three bytes long CRC. */
+
+/* Register: RADIO_CRCPOLY */
+/* Description: CRC polynomial. */
+
+/* Bits 23..0 : CRC polynomial. Decision point: START task. */
+#define RADIO_CRCPOLY_CRCPOLY_Pos (0UL) /*!< Position of CRCPOLY field. */
+#define RADIO_CRCPOLY_CRCPOLY_Msk (0xFFFFFFUL << RADIO_CRCPOLY_CRCPOLY_Pos) /*!< Bit mask of CRCPOLY field. */
+
+/* Register: RADIO_CRCINIT */
+/* Description: CRC initial value. */
+
+/* Bits 23..0 : Initial value for CRC calculation. Decision point: START task. */
+#define RADIO_CRCINIT_CRCINIT_Pos (0UL) /*!< Position of CRCINIT field. */
+#define RADIO_CRCINIT_CRCINIT_Msk (0xFFFFFFUL << RADIO_CRCINIT_CRCINIT_Pos) /*!< Bit mask of CRCINIT field. */
+
+/* Register: RADIO_TEST */
+/* Description: Test features enable register. */
+
+/* Bit 1 : PLL lock. Decision point: TXEN or RXEN task. */
+#define RADIO_TEST_PLLLOCK_Pos (1UL) /*!< Position of PLLLOCK field. */
+#define RADIO_TEST_PLLLOCK_Msk (0x1UL << RADIO_TEST_PLLLOCK_Pos) /*!< Bit mask of PLLLOCK field. */
+#define RADIO_TEST_PLLLOCK_Disabled (0UL) /*!< PLL lock disabled. */
+#define RADIO_TEST_PLLLOCK_Enabled (1UL) /*!< PLL lock enabled. */
+
+/* Bit 0 : Constant carrier. Decision point: TXEN task. */
+#define RADIO_TEST_CONSTCARRIER_Pos (0UL) /*!< Position of CONSTCARRIER field. */
+#define RADIO_TEST_CONSTCARRIER_Msk (0x1UL << RADIO_TEST_CONSTCARRIER_Pos) /*!< Bit mask of CONSTCARRIER field. */
+#define RADIO_TEST_CONSTCARRIER_Disabled (0UL) /*!< Constant carrier disabled. */
+#define RADIO_TEST_CONSTCARRIER_Enabled (1UL) /*!< Constant carrier enabled. */
+
+/* Register: RADIO_TIFS */
+/* Description: Inter Frame Spacing in microseconds. */
+
+/* Bits 7..0 : Inter frame spacing in microseconds. Decision point: START rask */
+#define RADIO_TIFS_TIFS_Pos (0UL) /*!< Position of TIFS field. */
+#define RADIO_TIFS_TIFS_Msk (0xFFUL << RADIO_TIFS_TIFS_Pos) /*!< Bit mask of TIFS field. */
+
+/* Register: RADIO_RSSISAMPLE */
+/* Description: RSSI sample. */
+
+/* Bits 6..0 : RSSI sample result. The result is read as a positive value so that ReceivedSignalStrength = -RSSISAMPLE dBm */
+#define RADIO_RSSISAMPLE_RSSISAMPLE_Pos (0UL) /*!< Position of RSSISAMPLE field. */
+#define RADIO_RSSISAMPLE_RSSISAMPLE_Msk (0x7FUL << RADIO_RSSISAMPLE_RSSISAMPLE_Pos) /*!< Bit mask of RSSISAMPLE field. */
+
+/* Register: RADIO_STATE */
+/* Description: Current radio state. */
+
+/* Bits 3..0 : Current radio state. */
+#define RADIO_STATE_STATE_Pos (0UL) /*!< Position of STATE field. */
+#define RADIO_STATE_STATE_Msk (0xFUL << RADIO_STATE_STATE_Pos) /*!< Bit mask of STATE field. */
+#define RADIO_STATE_STATE_Disabled (0x00UL) /*!< Radio is in the Disabled state. */
+#define RADIO_STATE_STATE_RxRu (0x01UL) /*!< Radio is in the Rx Ramp Up state. */
+#define RADIO_STATE_STATE_RxIdle (0x02UL) /*!< Radio is in the Rx Idle state. */
+#define RADIO_STATE_STATE_Rx (0x03UL) /*!< Radio is in the Rx state. */
+#define RADIO_STATE_STATE_RxDisable (0x04UL) /*!< Radio is in the Rx Disable state. */
+#define RADIO_STATE_STATE_TxRu (0x09UL) /*!< Radio is in the Tx Ramp Up state. */
+#define RADIO_STATE_STATE_TxIdle (0x0AUL) /*!< Radio is in the Tx Idle state. */
+#define RADIO_STATE_STATE_Tx (0x0BUL) /*!< Radio is in the Tx state. */
+#define RADIO_STATE_STATE_TxDisable (0x0CUL) /*!< Radio is in the Tx Disable state. */
+
+/* Register: RADIO_DATAWHITEIV */
+/* Description: Data whitening initial value. */
+
+/* Bits 6..0 : Data whitening initial value. Bit 0 corresponds to Position 0 of the LSFR, Bit 1 to position 5... Decision point: TXEN or RXEN task. */
+#define RADIO_DATAWHITEIV_DATAWHITEIV_Pos (0UL) /*!< Position of DATAWHITEIV field. */
+#define RADIO_DATAWHITEIV_DATAWHITEIV_Msk (0x7FUL << RADIO_DATAWHITEIV_DATAWHITEIV_Pos) /*!< Bit mask of DATAWHITEIV field. */
+
+/* Register: RADIO_DAP */
+/* Description: Device address prefix. */
+
+/* Bits 15..0 : Device address prefix. */
+#define RADIO_DAP_DAP_Pos (0UL) /*!< Position of DAP field. */
+#define RADIO_DAP_DAP_Msk (0xFFFFUL << RADIO_DAP_DAP_Pos) /*!< Bit mask of DAP field. */
+
+/* Register: RADIO_DACNF */
+/* Description: Device address match configuration. */
+
+/* Bit 15 : TxAdd for device address 7. */
+#define RADIO_DACNF_TXADD7_Pos (15UL) /*!< Position of TXADD7 field. */
+#define RADIO_DACNF_TXADD7_Msk (0x1UL << RADIO_DACNF_TXADD7_Pos) /*!< Bit mask of TXADD7 field. */
+
+/* Bit 14 : TxAdd for device address 6. */
+#define RADIO_DACNF_TXADD6_Pos (14UL) /*!< Position of TXADD6 field. */
+#define RADIO_DACNF_TXADD6_Msk (0x1UL << RADIO_DACNF_TXADD6_Pos) /*!< Bit mask of TXADD6 field. */
+
+/* Bit 13 : TxAdd for device address 5. */
+#define RADIO_DACNF_TXADD5_Pos (13UL) /*!< Position of TXADD5 field. */
+#define RADIO_DACNF_TXADD5_Msk (0x1UL << RADIO_DACNF_TXADD5_Pos) /*!< Bit mask of TXADD5 field. */
+
+/* Bit 12 : TxAdd for device address 4. */
+#define RADIO_DACNF_TXADD4_Pos (12UL) /*!< Position of TXADD4 field. */
+#define RADIO_DACNF_TXADD4_Msk (0x1UL << RADIO_DACNF_TXADD4_Pos) /*!< Bit mask of TXADD4 field. */
+
+/* Bit 11 : TxAdd for device address 3. */
+#define RADIO_DACNF_TXADD3_Pos (11UL) /*!< Position of TXADD3 field. */
+#define RADIO_DACNF_TXADD3_Msk (0x1UL << RADIO_DACNF_TXADD3_Pos) /*!< Bit mask of TXADD3 field. */
+
+/* Bit 10 : TxAdd for device address 2. */
+#define RADIO_DACNF_TXADD2_Pos (10UL) /*!< Position of TXADD2 field. */
+#define RADIO_DACNF_TXADD2_Msk (0x1UL << RADIO_DACNF_TXADD2_Pos) /*!< Bit mask of TXADD2 field. */
+
+/* Bit 9 : TxAdd for device address 1. */
+#define RADIO_DACNF_TXADD1_Pos (9UL) /*!< Position of TXADD1 field. */
+#define RADIO_DACNF_TXADD1_Msk (0x1UL << RADIO_DACNF_TXADD1_Pos) /*!< Bit mask of TXADD1 field. */
+
+/* Bit 8 : TxAdd for device address 0. */
+#define RADIO_DACNF_TXADD0_Pos (8UL) /*!< Position of TXADD0 field. */
+#define RADIO_DACNF_TXADD0_Msk (0x1UL << RADIO_DACNF_TXADD0_Pos) /*!< Bit mask of TXADD0 field. */
+
+/* Bit 7 : Enable or disable device address matching using device address 7. */
+#define RADIO_DACNF_ENA7_Pos (7UL) /*!< Position of ENA7 field. */
+#define RADIO_DACNF_ENA7_Msk (0x1UL << RADIO_DACNF_ENA7_Pos) /*!< Bit mask of ENA7 field. */
+#define RADIO_DACNF_ENA7_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA7_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 6 : Enable or disable device address matching using device address 6. */
+#define RADIO_DACNF_ENA6_Pos (6UL) /*!< Position of ENA6 field. */
+#define RADIO_DACNF_ENA6_Msk (0x1UL << RADIO_DACNF_ENA6_Pos) /*!< Bit mask of ENA6 field. */
+#define RADIO_DACNF_ENA6_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA6_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 5 : Enable or disable device address matching using device address 5. */
+#define RADIO_DACNF_ENA5_Pos (5UL) /*!< Position of ENA5 field. */
+#define RADIO_DACNF_ENA5_Msk (0x1UL << RADIO_DACNF_ENA5_Pos) /*!< Bit mask of ENA5 field. */
+#define RADIO_DACNF_ENA5_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA5_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 4 : Enable or disable device address matching using device address 4. */
+#define RADIO_DACNF_ENA4_Pos (4UL) /*!< Position of ENA4 field. */
+#define RADIO_DACNF_ENA4_Msk (0x1UL << RADIO_DACNF_ENA4_Pos) /*!< Bit mask of ENA4 field. */
+#define RADIO_DACNF_ENA4_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA4_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 3 : Enable or disable device address matching using device address 3. */
+#define RADIO_DACNF_ENA3_Pos (3UL) /*!< Position of ENA3 field. */
+#define RADIO_DACNF_ENA3_Msk (0x1UL << RADIO_DACNF_ENA3_Pos) /*!< Bit mask of ENA3 field. */
+#define RADIO_DACNF_ENA3_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA3_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 2 : Enable or disable device address matching using device address 2. */
+#define RADIO_DACNF_ENA2_Pos (2UL) /*!< Position of ENA2 field. */
+#define RADIO_DACNF_ENA2_Msk (0x1UL << RADIO_DACNF_ENA2_Pos) /*!< Bit mask of ENA2 field. */
+#define RADIO_DACNF_ENA2_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA2_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 1 : Enable or disable device address matching using device address 1. */
+#define RADIO_DACNF_ENA1_Pos (1UL) /*!< Position of ENA1 field. */
+#define RADIO_DACNF_ENA1_Msk (0x1UL << RADIO_DACNF_ENA1_Pos) /*!< Bit mask of ENA1 field. */
+#define RADIO_DACNF_ENA1_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA1_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 0 : Enable or disable device address matching using device address 0. */
+#define RADIO_DACNF_ENA0_Pos (0UL) /*!< Position of ENA0 field. */
+#define RADIO_DACNF_ENA0_Msk (0x1UL << RADIO_DACNF_ENA0_Pos) /*!< Bit mask of ENA0 field. */
+#define RADIO_DACNF_ENA0_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA0_Enabled (1UL) /*!< Enabled. */
+
+/* Register: RADIO_OVERRIDE0 */
+/* Description: Trim value override register 0. */
+
+/* Bits 31..0 : Trim value override 0. */
+#define RADIO_OVERRIDE0_OVERRIDE0_Pos (0UL) /*!< Position of OVERRIDE0 field. */
+#define RADIO_OVERRIDE0_OVERRIDE0_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE0_OVERRIDE0_Pos) /*!< Bit mask of OVERRIDE0 field. */
+
+/* Register: RADIO_OVERRIDE1 */
+/* Description: Trim value override register 1. */
+
+/* Bits 31..0 : Trim value override 1. */
+#define RADIO_OVERRIDE1_OVERRIDE1_Pos (0UL) /*!< Position of OVERRIDE1 field. */
+#define RADIO_OVERRIDE1_OVERRIDE1_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE1_OVERRIDE1_Pos) /*!< Bit mask of OVERRIDE1 field. */
+
+/* Register: RADIO_OVERRIDE2 */
+/* Description: Trim value override register 2. */
+
+/* Bits 31..0 : Trim value override 2. */
+#define RADIO_OVERRIDE2_OVERRIDE2_Pos (0UL) /*!< Position of OVERRIDE2 field. */
+#define RADIO_OVERRIDE2_OVERRIDE2_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE2_OVERRIDE2_Pos) /*!< Bit mask of OVERRIDE2 field. */
+
+/* Register: RADIO_OVERRIDE3 */
+/* Description: Trim value override register 3. */
+
+/* Bits 31..0 : Trim value override 3. */
+#define RADIO_OVERRIDE3_OVERRIDE3_Pos (0UL) /*!< Position of OVERRIDE3 field. */
+#define RADIO_OVERRIDE3_OVERRIDE3_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE3_OVERRIDE3_Pos) /*!< Bit mask of OVERRIDE3 field. */
+
+/* Register: RADIO_OVERRIDE4 */
+/* Description: Trim value override register 4. */
+
+/* Bit 31 : Enable or disable override of default trim values. */
+#define RADIO_OVERRIDE4_ENABLE_Pos (31UL) /*!< Position of ENABLE field. */
+#define RADIO_OVERRIDE4_ENABLE_Msk (0x1UL << RADIO_OVERRIDE4_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define RADIO_OVERRIDE4_ENABLE_Disabled (0UL) /*!< Override trim values disabled. */
+#define RADIO_OVERRIDE4_ENABLE_Enabled (1UL) /*!< Override trim values enabled. */
+
+/* Bits 27..0 : Trim value override 4. */
+#define RADIO_OVERRIDE4_OVERRIDE4_Pos (0UL) /*!< Position of OVERRIDE4 field. */
+#define RADIO_OVERRIDE4_OVERRIDE4_Msk (0xFFFFFFFUL << RADIO_OVERRIDE4_OVERRIDE4_Pos) /*!< Bit mask of OVERRIDE4 field. */
+
+/* Register: RADIO_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RADIO_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RADIO_POWER_POWER_Msk (0x1UL << RADIO_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RADIO_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RADIO_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RNG */
+/* Description: Random Number Generator. */
+
+/* Register: RNG_SHORTS */
+/* Description: Shortcuts for the RNG. */
+
+/* Bit 0 : Shortcut between VALRDY event and STOP task. */
+#define RNG_SHORTS_VALRDY_STOP_Pos (0UL) /*!< Position of VALRDY_STOP field. */
+#define RNG_SHORTS_VALRDY_STOP_Msk (0x1UL << RNG_SHORTS_VALRDY_STOP_Pos) /*!< Bit mask of VALRDY_STOP field. */
+#define RNG_SHORTS_VALRDY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define RNG_SHORTS_VALRDY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: RNG_INTENSET */
+/* Description: Interrupt enable set register */
+
+/* Bit 0 : Enable interrupt on VALRDY event. */
+#define RNG_INTENSET_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */
+#define RNG_INTENSET_VALRDY_Msk (0x1UL << RNG_INTENSET_VALRDY_Pos) /*!< Bit mask of VALRDY field. */
+#define RNG_INTENSET_VALRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RNG_INTENSET_VALRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RNG_INTENSET_VALRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RNG_INTENCLR */
+/* Description: Interrupt enable clear register */
+
+/* Bit 0 : Disable interrupt on VALRDY event. */
+#define RNG_INTENCLR_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */
+#define RNG_INTENCLR_VALRDY_Msk (0x1UL << RNG_INTENCLR_VALRDY_Pos) /*!< Bit mask of VALRDY field. */
+#define RNG_INTENCLR_VALRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RNG_INTENCLR_VALRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RNG_INTENCLR_VALRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RNG_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 0 : Digital error correction enable. */
+#define RNG_CONFIG_DERCEN_Pos (0UL) /*!< Position of DERCEN field. */
+#define RNG_CONFIG_DERCEN_Msk (0x1UL << RNG_CONFIG_DERCEN_Pos) /*!< Bit mask of DERCEN field. */
+#define RNG_CONFIG_DERCEN_Disabled (0UL) /*!< Digital error correction disabled. */
+#define RNG_CONFIG_DERCEN_Enabled (1UL) /*!< Digital error correction enabled. */
+
+/* Register: RNG_VALUE */
+/* Description: RNG random number. */
+
+/* Bits 7..0 : Generated random number. */
+#define RNG_VALUE_VALUE_Pos (0UL) /*!< Position of VALUE field. */
+#define RNG_VALUE_VALUE_Msk (0xFFUL << RNG_VALUE_VALUE_Pos) /*!< Bit mask of VALUE field. */
+
+/* Register: RNG_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RNG_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RNG_POWER_POWER_Msk (0x1UL << RNG_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RNG_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RNG_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RTC */
+/* Description: Real time counter 0. */
+
+/* Register: RTC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on COMPARE[3] event. */
+#define RTC_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_INTENSET_COMPARE3_Msk (0x1UL << RTC_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_INTENSET_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 18 : Enable interrupt on COMPARE[2] event. */
+#define RTC_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_INTENSET_COMPARE2_Msk (0x1UL << RTC_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_INTENSET_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 17 : Enable interrupt on COMPARE[1] event. */
+#define RTC_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_INTENSET_COMPARE1_Msk (0x1UL << RTC_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_INTENSET_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 16 : Enable interrupt on COMPARE[0] event. */
+#define RTC_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_INTENSET_COMPARE0_Msk (0x1UL << RTC_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_INTENSET_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on OVRFLW event. */
+#define RTC_INTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_INTENSET_OVRFLW_Msk (0x1UL << RTC_INTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_INTENSET_OVRFLW_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_OVRFLW_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_OVRFLW_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on TICK event. */
+#define RTC_INTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_INTENSET_TICK_Msk (0x1UL << RTC_INTENSET_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_INTENSET_TICK_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_TICK_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_TICK_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RTC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on COMPARE[3] event. */
+#define RTC_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_INTENCLR_COMPARE3_Msk (0x1UL << RTC_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_INTENCLR_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 18 : Disable interrupt on COMPARE[2] event. */
+#define RTC_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_INTENCLR_COMPARE2_Msk (0x1UL << RTC_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_INTENCLR_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 17 : Disable interrupt on COMPARE[1] event. */
+#define RTC_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_INTENCLR_COMPARE1_Msk (0x1UL << RTC_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_INTENCLR_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 16 : Disable interrupt on COMPARE[0] event. */
+#define RTC_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_INTENCLR_COMPARE0_Msk (0x1UL << RTC_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_INTENCLR_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on OVRFLW event. */
+#define RTC_INTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_INTENCLR_OVRFLW_Msk (0x1UL << RTC_INTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_INTENCLR_OVRFLW_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_OVRFLW_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_OVRFLW_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on TICK event. */
+#define RTC_INTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_INTENCLR_TICK_Msk (0x1UL << RTC_INTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_INTENCLR_TICK_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_TICK_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_TICK_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RTC_EVTEN */
+/* Description: Configures event enable routing to PPI for each RTC event. */
+
+/* Bit 19 : COMPARE[3] event enable. */
+#define RTC_EVTEN_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTEN_COMPARE3_Msk (0x1UL << RTC_EVTEN_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTEN_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 18 : COMPARE[2] event enable. */
+#define RTC_EVTEN_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTEN_COMPARE2_Msk (0x1UL << RTC_EVTEN_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTEN_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 17 : COMPARE[1] event enable. */
+#define RTC_EVTEN_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTEN_COMPARE1_Msk (0x1UL << RTC_EVTEN_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTEN_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 16 : COMPARE[0] event enable. */
+#define RTC_EVTEN_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTEN_COMPARE0_Msk (0x1UL << RTC_EVTEN_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTEN_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 1 : OVRFLW event enable. */
+#define RTC_EVTEN_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTEN_OVRFLW_Msk (0x1UL << RTC_EVTEN_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTEN_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 0 : TICK event enable. */
+#define RTC_EVTEN_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTEN_TICK_Msk (0x1UL << RTC_EVTEN_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTEN_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_TICK_Enabled (1UL) /*!< Event enabled. */
+
+/* Register: RTC_EVTENSET */
+/* Description: Enable events routing to PPI. The reading of this register gives the value of EVTEN. */
+
+/* Bit 19 : Enable routing to PPI of COMPARE[3] event. */
+#define RTC_EVTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTENSET_COMPARE3_Msk (0x1UL << RTC_EVTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTENSET_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE3_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 18 : Enable routing to PPI of COMPARE[2] event. */
+#define RTC_EVTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTENSET_COMPARE2_Msk (0x1UL << RTC_EVTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTENSET_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE2_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 17 : Enable routing to PPI of COMPARE[1] event. */
+#define RTC_EVTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTENSET_COMPARE1_Msk (0x1UL << RTC_EVTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTENSET_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE1_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 16 : Enable routing to PPI of COMPARE[0] event. */
+#define RTC_EVTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTENSET_COMPARE0_Msk (0x1UL << RTC_EVTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTENSET_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE0_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 1 : Enable routing to PPI of OVRFLW event. */
+#define RTC_EVTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTENSET_OVRFLW_Msk (0x1UL << RTC_EVTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTENSET_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_OVRFLW_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 0 : Enable routing to PPI of TICK event. */
+#define RTC_EVTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTENSET_TICK_Msk (0x1UL << RTC_EVTENSET_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTENSET_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_TICK_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_TICK_Set (1UL) /*!< Enable event on write. */
+
+/* Register: RTC_EVTENCLR */
+/* Description: Disable events routing to PPI. The reading of this register gives the value of EVTEN. */
+
+/* Bit 19 : Disable routing to PPI of COMPARE[3] event. */
+#define RTC_EVTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTENCLR_COMPARE3_Msk (0x1UL << RTC_EVTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTENCLR_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE3_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 18 : Disable routing to PPI of COMPARE[2] event. */
+#define RTC_EVTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTENCLR_COMPARE2_Msk (0x1UL << RTC_EVTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTENCLR_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE2_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 17 : Disable routing to PPI of COMPARE[1] event. */
+#define RTC_EVTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTENCLR_COMPARE1_Msk (0x1UL << RTC_EVTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTENCLR_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE1_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 16 : Disable routing to PPI of COMPARE[0] event. */
+#define RTC_EVTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTENCLR_COMPARE0_Msk (0x1UL << RTC_EVTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTENCLR_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE0_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 1 : Disable routing to PPI of OVRFLW event. */
+#define RTC_EVTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTENCLR_OVRFLW_Msk (0x1UL << RTC_EVTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTENCLR_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_OVRFLW_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 0 : Disable routing to PPI of TICK event. */
+#define RTC_EVTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTENCLR_TICK_Msk (0x1UL << RTC_EVTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTENCLR_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_TICK_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_TICK_Clear (1UL) /*!< Disable event on write. */
+
+/* Register: RTC_COUNTER */
+/* Description: Current COUNTER value. */
+
+/* Bits 23..0 : Counter value. */
+#define RTC_COUNTER_COUNTER_Pos (0UL) /*!< Position of COUNTER field. */
+#define RTC_COUNTER_COUNTER_Msk (0xFFFFFFUL << RTC_COUNTER_COUNTER_Pos) /*!< Bit mask of COUNTER field. */
+
+/* Register: RTC_PRESCALER */
+/* Description: 12-bit prescaler for COUNTER frequency (32768/(PRESCALER+1)). Must be written when RTC is STOPed. */
+
+/* Bits 11..0 : RTC PRESCALER value. */
+#define RTC_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */
+#define RTC_PRESCALER_PRESCALER_Msk (0xFFFUL << RTC_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */
+
+/* Register: RTC_CC */
+/* Description: Capture/compare registers. */
+
+/* Bits 23..0 : Compare value. */
+#define RTC_CC_COMPARE_Pos (0UL) /*!< Position of COMPARE field. */
+#define RTC_CC_COMPARE_Msk (0xFFFFFFUL << RTC_CC_COMPARE_Pos) /*!< Bit mask of COMPARE field. */
+
+/* Register: RTC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RTC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RTC_POWER_POWER_Msk (0x1UL << RTC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RTC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RTC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: SPI */
+/* Description: SPI master 0. */
+
+/* Register: SPI_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on READY event. */
+#define SPI_INTENSET_READY_Pos (2UL) /*!< Position of READY field. */
+#define SPI_INTENSET_READY_Msk (0x1UL << SPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define SPI_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPI_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPI_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPI_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on READY event. */
+#define SPI_INTENCLR_READY_Pos (2UL) /*!< Position of READY field. */
+#define SPI_INTENCLR_READY_Msk (0x1UL << SPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define SPI_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPI_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPI_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPI_ENABLE */
+/* Description: Enable SPI. */
+
+/* Bits 2..0 : Enable or disable SPI. */
+#define SPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPI_ENABLE_ENABLE_Msk (0x7UL << SPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPI_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPI. */
+#define SPI_ENABLE_ENABLE_Enabled (0x01UL) /*!< Enable SPI. */
+
+/* Register: SPI_RXD */
+/* Description: RX data. */
+
+/* Bits 7..0 : RX data from last transfer. */
+#define SPI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define SPI_RXD_RXD_Msk (0xFFUL << SPI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: SPI_TXD */
+/* Description: TX data. */
+
+/* Bits 7..0 : TX data for next transfer. */
+#define SPI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define SPI_TXD_TXD_Msk (0xFFUL << SPI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: SPI_FREQUENCY */
+/* Description: SPI frequency */
+
+/* Bits 31..0 : SPI data rate. */
+#define SPI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define SPI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define SPI_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125kbps. */
+#define SPI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250kbps. */
+#define SPI_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500kbps. */
+#define SPI_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8Mbps. */
+
+/* Register: SPI_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPI_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPI_CONFIG_CPOL_Msk (0x1UL << SPI_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPI_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPI_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPI_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPI_CONFIG_CPHA_Msk (0x1UL << SPI_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPI_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPI_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPI_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPI_CONFIG_ORDER_Msk (0x1UL << SPI_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPI_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPI_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPI_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPI_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPI_POWER_POWER_Msk (0x1UL << SPI_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPI_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPI_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: SPIM */
+/* Description: SPI master with easyDMA 1. */
+
+/* Register: SPIM_SHORTS */
+/* Description: Shortcuts for SPIM. */
+
+/* Bit 17 : Shortcut between END event and START task. */
+#define SPIM_SHORTS_END_START_Pos (17UL) /*!< Position of END_START field. */
+#define SPIM_SHORTS_END_START_Msk (0x1UL << SPIM_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */
+#define SPIM_SHORTS_END_START_Disabled (0UL) /*!< Shortcut disabled. */
+#define SPIM_SHORTS_END_START_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: SPIM_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on STARTED event. */
+#define SPIM_INTENSET_STARTED_Pos (19UL) /*!< Position of STARTED field. */
+#define SPIM_INTENSET_STARTED_Msk (0x1UL << SPIM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */
+#define SPIM_INTENSET_STARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_STARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_STARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 8 : Enable interrupt on ENDTX event. */
+#define SPIM_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */
+#define SPIM_INTENSET_ENDTX_Msk (0x1UL << SPIM_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */
+#define SPIM_INTENSET_ENDTX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 6 : Enable interrupt on END event. */
+#define SPIM_INTENSET_END_Pos (6UL) /*!< Position of END field. */
+#define SPIM_INTENSET_END_Msk (0x1UL << SPIM_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define SPIM_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 4 : Enable interrupt on ENDRX event. */
+#define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIM_INTENSET_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_ENDRX_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on STOPPED event. */
+#define SPIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define SPIM_INTENSET_STOPPED_Msk (0x1UL << SPIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define SPIM_INTENSET_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_STOPPED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPIM_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on STARTED event. */
+#define SPIM_INTENCLR_STARTED_Pos (19UL) /*!< Position of STARTED field. */
+#define SPIM_INTENCLR_STARTED_Msk (0x1UL << SPIM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */
+#define SPIM_INTENCLR_STARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_STARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_STARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 8 : Disable interrupt on ENDTX event. */
+#define SPIM_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */
+#define SPIM_INTENCLR_ENDTX_Msk (0x1UL << SPIM_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */
+#define SPIM_INTENCLR_ENDTX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 6 : Disable interrupt on END event. */
+#define SPIM_INTENCLR_END_Pos (6UL) /*!< Position of END field. */
+#define SPIM_INTENCLR_END_Msk (0x1UL << SPIM_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define SPIM_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 4 : Disable interrupt on ENDRX event. */
+#define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIM_INTENCLR_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_ENDRX_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on STOPPED event. */
+#define SPIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define SPIM_INTENCLR_STOPPED_Msk (0x1UL << SPIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define SPIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPIM_ENABLE */
+/* Description: Enable SPIM. */
+
+/* Bits 3..0 : Enable or disable SPIM. */
+#define SPIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPIM_ENABLE_ENABLE_Msk (0xFUL << SPIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPIM_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPIM. */
+#define SPIM_ENABLE_ENABLE_Enabled (0x07UL) /*!< Enable SPIM. */
+
+/* Register: SPIM_RXDDATA */
+/* Description: RXD register. */
+
+/* Bits 7..0 : RX data received. Double buffered. */
+#define SPIM_RXDDATA_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define SPIM_RXDDATA_RXD_Msk (0xFFUL << SPIM_RXDDATA_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: SPIM_TXDDATA */
+/* Description: TXD register. */
+
+/* Bits 7..0 : TX data to send. Double buffered. */
+#define SPIM_TXDDATA_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define SPIM_TXDDATA_TXD_Msk (0xFFUL << SPIM_TXDDATA_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: SPIM_FREQUENCY */
+/* Description: SPI frequency. */
+
+/* Bits 31..0 : SPI master data rate. */
+#define SPIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define SPIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define SPIM_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps. */
+
+/* Register: SPIM_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPIM_ORC */
+/* Description: Over-read character. */
+
+/* Bits 7..0 : Over-read character. */
+#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
+#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
+
+/* Register: SPIM_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPIM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPIM_POWER_POWER_Msk (0x1UL << SPIM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPIM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPIM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+/* Register: SPIM_RXD_PTR */
+/* Description: Data pointer. */
+
+/* Bits 31..0 : Data pointer. */
+#define SPIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
+#define SPIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
+
+/* Register: SPIM_RXD_MAXCNT */
+/* Description: Maximum number of buffer bytes to receive. */
+
+/* Bits 7..0 : Maximum number of buffer bytes to receive. */
+#define SPIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
+#define SPIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
+
+/* Register: SPIM_RXD_AMOUNT */
+/* Description: Number of bytes received in the last transaction. */
+
+/* Bits 7..0 : Number of bytes received in the last transaction. */
+#define SPIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
+#define SPIM_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
+
+/* Register: SPIM_TXD_PTR */
+/* Description: Data pointer. */
+
+/* Bits 31..0 : Data pointer. */
+#define SPIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
+#define SPIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
+
+/* Register: SPIM_TXD_MAXCNT */
+/* Description: Maximum number of buffer bytes to send. */
+
+/* Bits 7..0 : Maximum number of buffer bytes to send. */
+#define SPIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
+#define SPIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
+
+/* Register: SPIM_TXD_AMOUNT */
+/* Description: Number of bytes sent in the last transaction. */
+
+/* Bits 7..0 : Number of bytes sent in the last transaction. */
+#define SPIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
+#define SPIM_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
+
+
+/* Peripheral: SPIS */
+/* Description: SPI slave 1. */
+
+/* Register: SPIS_SHORTS */
+/* Description: Shortcuts for SPIS. */
+
+/* Bit 2 : Shortcut between END event and the ACQUIRE task. */
+#define SPIS_SHORTS_END_ACQUIRE_Pos (2UL) /*!< Position of END_ACQUIRE field. */
+#define SPIS_SHORTS_END_ACQUIRE_Msk (0x1UL << SPIS_SHORTS_END_ACQUIRE_Pos) /*!< Bit mask of END_ACQUIRE field. */
+#define SPIS_SHORTS_END_ACQUIRE_Disabled (0UL) /*!< Shortcut disabled. */
+#define SPIS_SHORTS_END_ACQUIRE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: SPIS_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 10 : Enable interrupt on ACQUIRED event. */
+#define SPIS_INTENSET_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */
+#define SPIS_INTENSET_ACQUIRED_Msk (0x1UL << SPIS_INTENSET_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */
+#define SPIS_INTENSET_ACQUIRED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on END event. */
+#define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */
+#define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define SPIS_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPIS_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 10 : Disable interrupt on ACQUIRED event. */
+#define SPIS_INTENCLR_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */
+#define SPIS_INTENCLR_ACQUIRED_Msk (0x1UL << SPIS_INTENCLR_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */
+#define SPIS_INTENCLR_ACQUIRED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on END event. */
+#define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */
+#define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define SPIS_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPIS_SEMSTAT */
+/* Description: Semaphore status. */
+
+/* Bits 1..0 : Semaphore status. */
+#define SPIS_SEMSTAT_SEMSTAT_Pos (0UL) /*!< Position of SEMSTAT field. */
+#define SPIS_SEMSTAT_SEMSTAT_Msk (0x3UL << SPIS_SEMSTAT_SEMSTAT_Pos) /*!< Bit mask of SEMSTAT field. */
+#define SPIS_SEMSTAT_SEMSTAT_Free (0x00UL) /*!< Semaphore is free. */
+#define SPIS_SEMSTAT_SEMSTAT_CPU (0x01UL) /*!< Semaphore is assigned to the CPU. */
+#define SPIS_SEMSTAT_SEMSTAT_SPIS (0x02UL) /*!< Semaphore is assigned to the SPIS. */
+#define SPIS_SEMSTAT_SEMSTAT_CPUPending (0x03UL) /*!< Semaphore is assigned to the SPIS, but a handover to the CPU is pending. */
+
+/* Register: SPIS_STATUS */
+/* Description: Status from last transaction. */
+
+/* Bit 1 : RX buffer overflow detected, and prevented. */
+#define SPIS_STATUS_OVERFLOW_Pos (1UL) /*!< Position of OVERFLOW field. */
+#define SPIS_STATUS_OVERFLOW_Msk (0x1UL << SPIS_STATUS_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */
+#define SPIS_STATUS_OVERFLOW_NotPresent (0UL) /*!< Error not present. */
+#define SPIS_STATUS_OVERFLOW_Present (1UL) /*!< Error present. */
+#define SPIS_STATUS_OVERFLOW_Clear (1UL) /*!< Clear on write. */
+
+/* Bit 0 : TX buffer overread detected, and prevented. */
+#define SPIS_STATUS_OVERREAD_Pos (0UL) /*!< Position of OVERREAD field. */
+#define SPIS_STATUS_OVERREAD_Msk (0x1UL << SPIS_STATUS_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */
+#define SPIS_STATUS_OVERREAD_NotPresent (0UL) /*!< Error not present. */
+#define SPIS_STATUS_OVERREAD_Present (1UL) /*!< Error present. */
+#define SPIS_STATUS_OVERREAD_Clear (1UL) /*!< Clear on write. */
+
+/* Register: SPIS_ENABLE */
+/* Description: Enable SPIS. */
+
+/* Bits 2..0 : Enable or disable SPIS. */
+#define SPIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPIS_ENABLE_ENABLE_Msk (0x7UL << SPIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPIS_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPIS. */
+#define SPIS_ENABLE_ENABLE_Enabled (0x02UL) /*!< Enable SPIS. */
+
+/* Register: SPIS_MAXRX */
+/* Description: Maximum number of bytes in the receive buffer. */
+
+/* Bits 7..0 : Maximum number of bytes in the receive buffer. */
+#define SPIS_MAXRX_MAXRX_Pos (0UL) /*!< Position of MAXRX field. */
+#define SPIS_MAXRX_MAXRX_Msk (0xFFUL << SPIS_MAXRX_MAXRX_Pos) /*!< Bit mask of MAXRX field. */
+
+/* Register: SPIS_AMOUNTRX */
+/* Description: Number of bytes received in last granted transaction. */
+
+/* Bits 7..0 : Number of bytes received in last granted transaction. */
+#define SPIS_AMOUNTRX_AMOUNTRX_Pos (0UL) /*!< Position of AMOUNTRX field. */
+#define SPIS_AMOUNTRX_AMOUNTRX_Msk (0xFFUL << SPIS_AMOUNTRX_AMOUNTRX_Pos) /*!< Bit mask of AMOUNTRX field. */
+
+/* Register: SPIS_MAXTX */
+/* Description: Maximum number of bytes in the transmit buffer. */
+
+/* Bits 7..0 : Maximum number of bytes in the transmit buffer. */
+#define SPIS_MAXTX_MAXTX_Pos (0UL) /*!< Position of MAXTX field. */
+#define SPIS_MAXTX_MAXTX_Msk (0xFFUL << SPIS_MAXTX_MAXTX_Pos) /*!< Bit mask of MAXTX field. */
+
+/* Register: SPIS_AMOUNTTX */
+/* Description: Number of bytes transmitted in last granted transaction. */
+
+/* Bits 7..0 : Number of bytes transmitted in last granted transaction. */
+#define SPIS_AMOUNTTX_AMOUNTTX_Pos (0UL) /*!< Position of AMOUNTTX field. */
+#define SPIS_AMOUNTTX_AMOUNTTX_Msk (0xFFUL << SPIS_AMOUNTTX_AMOUNTTX_Pos) /*!< Bit mask of AMOUNTTX field. */
+
+/* Register: SPIS_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPIS_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPIS_CONFIG_CPOL_Msk (0x1UL << SPIS_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPIS_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPIS_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPIS_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPIS_CONFIG_CPHA_Msk (0x1UL << SPIS_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPIS_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPIS_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPIS_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPIS_CONFIG_ORDER_Msk (0x1UL << SPIS_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPIS_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPIS_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPIS_DEF */
+/* Description: Default character. */
+
+/* Bits 7..0 : Default character. */
+#define SPIS_DEF_DEF_Pos (0UL) /*!< Position of DEF field. */
+#define SPIS_DEF_DEF_Msk (0xFFUL << SPIS_DEF_DEF_Pos) /*!< Bit mask of DEF field. */
+
+/* Register: SPIS_ORC */
+/* Description: Over-read character. */
+
+/* Bits 7..0 : Over-read character. */
+#define SPIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
+#define SPIS_ORC_ORC_Msk (0xFFUL << SPIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
+
+/* Register: SPIS_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPIS_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPIS_POWER_POWER_Msk (0x1UL << SPIS_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPIS_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPIS_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TEMP */
+/* Description: Temperature Sensor. */
+
+/* Register: TEMP_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on DATARDY event. */
+#define TEMP_INTENSET_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */
+#define TEMP_INTENSET_DATARDY_Msk (0x1UL << TEMP_INTENSET_DATARDY_Pos) /*!< Bit mask of DATARDY field. */
+#define TEMP_INTENSET_DATARDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TEMP_INTENSET_DATARDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TEMP_INTENSET_DATARDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TEMP_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on DATARDY event. */
+#define TEMP_INTENCLR_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */
+#define TEMP_INTENCLR_DATARDY_Msk (0x1UL << TEMP_INTENCLR_DATARDY_Pos) /*!< Bit mask of DATARDY field. */
+#define TEMP_INTENCLR_DATARDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TEMP_INTENCLR_DATARDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TEMP_INTENCLR_DATARDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TEMP_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TEMP_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TEMP_POWER_POWER_Msk (0x1UL << TEMP_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TEMP_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TEMP_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TIMER */
+/* Description: Timer 0. */
+
+/* Register: TIMER_SHORTS */
+/* Description: Shortcuts for Timer. */
+
+/* Bit 11 : Shortcut between CC[3] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE3_STOP_Pos (11UL) /*!< Position of COMPARE3_STOP field. */
+#define TIMER_SHORTS_COMPARE3_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE3_STOP_Pos) /*!< Bit mask of COMPARE3_STOP field. */
+#define TIMER_SHORTS_COMPARE3_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE3_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 10 : Shortcut between CC[2] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE2_STOP_Pos (10UL) /*!< Position of COMPARE2_STOP field. */
+#define TIMER_SHORTS_COMPARE2_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE2_STOP_Pos) /*!< Bit mask of COMPARE2_STOP field. */
+#define TIMER_SHORTS_COMPARE2_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE2_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 9 : Shortcut between CC[1] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE1_STOP_Pos (9UL) /*!< Position of COMPARE1_STOP field. */
+#define TIMER_SHORTS_COMPARE1_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE1_STOP_Pos) /*!< Bit mask of COMPARE1_STOP field. */
+#define TIMER_SHORTS_COMPARE1_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE1_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 8 : Shortcut between CC[0] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE0_STOP_Pos (8UL) /*!< Position of COMPARE0_STOP field. */
+#define TIMER_SHORTS_COMPARE0_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE0_STOP_Pos) /*!< Bit mask of COMPARE0_STOP field. */
+#define TIMER_SHORTS_COMPARE0_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE0_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between CC[3] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Pos (3UL) /*!< Position of COMPARE3_CLEAR field. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE3_CLEAR_Pos) /*!< Bit mask of COMPARE3_CLEAR field. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between CC[2] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Pos (2UL) /*!< Position of COMPARE2_CLEAR field. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE2_CLEAR_Pos) /*!< Bit mask of COMPARE2_CLEAR field. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between CC[1] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Pos (1UL) /*!< Position of COMPARE1_CLEAR field. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE1_CLEAR_Pos) /*!< Bit mask of COMPARE1_CLEAR field. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between CC[0] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Pos (0UL) /*!< Position of COMPARE0_CLEAR field. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE0_CLEAR_Pos) /*!< Bit mask of COMPARE0_CLEAR field. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: TIMER_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on COMPARE[3] */
+#define TIMER_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define TIMER_INTENSET_COMPARE3_Msk (0x1UL << TIMER_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define TIMER_INTENSET_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 18 : Enable interrupt on COMPARE[2] */
+#define TIMER_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define TIMER_INTENSET_COMPARE2_Msk (0x1UL << TIMER_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define TIMER_INTENSET_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 17 : Enable interrupt on COMPARE[1] */
+#define TIMER_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define TIMER_INTENSET_COMPARE1_Msk (0x1UL << TIMER_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define TIMER_INTENSET_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 16 : Enable interrupt on COMPARE[0] */
+#define TIMER_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define TIMER_INTENSET_COMPARE0_Msk (0x1UL << TIMER_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define TIMER_INTENSET_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TIMER_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on COMPARE[3] */
+#define TIMER_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define TIMER_INTENCLR_COMPARE3_Msk (0x1UL << TIMER_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define TIMER_INTENCLR_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 18 : Disable interrupt on COMPARE[2] */
+#define TIMER_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define TIMER_INTENCLR_COMPARE2_Msk (0x1UL << TIMER_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define TIMER_INTENCLR_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 17 : Disable interrupt on COMPARE[1] */
+#define TIMER_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define TIMER_INTENCLR_COMPARE1_Msk (0x1UL << TIMER_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define TIMER_INTENCLR_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 16 : Disable interrupt on COMPARE[0] */
+#define TIMER_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define TIMER_INTENCLR_COMPARE0_Msk (0x1UL << TIMER_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define TIMER_INTENCLR_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TIMER_MODE */
+/* Description: Timer Mode selection. */
+
+/* Bit 0 : Select Normal or Counter mode. */
+#define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define TIMER_MODE_MODE_Msk (0x1UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define TIMER_MODE_MODE_Timer (0UL) /*!< Timer in Normal mode. */
+#define TIMER_MODE_MODE_Counter (1UL) /*!< Timer in Counter mode. */
+
+/* Register: TIMER_BITMODE */
+/* Description: Sets timer behaviour. */
+
+/* Bits 1..0 : Sets timer behaviour ro be like the implementation of a timer with width as indicated. */
+#define TIMER_BITMODE_BITMODE_Pos (0UL) /*!< Position of BITMODE field. */
+#define TIMER_BITMODE_BITMODE_Msk (0x3UL << TIMER_BITMODE_BITMODE_Pos) /*!< Bit mask of BITMODE field. */
+#define TIMER_BITMODE_BITMODE_16Bit (0x00UL) /*!< 16-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_08Bit (0x01UL) /*!< 8-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_24Bit (0x02UL) /*!< 24-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_32Bit (0x03UL) /*!< 32-bit timer behaviour. */
+
+/* Register: TIMER_PRESCALER */
+/* Description: 4-bit prescaler to source clock frequency (max value 9). Source clock frequency is divided by 2^SCALE. */
+
+/* Bits 3..0 : Timer PRESCALER value. Max value is 9. */
+#define TIMER_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */
+#define TIMER_PRESCALER_PRESCALER_Msk (0xFUL << TIMER_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */
+
+/* Register: TIMER_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TIMER_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TIMER_POWER_POWER_Msk (0x1UL << TIMER_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TIMER_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TIMER_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TWI */
+/* Description: Two-wire interface master 0. */
+
+/* Register: TWI_SHORTS */
+/* Description: Shortcuts for TWI. */
+
+/* Bit 1 : Shortcut between BB event and the STOP task. */
+#define TWI_SHORTS_BB_STOP_Pos (1UL) /*!< Position of BB_STOP field. */
+#define TWI_SHORTS_BB_STOP_Msk (0x1UL << TWI_SHORTS_BB_STOP_Pos) /*!< Bit mask of BB_STOP field. */
+#define TWI_SHORTS_BB_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TWI_SHORTS_BB_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between BB event and the SUSPEND task. */
+#define TWI_SHORTS_BB_SUSPEND_Pos (0UL) /*!< Position of BB_SUSPEND field. */
+#define TWI_SHORTS_BB_SUSPEND_Msk (0x1UL << TWI_SHORTS_BB_SUSPEND_Pos) /*!< Bit mask of BB_SUSPEND field. */
+#define TWI_SHORTS_BB_SUSPEND_Disabled (0UL) /*!< Shortcut disabled. */
+#define TWI_SHORTS_BB_SUSPEND_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: TWI_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 18 : Enable interrupt on SUSPENDED event. */
+#define TWI_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */
+#define TWI_INTENSET_SUSPENDED_Msk (0x1UL << TWI_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */
+#define TWI_INTENSET_SUSPENDED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_SUSPENDED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_SUSPENDED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 14 : Enable interrupt on BB event. */
+#define TWI_INTENSET_BB_Pos (14UL) /*!< Position of BB field. */
+#define TWI_INTENSET_BB_Msk (0x1UL << TWI_INTENSET_BB_Pos) /*!< Bit mask of BB field. */
+#define TWI_INTENSET_BB_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_BB_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_BB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 9 : Enable interrupt on ERROR event. */
+#define TWI_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define TWI_INTENSET_ERROR_Msk (0x1UL << TWI_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define TWI_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on TXDSENT event. */
+#define TWI_INTENSET_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */
+#define TWI_INTENSET_TXDSENT_Msk (0x1UL << TWI_INTENSET_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */
+#define TWI_INTENSET_TXDSENT_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_TXDSENT_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_TXDSENT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on READY event. */
+#define TWI_INTENSET_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */
+#define TWI_INTENSET_RXDREADY_Msk (0x1UL << TWI_INTENSET_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */
+#define TWI_INTENSET_RXDREADY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_RXDREADY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_RXDREADY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on STOPPED event. */
+#define TWI_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define TWI_INTENSET_STOPPED_Msk (0x1UL << TWI_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define TWI_INTENSET_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_STOPPED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TWI_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 18 : Disable interrupt on SUSPENDED event. */
+#define TWI_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */
+#define TWI_INTENCLR_SUSPENDED_Msk (0x1UL << TWI_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */
+#define TWI_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 14 : Disable interrupt on BB event. */
+#define TWI_INTENCLR_BB_Pos (14UL) /*!< Position of BB field. */
+#define TWI_INTENCLR_BB_Msk (0x1UL << TWI_INTENCLR_BB_Pos) /*!< Bit mask of BB field. */
+#define TWI_INTENCLR_BB_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_BB_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_BB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 9 : Disable interrupt on ERROR event. */
+#define TWI_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define TWI_INTENCLR_ERROR_Msk (0x1UL << TWI_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define TWI_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on TXDSENT event. */
+#define TWI_INTENCLR_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */
+#define TWI_INTENCLR_TXDSENT_Msk (0x1UL << TWI_INTENCLR_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */
+#define TWI_INTENCLR_TXDSENT_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_TXDSENT_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_TXDSENT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on RXDREADY event. */
+#define TWI_INTENCLR_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */
+#define TWI_INTENCLR_RXDREADY_Msk (0x1UL << TWI_INTENCLR_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */
+#define TWI_INTENCLR_RXDREADY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_RXDREADY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_RXDREADY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on STOPPED event. */
+#define TWI_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define TWI_INTENCLR_STOPPED_Msk (0x1UL << TWI_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define TWI_INTENCLR_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_STOPPED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TWI_ERRORSRC */
+/* Description: Two-wire error source. Write error field to 1 to clear error. */
+
+/* Bit 2 : NACK received after sending a data byte. */
+#define TWI_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */
+#define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */
+#define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Error not present. */
+#define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Error present. */
+#define TWI_ERRORSRC_DNACK_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 1 : NACK received after sending the address. */
+#define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */
+#define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */
+#define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Error not present. */
+#define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Error present. */
+#define TWI_ERRORSRC_ANACK_Clear (1UL) /*!< Clear error on write. */
+
+/* Register: TWI_ENABLE */
+/* Description: Enable two-wire master. */
+
+/* Bits 2..0 : Enable or disable W2M */
+#define TWI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define TWI_ENABLE_ENABLE_Msk (0x7UL << TWI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define TWI_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled. */
+#define TWI_ENABLE_ENABLE_Enabled (0x05UL) /*!< Enabled. */
+
+/* Register: TWI_RXD */
+/* Description: RX data register. */
+
+/* Bits 7..0 : RX data from last transfer. */
+#define TWI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define TWI_RXD_RXD_Msk (0xFFUL << TWI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: TWI_TXD */
+/* Description: TX data register. */
+
+/* Bits 7..0 : TX data for next transfer. */
+#define TWI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define TWI_TXD_TXD_Msk (0xFFUL << TWI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: TWI_FREQUENCY */
+/* Description: Two-wire frequency. */
+
+/* Bits 31..0 : Two-wire master clock frequency. */
+#define TWI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define TWI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define TWI_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps. */
+#define TWI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps. */
+#define TWI_FREQUENCY_FREQUENCY_K400 (0x06680000UL) /*!< 400 kbps. */
+
+/* Register: TWI_ADDRESS */
+/* Description: Address used in the two-wire transfer. */
+
+/* Bits 6..0 : Two-wire address. */
+#define TWI_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */
+#define TWI_ADDRESS_ADDRESS_Msk (0x7FUL << TWI_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+
+/* Register: TWI_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TWI_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TWI_POWER_POWER_Msk (0x1UL << TWI_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TWI_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TWI_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: UART */
+/* Description: Universal Asynchronous Receiver/Transmitter. */
+
+/* Register: UART_SHORTS */
+/* Description: Shortcuts for UART. */
+
+/* Bit 4 : Shortcut between NCTS event and the STOPRX task. */
+#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */
+#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */
+#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Shortcut disabled. */
+#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between CTS event and the STARTRX task. */
+#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */
+#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */
+#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Shortcut disabled. */
+#define UART_SHORTS_CTS_STARTRX_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: UART_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 17 : Enable interrupt on RXTO event. */
+#define UART_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */
+#define UART_INTENSET_RXTO_Msk (0x1UL << UART_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */
+#define UART_INTENSET_RXTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_RXTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_RXTO_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 9 : Enable interrupt on ERROR event. */
+#define UART_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define UART_INTENSET_ERROR_Msk (0x1UL << UART_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define UART_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on TXRDY event. */
+#define UART_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */
+#define UART_INTENSET_TXDRDY_Msk (0x1UL << UART_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */
+#define UART_INTENSET_TXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_TXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_TXDRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on RXRDY event. */
+#define UART_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */
+#define UART_INTENSET_RXDRDY_Msk (0x1UL << UART_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */
+#define UART_INTENSET_RXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_RXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_RXDRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on NCTS event. */
+#define UART_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */
+#define UART_INTENSET_NCTS_Msk (0x1UL << UART_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */
+#define UART_INTENSET_NCTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_NCTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_NCTS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on CTS event. */
+#define UART_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */
+#define UART_INTENSET_CTS_Msk (0x1UL << UART_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */
+#define UART_INTENSET_CTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_CTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_CTS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: UART_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 17 : Disable interrupt on RXTO event. */
+#define UART_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */
+#define UART_INTENCLR_RXTO_Msk (0x1UL << UART_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */
+#define UART_INTENCLR_RXTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_RXTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_RXTO_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 9 : Disable interrupt on ERROR event. */
+#define UART_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define UART_INTENCLR_ERROR_Msk (0x1UL << UART_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define UART_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on TXRDY event. */
+#define UART_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */
+#define UART_INTENCLR_TXDRDY_Msk (0x1UL << UART_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */
+#define UART_INTENCLR_TXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_TXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on RXRDY event. */
+#define UART_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */
+#define UART_INTENCLR_RXDRDY_Msk (0x1UL << UART_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */
+#define UART_INTENCLR_RXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_RXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on NCTS event. */
+#define UART_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */
+#define UART_INTENCLR_NCTS_Msk (0x1UL << UART_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */
+#define UART_INTENCLR_NCTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_NCTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_NCTS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on CTS event. */
+#define UART_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */
+#define UART_INTENCLR_CTS_Msk (0x1UL << UART_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */
+#define UART_INTENCLR_CTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_CTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_CTS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: UART_ERRORSRC */
+/* Description: Error source. Write error field to 1 to clear error. */
+
+/* Bit 3 : The serial data input is '0' for longer than the length of a data frame. */
+#define UART_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */
+#define UART_ERRORSRC_BREAK_Msk (0x1UL << UART_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */
+#define UART_ERRORSRC_BREAK_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_BREAK_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_BREAK_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 2 : A valid stop bit is not detected on the serial data input after all bits in a character have been received. */
+#define UART_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */
+#define UART_ERRORSRC_FRAMING_Msk (0x1UL << UART_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */
+#define UART_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_FRAMING_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_FRAMING_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 1 : A character with bad parity is received. Only checked if HW parity control is enabled. */
+#define UART_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */
+#define UART_ERRORSRC_PARITY_Msk (0x1UL << UART_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */
+#define UART_ERRORSRC_PARITY_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_PARITY_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_PARITY_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 0 : A start bit is received while the previous data still lies in RXD. (Data loss). */
+#define UART_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
+#define UART_ERRORSRC_OVERRUN_Msk (0x1UL << UART_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
+#define UART_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_OVERRUN_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_OVERRUN_Clear (1UL) /*!< Clear error on write. */
+
+/* Register: UART_ENABLE */
+/* Description: Enable UART and acquire IOs. */
+
+/* Bits 2..0 : Enable or disable UART and acquire IOs. */
+#define UART_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define UART_ENABLE_ENABLE_Msk (0x7UL << UART_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define UART_ENABLE_ENABLE_Disabled (0x00UL) /*!< UART disabled. */
+#define UART_ENABLE_ENABLE_Enabled (0x04UL) /*!< UART enabled. */
+
+/* Register: UART_RXD */
+/* Description: RXD register. On read action the buffer pointer is displaced. Once read the character is consumed. If read when no character available, the UART will stop working. */
+
+/* Bits 7..0 : RX data from previous transfer. Double buffered. */
+#define UART_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define UART_RXD_RXD_Msk (0xFFUL << UART_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: UART_TXD */
+/* Description: TXD register. */
+
+/* Bits 7..0 : TX data for transfer. */
+#define UART_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define UART_TXD_TXD_Msk (0xFFUL << UART_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: UART_BAUDRATE */
+/* Description: UART Baudrate. */
+
+/* Bits 31..0 : UART baudrate. */
+#define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */
+#define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */
+#define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBEDFA4UL) /*!< 921600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1M baud. */
+
+/* Register: UART_CONFIG */
+/* Description: Configuration of parity and hardware flow control register. */
+
+/* Bits 3..1 : Include parity bit. */
+#define UART_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */
+#define UART_CONFIG_PARITY_Msk (0x7UL << UART_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */
+#define UART_CONFIG_PARITY_Excluded (0UL) /*!< Parity bit excluded. */
+#define UART_CONFIG_PARITY_Included (7UL) /*!< Parity bit included. */
+
+/* Bit 0 : Hardware flow control. */
+#define UART_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */
+#define UART_CONFIG_HWFC_Msk (0x1UL << UART_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */
+#define UART_CONFIG_HWFC_Disabled (0UL) /*!< Hardware flow control disabled. */
+#define UART_CONFIG_HWFC_Enabled (1UL) /*!< Hardware flow control enabled. */
+
+/* Register: UART_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define UART_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define UART_POWER_POWER_Msk (0x1UL << UART_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define UART_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define UART_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: UICR */
+/* Description: User Information Configuration. */
+
+/* Register: UICR_RBPCONF */
+/* Description: Readback protection configuration. */
+
+/* Bits 15..8 : Readback protect all code in the device. */
+#define UICR_RBPCONF_PALL_Pos (8UL) /*!< Position of PALL field. */
+#define UICR_RBPCONF_PALL_Msk (0xFFUL << UICR_RBPCONF_PALL_Pos) /*!< Bit mask of PALL field. */
+#define UICR_RBPCONF_PALL_Disabled (0xFFUL) /*!< Disabled. */
+#define UICR_RBPCONF_PALL_Enabled (0x00UL) /*!< Enabled. */
+
+/* Bits 7..0 : Readback protect region 0. Will be ignored if pre-programmed factory code is present on the chip. */
+#define UICR_RBPCONF_PR0_Pos (0UL) /*!< Position of PR0 field. */
+#define UICR_RBPCONF_PR0_Msk (0xFFUL << UICR_RBPCONF_PR0_Pos) /*!< Bit mask of PR0 field. */
+#define UICR_RBPCONF_PR0_Disabled (0xFFUL) /*!< Disabled. */
+#define UICR_RBPCONF_PR0_Enabled (0x00UL) /*!< Enabled. */
+
+/* Register: UICR_XTALFREQ */
+/* Description: Reset value for CLOCK XTALFREQ register. */
+
+/* Bits 7..0 : Reset value for CLOCK XTALFREQ register. */
+#define UICR_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
+#define UICR_XTALFREQ_XTALFREQ_Msk (0xFFUL << UICR_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
+#define UICR_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz Xtal is used. */
+#define UICR_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz Xtal is used. */
+
+/* Register: UICR_FWID */
+/* Description: Firmware ID. */
+
+/* Bits 15..0 : Identification number for the firmware loaded into the chip. */
+#define UICR_FWID_FWID_Pos (0UL) /*!< Position of FWID field. */
+#define UICR_FWID_FWID_Msk (0xFFFFUL << UICR_FWID_FWID_Pos) /*!< Bit mask of FWID field. */
+
+
+/* Peripheral: WDT */
+/* Description: Watchdog Timer. */
+
+/* Register: WDT_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on TIMEOUT event. */
+#define WDT_INTENSET_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */
+#define WDT_INTENSET_TIMEOUT_Msk (0x1UL << WDT_INTENSET_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */
+#define WDT_INTENSET_TIMEOUT_Disabled (0UL) /*!< Interrupt disabled. */
+#define WDT_INTENSET_TIMEOUT_Enabled (1UL) /*!< Interrupt enabled. */
+#define WDT_INTENSET_TIMEOUT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: WDT_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on TIMEOUT event. */
+#define WDT_INTENCLR_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */
+#define WDT_INTENCLR_TIMEOUT_Msk (0x1UL << WDT_INTENCLR_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */
+#define WDT_INTENCLR_TIMEOUT_Disabled (0UL) /*!< Interrupt disabled. */
+#define WDT_INTENCLR_TIMEOUT_Enabled (1UL) /*!< Interrupt enabled. */
+#define WDT_INTENCLR_TIMEOUT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: WDT_RUNSTATUS */
+/* Description: Watchdog running status. */
+
+/* Bit 0 : Watchdog running status. */
+#define WDT_RUNSTATUS_RUNSTATUS_Pos (0UL) /*!< Position of RUNSTATUS field. */
+#define WDT_RUNSTATUS_RUNSTATUS_Msk (0x1UL << WDT_RUNSTATUS_RUNSTATUS_Pos) /*!< Bit mask of RUNSTATUS field. */
+#define WDT_RUNSTATUS_RUNSTATUS_NotRunning (0UL) /*!< Watchdog timer is not running. */
+#define WDT_RUNSTATUS_RUNSTATUS_Running (1UL) /*!< Watchdog timer is running. */
+
+/* Register: WDT_REQSTATUS */
+/* Description: Request status. */
+
+/* Bit 7 : Request status for RR[7]. */
+#define WDT_REQSTATUS_RR7_Pos (7UL) /*!< Position of RR7 field. */
+#define WDT_REQSTATUS_RR7_Msk (0x1UL << WDT_REQSTATUS_RR7_Pos) /*!< Bit mask of RR7 field. */
+#define WDT_REQSTATUS_RR7_DisabledOrRequested (0UL) /*!< RR[7] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR7_EnabledAndUnrequested (1UL) /*!< RR[7] register is enabled and has not jet requested. */
+
+/* Bit 6 : Request status for RR[6]. */
+#define WDT_REQSTATUS_RR6_Pos (6UL) /*!< Position of RR6 field. */
+#define WDT_REQSTATUS_RR6_Msk (0x1UL << WDT_REQSTATUS_RR6_Pos) /*!< Bit mask of RR6 field. */
+#define WDT_REQSTATUS_RR6_DisabledOrRequested (0UL) /*!< RR[6] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR6_EnabledAndUnrequested (1UL) /*!< RR[6] register is enabled and has not jet requested. */
+
+/* Bit 5 : Request status for RR[5]. */
+#define WDT_REQSTATUS_RR5_Pos (5UL) /*!< Position of RR5 field. */
+#define WDT_REQSTATUS_RR5_Msk (0x1UL << WDT_REQSTATUS_RR5_Pos) /*!< Bit mask of RR5 field. */
+#define WDT_REQSTATUS_RR5_DisabledOrRequested (0UL) /*!< RR[5] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR5_EnabledAndUnrequested (1UL) /*!< RR[5] register is enabled and has not jet requested. */
+
+/* Bit 4 : Request status for RR[4]. */
+#define WDT_REQSTATUS_RR4_Pos (4UL) /*!< Position of RR4 field. */
+#define WDT_REQSTATUS_RR4_Msk (0x1UL << WDT_REQSTATUS_RR4_Pos) /*!< Bit mask of RR4 field. */
+#define WDT_REQSTATUS_RR4_DisabledOrRequested (0UL) /*!< RR[4] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR4_EnabledAndUnrequested (1UL) /*!< RR[4] register is enabled and has not jet requested. */
+
+/* Bit 3 : Request status for RR[3]. */
+#define WDT_REQSTATUS_RR3_Pos (3UL) /*!< Position of RR3 field. */
+#define WDT_REQSTATUS_RR3_Msk (0x1UL << WDT_REQSTATUS_RR3_Pos) /*!< Bit mask of RR3 field. */
+#define WDT_REQSTATUS_RR3_DisabledOrRequested (0UL) /*!< RR[3] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR3_EnabledAndUnrequested (1UL) /*!< RR[3] register is enabled and has not jet requested. */
+
+/* Bit 2 : Request status for RR[2]. */
+#define WDT_REQSTATUS_RR2_Pos (2UL) /*!< Position of RR2 field. */
+#define WDT_REQSTATUS_RR2_Msk (0x1UL << WDT_REQSTATUS_RR2_Pos) /*!< Bit mask of RR2 field. */
+#define WDT_REQSTATUS_RR2_DisabledOrRequested (0UL) /*!< RR[2] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR2_EnabledAndUnrequested (1UL) /*!< RR[2] register is enabled and has not jet requested. */
+
+/* Bit 1 : Request status for RR[1]. */
+#define WDT_REQSTATUS_RR1_Pos (1UL) /*!< Position of RR1 field. */
+#define WDT_REQSTATUS_RR1_Msk (0x1UL << WDT_REQSTATUS_RR1_Pos) /*!< Bit mask of RR1 field. */
+#define WDT_REQSTATUS_RR1_DisabledOrRequested (0UL) /*!< RR[1] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR1_EnabledAndUnrequested (1UL) /*!< RR[1] register is enabled and has not jet requested. */
+
+/* Bit 0 : Request status for RR[0]. */
+#define WDT_REQSTATUS_RR0_Pos (0UL) /*!< Position of RR0 field. */
+#define WDT_REQSTATUS_RR0_Msk (0x1UL << WDT_REQSTATUS_RR0_Pos) /*!< Bit mask of RR0 field. */
+#define WDT_REQSTATUS_RR0_DisabledOrRequested (0UL) /*!< RR[0] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR0_EnabledAndUnrequested (1UL) /*!< RR[0] register is enabled and has not jet requested. */
+
+/* Register: WDT_RREN */
+/* Description: Reload request enable. */
+
+/* Bit 7 : Enable or disable RR[7] register. */
+#define WDT_RREN_RR7_Pos (7UL) /*!< Position of RR7 field. */
+#define WDT_RREN_RR7_Msk (0x1UL << WDT_RREN_RR7_Pos) /*!< Bit mask of RR7 field. */
+#define WDT_RREN_RR7_Disabled (0UL) /*!< RR[7] register is disabled. */
+#define WDT_RREN_RR7_Enabled (1UL) /*!< RR[7] register is enabled. */
+
+/* Bit 6 : Enable or disable RR[6] register. */
+#define WDT_RREN_RR6_Pos (6UL) /*!< Position of RR6 field. */
+#define WDT_RREN_RR6_Msk (0x1UL << WDT_RREN_RR6_Pos) /*!< Bit mask of RR6 field. */
+#define WDT_RREN_RR6_Disabled (0UL) /*!< RR[6] register is disabled. */
+#define WDT_RREN_RR6_Enabled (1UL) /*!< RR[6] register is enabled. */
+
+/* Bit 5 : Enable or disable RR[5] register. */
+#define WDT_RREN_RR5_Pos (5UL) /*!< Position of RR5 field. */
+#define WDT_RREN_RR5_Msk (0x1UL << WDT_RREN_RR5_Pos) /*!< Bit mask of RR5 field. */
+#define WDT_RREN_RR5_Disabled (0UL) /*!< RR[5] register is disabled. */
+#define WDT_RREN_RR5_Enabled (1UL) /*!< RR[5] register is enabled. */
+
+/* Bit 4 : Enable or disable RR[4] register. */
+#define WDT_RREN_RR4_Pos (4UL) /*!< Position of RR4 field. */
+#define WDT_RREN_RR4_Msk (0x1UL << WDT_RREN_RR4_Pos) /*!< Bit mask of RR4 field. */
+#define WDT_RREN_RR4_Disabled (0UL) /*!< RR[4] register is disabled. */
+#define WDT_RREN_RR4_Enabled (1UL) /*!< RR[4] register is enabled. */
+
+/* Bit 3 : Enable or disable RR[3] register. */
+#define WDT_RREN_RR3_Pos (3UL) /*!< Position of RR3 field. */
+#define WDT_RREN_RR3_Msk (0x1UL << WDT_RREN_RR3_Pos) /*!< Bit mask of RR3 field. */
+#define WDT_RREN_RR3_Disabled (0UL) /*!< RR[3] register is disabled. */
+#define WDT_RREN_RR3_Enabled (1UL) /*!< RR[3] register is enabled. */
+
+/* Bit 2 : Enable or disable RR[2] register. */
+#define WDT_RREN_RR2_Pos (2UL) /*!< Position of RR2 field. */
+#define WDT_RREN_RR2_Msk (0x1UL << WDT_RREN_RR2_Pos) /*!< Bit mask of RR2 field. */
+#define WDT_RREN_RR2_Disabled (0UL) /*!< RR[2] register is disabled. */
+#define WDT_RREN_RR2_Enabled (1UL) /*!< RR[2] register is enabled. */
+
+/* Bit 1 : Enable or disable RR[1] register. */
+#define WDT_RREN_RR1_Pos (1UL) /*!< Position of RR1 field. */
+#define WDT_RREN_RR1_Msk (0x1UL << WDT_RREN_RR1_Pos) /*!< Bit mask of RR1 field. */
+#define WDT_RREN_RR1_Disabled (0UL) /*!< RR[1] register is disabled. */
+#define WDT_RREN_RR1_Enabled (1UL) /*!< RR[1] register is enabled. */
+
+/* Bit 0 : Enable or disable RR[0] register. */
+#define WDT_RREN_RR0_Pos (0UL) /*!< Position of RR0 field. */
+#define WDT_RREN_RR0_Msk (0x1UL << WDT_RREN_RR0_Pos) /*!< Bit mask of RR0 field. */
+#define WDT_RREN_RR0_Disabled (0UL) /*!< RR[0] register is disabled. */
+#define WDT_RREN_RR0_Enabled (1UL) /*!< RR[0] register is enabled. */
+
+/* Register: WDT_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 3 : Configure the watchdog to pause or not while the CPU is halted by the debugger. */
+#define WDT_CONFIG_HALT_Pos (3UL) /*!< Position of HALT field. */
+#define WDT_CONFIG_HALT_Msk (0x1UL << WDT_CONFIG_HALT_Pos) /*!< Bit mask of HALT field. */
+#define WDT_CONFIG_HALT_Pause (0UL) /*!< Pause watchdog while the CPU is halted by the debugger. */
+#define WDT_CONFIG_HALT_Run (1UL) /*!< Do not pause watchdog while the CPU is halted by the debugger. */
+
+/* Bit 0 : Configure the watchdog to pause or not while the CPU is sleeping. */
+#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */
+#define WDT_CONFIG_SLEEP_Msk (0x1UL << WDT_CONFIG_SLEEP_Pos) /*!< Bit mask of SLEEP field. */
+#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause watchdog while the CPU is asleep. */
+#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Do not pause watchdog while the CPU is asleep. */
+
+/* Register: WDT_RR */
+/* Description: Reload requests registers. */
+
+/* Bits 31..0 : Reload register. */
+#define WDT_RR_RR_Pos (0UL) /*!< Position of RR field. */
+#define WDT_RR_RR_Msk (0xFFFFFFFFUL << WDT_RR_RR_Pos) /*!< Bit mask of RR field. */
+#define WDT_RR_RR_Reload (0x6E524635UL) /*!< Value to request a reload of the watchdog timer. */
+
+/* Register: WDT_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define WDT_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define WDT_POWER_POWER_Msk (0x1UL << WDT_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define WDT_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define WDT_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/*lint --flb "Leave library region" */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/nrf_delay.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,74 @@
+#ifndef _NRF_DELAY_H
+#define _NRF_DELAY_H
+
+// #include "nrf.h"
+
+/*lint --e{438, 522} "Variable not used" "Function lacks side-effects" */
+#if defined ( __CC_ARM   )
+static __ASM void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
+{
+loop
+        SUBS    R0, R0, #1
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        BNE    loop
+        BX     LR
+}
+#elif defined ( __ICCARM__ )
+static void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
+{
+__ASM (
+"loop:\n\t"
+       " SUBS R0, R0, #1\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " BNE loop\n\t");
+}
+#elif defined   (  __GNUC__  )
+__INLINE static void nrf_delay_us(uint32_t volatile number_of_us)
+{
+    do 
+    {
+    __ASM volatile (
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+        "NOP\n\t"
+    );
+    } while (--number_of_us);
+}
+#endif
+
+void nrf_delay_ms(uint32_t volatile number_of_ms);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TARGET_NRF51_MICROBIT/system_nrf51.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,68 @@
+/* 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:
+ *
+ *   * 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 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (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 SYSTEM_NRF51_H
+#define SYSTEM_NRF51_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_NRF51_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Ticker.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,127 @@
+/* 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_TICKER_H
+#define MBED_TICKER_H
+
+#include "TimerEvent.h"
+#include "FunctionPointer.h"
+
+namespace mbed {
+
+/** A Ticker is used to call a function at a recurring interval
+ *
+ *  You can use as many seperate Ticker objects as you require.
+ *
+ * Example:
+ * @code
+ * // Toggle the blinking led after 5 seconds
+ *
+ * #include "mbed.h"
+ *
+ * Ticker timer;
+ * DigitalOut led1(LED1);
+ * DigitalOut led2(LED2);
+ *
+ * int flip = 0;
+ *
+ * void attime() {
+ *     flip = !flip;
+ * }
+ *
+ * int main() {
+ *     timer.attach(&attime, 5);
+ *     while(1) {
+ *         if(flip == 0) {
+ *             led1 = !led1;
+ *         } else {
+ *             led2 = !led2;
+ *         }
+ *         wait(0.2);
+ *     }
+ * }
+ * @endcode
+ */
+class Ticker : public TimerEvent {
+
+public:
+    Ticker() : TimerEvent() {
+    }
+
+    Ticker(const ticker_data_t *data) : TimerEvent(data) {
+    }
+
+    /** Attach a function to be called by the Ticker, specifiying the interval in seconds
+     *
+     *  @param fptr pointer to the function to be called
+     *  @param t the time between calls in seconds
+     */
+    void attach(void (*fptr)(void), float t) {
+        attach_us(fptr, t * 1000000.0f);
+    }
+
+    /** Attach a member function to be called by the Ticker, specifiying the interval in seconds
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *  @param t the time between calls in seconds
+     */
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void), float t) {
+        attach_us(tptr, mptr, t * 1000000.0f);
+    }
+
+    /** Attach a function to be called by the Ticker, specifiying the interval in micro-seconds
+     *
+     *  @param fptr pointer to the function to be called
+     *  @param t the time between calls in micro-seconds
+     */
+    void attach_us(void (*fptr)(void), timestamp_t t) {
+        _function.attach(fptr);
+        setup(t);
+    }
+
+    /** Attach a member function to be called by the Ticker, specifiying the interval in micro-seconds
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *  @param t the time between calls in micro-seconds
+     */
+    template<typename T>
+    void attach_us(T* tptr, void (T::*mptr)(void), timestamp_t t) {
+        _function.attach(tptr, mptr);
+        setup(t);
+    }
+
+    virtual ~Ticker() {
+        detach();
+    }
+
+    /** Detach the function
+     */
+    void detach();
+
+protected:
+    void setup(timestamp_t t);
+    virtual void handler();
+
+protected:
+    timestamp_t     _delay;     /**< Time delay (in microseconds) for re-setting the multi-shot callback. */
+    FunctionPointer _function;  /**< Callback. */
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Timeout.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,59 @@
+/* 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_TIMEOUT_H
+#define MBED_TIMEOUT_H
+
+#include "Ticker.h"
+
+namespace mbed {
+
+/** A Timeout is used to call a function at a point in the future
+ *
+ * You can use as many seperate Timeout objects as you require.
+ *
+ * Example:
+ * @code
+ * // Blink until timeout.
+ *
+ * #include "mbed.h"
+ *
+ * Timeout timeout;
+ * DigitalOut led(LED1);
+ *
+ * int on = 1;
+ *
+ * void attimeout() {
+ *     on = 0;
+ * }
+ *
+ * int main() {
+ *     timeout.attach(&attimeout, 5);
+ *     while(on) {
+ *         led = !led;
+ *         wait(0.2);
+ *     }
+ * }
+ * @endcode
+ */
+class Timeout : public Ticker {
+
+protected:
+    virtual void handler();
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Timer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,91 @@
+/* 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_TIMER_H
+#define MBED_TIMER_H
+
+#include "platform.h"
+#include "ticker_api.h"
+
+namespace mbed {
+
+/** A general purpose timer
+ *
+ * Example:
+ * @code
+ * // Count the time to toggle a LED
+ *
+ * #include "mbed.h"
+ *
+ * Timer timer;
+ * DigitalOut led(LED1);
+ * int begin, end;
+ *
+ * int main() {
+ *     timer.start();
+ *     begin = timer.read_us();
+ *     led = !led;
+ *     end = timer.read_us();
+ *     printf("Toggle the led takes %d us", end - begin);
+ * }
+ * @endcode
+ */
+class Timer {
+
+public:
+    Timer();
+    Timer(const ticker_data_t *data);
+
+    /** Start the timer
+     */
+    void start();
+
+    /** Stop the timer
+     */
+    void stop();
+
+    /** Reset the timer to 0.
+     *
+     * If it was already counting, it will continue
+     */
+    void reset();
+
+    /** Get the time passed in seconds
+     */
+    float read();
+
+    /** Get the time passed in mili-seconds
+     */
+    int read_ms();
+
+    /** Get the time passed in micro-seconds
+     */
+    int read_us();
+
+#ifdef MBED_OPERATORS
+    operator float();
+#endif
+
+protected:
+    int slicetime();
+    int _running;          // whether the timer is running
+    unsigned int _start;   // the start time of the latest slice
+    int _time;             // any accumulated time from previous slices
+    const ticker_data_t *_ticker_data;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/TimerEvent.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,56 @@
+/* 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_TIMEREVENT_H
+#define MBED_TIMEREVENT_H
+
+#include "ticker_api.h"
+#include "us_ticker_api.h"
+
+namespace mbed {
+
+/** Base abstraction for timer interrupts
+*/
+class TimerEvent {
+public:
+    TimerEvent();
+    TimerEvent(const ticker_data_t *data);
+
+    /** The handler registered with the underlying timer interrupt
+     */
+    static void irq(uint32_t id);
+
+    /** Destruction removes it...
+     */
+    virtual ~TimerEvent();
+
+protected:
+    // The handler called to service the timer event of the derived class
+    virtual void handler() = 0;
+
+    // insert in to linked list
+    void insert(timestamp_t timestamp);
+
+    // remove from linked list, if in it
+    void remove();
+
+    ticker_event_t event;
+
+    const ticker_data_t *_ticker_data;
+};
+
+} // namespace mbed
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/Transaction.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,73 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_TRANSACTION_H
+#define MBED_TRANSACTION_H
+
+#include "platform.h"
+#include "FunctionPointer.h"
+
+namespace mbed {
+
+/** Transaction structure
+ */
+typedef struct {
+    void *tx_buffer;           /**< Tx buffer */
+    size_t tx_length;          /**< Length of Tx buffer*/
+    void *rx_buffer;           /**< Rx buffer */
+    size_t rx_length;          /**< Length of Rx buffer */
+    uint32_t event;            /**< Event for a transaction */
+    event_callback_t callback; /**< User's callback */
+    uint8_t width;             /**< Buffer's word width (8, 16, 32, 64) */
+} transaction_t;
+
+/** Transaction class defines a transaction.
+ */
+template<typename Class>
+class Transaction {
+public:
+    Transaction(Class *tpointer, const transaction_t& transaction) : _obj(tpointer), _data(transaction) {
+    }
+
+    Transaction() : _obj(), _data() {
+    }
+
+    ~Transaction() {
+    }
+
+    /** Get object's instance for the transaction
+     *
+     * @return The object which was stored
+     */
+    Class* get_object() {
+        return _obj;
+    }
+
+    /** Get the transaction
+     *
+     * @return The transaction which was stored
+     */
+    transaction_t* get_transaction() {
+        return &_data;
+    }
+
+private:
+    Class* _obj;
+    transaction_t _data;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/analogin_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,39 @@
+/* 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_ANALOGIN_API_H
+#define MBED_ANALOGIN_API_H
+
+#include "device.h"
+
+#if DEVICE_ANALOGIN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct analogin_s analogin_t;
+
+void     analogin_init    (analogin_t *obj, PinName pin);
+float    analogin_read    (analogin_t *obj);
+uint16_t analogin_read_u16(analogin_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/analogout_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/* 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_ANALOGOUT_API_H
+#define MBED_ANALOGOUT_API_H
+
+#include "device.h"
+
+#if DEVICE_ANALOGOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct dac_s dac_t;
+
+void     analogout_init     (dac_t *obj, PinName pin);
+void     analogout_free     (dac_t *obj);
+void     analogout_write    (dac_t *obj, float value);
+void     analogout_write_u16(dac_t *obj, uint16_t value);
+float    analogout_read     (dac_t *obj);
+uint16_t analogout_read_u16 (dac_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/buffer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,30 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2014-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_BUFFER_H
+#define MBED_BUFFER_H
+
+#include <stddef.h>
+
+/** Generic buffer structure
+ */
+typedef struct buffer_s {
+    void    *buffer; /**< the pointer to a buffer */
+    size_t   length; /**< the buffer length */
+    size_t   pos;    /**< actual buffer position */
+    uint8_t  width;  /**< The buffer unit width (8, 16, 32, 64), used for proper *buffer casting */
+} buffer_t;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/can_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,80 @@
+/* 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_CAN_API_H
+#define MBED_CAN_API_H
+
+#include "device.h"
+
+#if DEVICE_CAN
+
+#include "PinNames.h"
+#include "PeripheralNames.h"
+#include "can_helper.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    IRQ_RX,
+    IRQ_TX,
+    IRQ_ERROR,
+    IRQ_OVERRUN,
+    IRQ_WAKEUP,
+    IRQ_PASSIVE,
+    IRQ_ARB,
+    IRQ_BUS,
+    IRQ_READY
+} CanIrqType;
+
+
+typedef enum {
+    MODE_RESET,
+    MODE_NORMAL,
+    MODE_SILENT,
+    MODE_TEST_LOCAL,
+    MODE_TEST_GLOBAL,
+    MODE_TEST_SILENT
+} CanMode;
+
+typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
+
+typedef struct can_s can_t;
+
+void          can_init     (can_t *obj, PinName rd, PinName td);
+void          can_free     (can_t *obj);
+int           can_frequency(can_t *obj, int hz);
+
+void          can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id);
+void          can_irq_free (can_t *obj);
+void          can_irq_set  (can_t *obj, CanIrqType irq, uint32_t enable);
+
+int           can_write    (can_t *obj, CAN_Message, int cc);
+int           can_read     (can_t *obj, CAN_Message *msg, int handle);
+int           can_mode     (can_t *obj, CanMode mode);
+int           can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle);
+void          can_reset    (can_t *obj);
+unsigned char can_rderror  (can_t *obj);
+unsigned char can_tderror  (can_t *obj);
+void          can_monitor  (can_t *obj, int silent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif    // MBED_CAN_API_H
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/can_helper.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,53 @@
+/* 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_CAN_HELPER_H
+#define MBED_CAN_HELPER_H
+
+#if DEVICE_CAN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum CANFormat {
+    CANStandard = 0,
+    CANExtended = 1,
+    CANAny = 2
+};
+typedef enum CANFormat CANFormat;
+
+enum CANType {
+    CANData   = 0,
+    CANRemote = 1
+};
+typedef enum CANType CANType;
+
+struct CAN_Message {
+    unsigned int   id;                 // 29 bit identifier
+    unsigned char  data[8];            // Data field
+    unsigned char  len;                // Length of data field in bytes
+    CANFormat      format;             // 0 - STANDARD, 1- EXTENDED IDENTIFIER
+    CANType        type;               // 0 - DATA FRAME, 1 - REMOTE FRAME
+};
+typedef struct CAN_Message CAN_Message;
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
+#endif // MBED_CAN_HELPER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/dma_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,45 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2014-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_DMA_API_H
+#define MBED_DMA_API_H
+
+#include <stdint.h>
+
+#define DMA_ERROR_OUT_OF_CHANNELS (-1)
+
+typedef enum {
+    DMA_USAGE_NEVER,
+    DMA_USAGE_OPPORTUNISTIC,
+    DMA_USAGE_ALWAYS,
+    DMA_USAGE_TEMPORARY_ALLOCATED,
+    DMA_USAGE_ALLOCATED
+} DMAUsage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void dma_init(void);
+
+int dma_channel_allocate(uint32_t capabilities);
+
+int dma_channel_free(int channelid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/ethernet_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,63 @@
+/* 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_ETHERNET_API_H
+#define MBED_ETHERNET_API_H
+
+#include "device.h"
+
+#if DEVICE_ETHERNET
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Connection constants
+
+int ethernet_init(void);
+void ethernet_free(void);
+
+// write size bytes from data to ethernet buffer
+// return num bytes written
+// or -1 if size is too big
+int ethernet_write(const char *data, int size);
+
+// send ethernet write buffer, returning the packet size sent
+int ethernet_send(void);
+
+// recieve from ethernet buffer, returning packet size, or 0 if no packet
+int ethernet_receive(void);
+
+// read size bytes in to data, return actual num bytes read (0..size)
+// if data == NULL, throw the bytes away
+int ethernet_read(char *data, int size);
+
+// get the ethernet address
+void ethernet_address(char *mac);
+
+// see if the link is up
+int ethernet_link(void);
+
+// force link settings
+void ethernet_set_link(int speed, int duplex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/gpio_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,57 @@
+/* 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_GPIO_API_H
+#define MBED_GPIO_API_H
+
+#include "device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Set the given pin as GPIO
+ * @param pin The pin to be set as GPIO
+ * @return The GPIO port mask for this pin
+ **/
+uint32_t gpio_set(PinName pin);
+
+/* Checks if gpio object is connected (pin was not initialized with NC)
+ * @param pin The pin to be set as GPIO
+ * @return 0 if port is initialized with NC
+ **/
+int gpio_is_connected(const gpio_t *obj);
+
+/* GPIO object */
+void gpio_init(gpio_t *obj, PinName pin);
+
+void gpio_mode (gpio_t *obj, PinMode mode);
+void gpio_dir  (gpio_t *obj, PinDirection direction);
+
+void gpio_write(gpio_t *obj, int value);
+int  gpio_read (gpio_t *obj);
+
+// the following set of functions are generic and are implemented in the common gpio.c file
+void gpio_init_in(gpio_t* gpio, PinName pin);
+void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode);
+void gpio_init_out(gpio_t* gpio, PinName pin);
+void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value);
+void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/gpio_irq_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,49 @@
+/* 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_GPIO_IRQ_API_H
+#define MBED_GPIO_IRQ_API_H
+
+#include "device.h"
+
+#if DEVICE_INTERRUPTIN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    IRQ_NONE,
+    IRQ_RISE,
+    IRQ_FALL
+} gpio_irq_event;
+
+typedef struct gpio_irq_s gpio_irq_t;
+
+typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
+
+int  gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id);
+void gpio_irq_free(gpio_irq_t *obj);
+void gpio_irq_set (gpio_irq_t *obj, gpio_irq_event event, uint32_t enable);
+void gpio_irq_enable(gpio_irq_t *obj);
+void gpio_irq_disable(gpio_irq_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/i2c_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,223 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_I2C_API_H
+#define MBED_I2C_API_H
+
+#include "device.h"
+#include "buffer.h"
+
+#if DEVICE_I2C
+
+/**
+ * @defgroup I2CEvents I2C Events Macros
+ *
+ * @{
+ */
+#define I2C_EVENT_ERROR               (1 << 1)
+#define I2C_EVENT_ERROR_NO_SLAVE      (1 << 2)
+#define I2C_EVENT_TRANSFER_COMPLETE   (1 << 3)
+#define I2C_EVENT_TRANSFER_EARLY_NACK (1 << 4)
+#define I2C_EVENT_ALL                 (I2C_EVENT_ERROR |  I2C_EVENT_TRANSFER_COMPLETE | I2C_EVENT_ERROR_NO_SLAVE | I2C_EVENT_TRANSFER_EARLY_NACK)
+
+/**@}*/
+
+#if DEVICE_I2C_ASYNCH
+/** Asynch i2c hal structure
+ */
+typedef struct {
+    struct i2c_s    i2c;     /**< Target specific i2c structure */
+    struct buffer_s tx_buff; /**< Tx buffer */
+    struct buffer_s rx_buff; /**< Rx buffer */
+} i2c_t;
+
+#else
+/** Non-asynch i2c hal structure
+ */
+typedef struct i2c_s i2c_t;
+
+#endif
+
+enum {
+  I2C_ERROR_NO_SLAVE = -1,
+  I2C_ERROR_BUS_BUSY = -2
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup GeneralI2C I2C Configuration Functions
+ * @{
+ */
+
+/** Initialize the I2C peripheral. It sets the default parameters for I2C
+ *  peripheral, and configure its specifieds pins.
+ *  @param obj  The i2c object
+ *  @param sda  The sda pin
+ *  @param scl  The scl pin
+ */
+void i2c_init(i2c_t *obj, PinName sda, PinName scl);
+
+/** Configure the I2C frequency.
+ *  @param obj The i2c object
+ *  @param hz  Frequency in Hz
+ */
+void i2c_frequency(i2c_t *obj, int hz);
+
+/** Send START command.
+ *  @param obj The i2c object
+ */
+int  i2c_start(i2c_t *obj);
+
+/** Send STOP command.
+ *  @param obj The i2c object
+ */
+int  i2c_stop(i2c_t *obj);
+
+/** Blocking reading data.
+ *  @param obj     The i2c object
+ *  @param address 7-bit address (last bit is 1)
+ *  @param data    The buffer for receiving
+ *  @param length  Number of bytes to read
+ *  @param stop    Stop to be generated after the transfer is done
+ *  @return Number of read bytes
+ */
+int  i2c_read(i2c_t *obj, int address, char *data, int length, int stop);
+
+/** Blocking sending data.
+ *  @param obj     The i2c object
+ *  @param address 7-bit address (last bit is 0)
+ *  @param data    The buffer for sending
+ *  @param length  Number of bytes to wrte
+ *  @param stop    Stop to be generated after the transfer is done
+ *  @return Number of written bytes
+ */
+int  i2c_write(i2c_t *obj, int address, const char *data, int length, int stop);
+
+/** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop().
+ *  @param obj The i2c object
+ */
+void i2c_reset(i2c_t *obj);
+
+/** Read one byte.
+ *  @param obj The i2c object
+ *  @param last Acknoledge
+ *  @return The read byte
+ */
+int  i2c_byte_read(i2c_t *obj, int last);
+
+/** Write one byte.
+ *  @param obj The i2c object
+ *  @param data Byte to be written
+ *  @return 1 if NAK was received, 0 if ACK was received, 2 for timeout.
+ */
+int  i2c_byte_write(i2c_t *obj, int data);
+
+/**@}*/
+
+#if DEVICE_I2CSLAVE
+
+/**
+ * \defgroup SynchI2C Synchronous I2C Hardware Abstraction Layer for slave
+ * @{
+ */
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+void i2c_slave_mode(i2c_t *obj, int enable_slave);
+
+/** Check to see if the I2C slave has been addressed.
+ *  @param obj The I2C object
+ *  @return The status - 1 - read addresses, 2 - write to all slaves,
+ *         3 write addressed, 0 - the slave has not been addressed
+ */
+int  i2c_slave_receive(i2c_t *obj);
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+int  i2c_slave_read(i2c_t *obj, char *data, int length);
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+int  i2c_slave_write(i2c_t *obj, const char *data, int length);
+
+/** Configure I2C address.
+ *  @param obj     The I2C object
+ *  @param idx     Currently not used
+ *  @param address The address to be set
+ *  @param mask    Currently not used
+ */
+void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask);
+
+#endif
+
+/**@}*/
+
+#if DEVICE_I2C_ASYNCH
+
+/**
+ * \defgroup AsynchI2C Asynchronous I2C Hardware Abstraction Layer
+ * @{
+ */
+
+/** Start i2c asynchronous transfer.
+ *  @param obj       The I2C object
+ *  @param tx        The buffer to send
+ *  @param tx_length The number of words to transmit
+ *  @param rx        The buffer to receive
+ *  @param rx_length The number of words to receive
+ *  @param address   The address to be set - 7bit or 9 bit
+ *  @param stop      If true, stop will be generated after the transfer is done
+ *  @param handler   The I2C IRQ handler to be set
+ *  @param hint      DMA hint usage
+ */
+void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** The asynchronous IRQ handler
+ *  @param obj The I2C object which holds the transfer information
+ *  @return event flags if a transfer termination condition was met or 0 otherwise.
+ */
+uint32_t i2c_irq_handler_asynch(i2c_t *obj);
+
+/** Attempts to determine if I2C peripheral is already in use.
+ *  @param obj The I2C object
+ *  @return non-zero if the I2C module is active or zero if it is not
+ */
+uint8_t i2c_active(i2c_t *obj);
+
+/** Abort ongoing asynchronous transaction.
+ *  @param obj The I2C object
+ */
+void i2c_abort_asynch(i2c_t *obj);
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/lp_ticker_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,82 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_LPTICKER_API_H
+#define MBED_LPTICKER_API_H
+
+#include "device.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+#include "ticker_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup LpTicker Low Power Ticker Functions
+ * @{
+ */
+
+/** Get low power ticker's data
+ *
+ * @return The low power ticker data
+ */
+const ticker_data_t* get_lp_ticker_data(void);
+
+/** The wrapper for ticker_irq_handler, to pass lp ticker's data
+ *
+ */
+void lp_ticker_irq_handler(void);
+
+/* HAL lp ticker */
+
+/** Initialize the low power ticker
+ *
+ */
+void lp_ticker_init(void);
+
+/** Read the current counter
+ *
+ * @return The current timer's counter value in microseconds
+ */
+uint32_t lp_ticker_read(void);
+
+/** Set interrupt for specified timestamp
+ *
+ * @param timestamp The time in microseconds to be set
+ */
+void lp_ticker_set_interrupt(timestamp_t timestamp);
+
+/** Disable low power ticker interrupt
+ *
+ */
+void lp_ticker_disable_interrupt(void);
+
+/** Clear the low power ticker interrupt
+ *
+ */
+void lp_ticker_clear_interrupt(void);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/mbed.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,69 @@
+/* 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_H
+#define MBED_H
+
+#define MBED_LIBRARY_VERSION 103
+
+#include "platform.h"
+
+// Useful C libraries
+#include <math.h>
+#include <time.h>
+
+// mbed Debug libraries
+#include "mbed_error.h"
+#include "mbed_interface.h"
+
+// mbed Peripheral components
+#include "DigitalIn.h"
+#include "DigitalOut.h"
+#include "DigitalInOut.h"
+#include "BusIn.h"
+#include "BusOut.h"
+#include "BusInOut.h"
+#include "PortIn.h"
+#include "PortInOut.h"
+#include "PortOut.h"
+#include "AnalogIn.h"
+#include "AnalogOut.h"
+#include "PwmOut.h"
+#include "Serial.h"
+#include "SPI.h"
+#include "SPISlave.h"
+#include "I2C.h"
+#include "I2CSlave.h"
+#include "Ethernet.h"
+#include "CAN.h"
+#include "RawSerial.h"
+
+// mbed Internal components
+#include "Timer.h"
+#include "Ticker.h"
+#include "Timeout.h"
+#include "LowPowerTimeout.h"
+#include "LowPowerTicker.h"
+#include "LowPowerTimer.h"
+#include "LocalFileSystem.h"
+#include "InterruptIn.h"
+#include "wait_api.h"
+#include "sleep_api.h"
+#include "rtc_time.h"
+
+using namespace mbed;
+using namespace std;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/mbed_assert.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,49 @@
+/* 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_ASSERT_H
+#define MBED_ASSERT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Internal mbed assert function which is invoked when MBED_ASSERT macro failes.
+ *  This function is active only if NDEBUG is not defined prior to including this
+ *  assert header file.
+ *  In case of MBED_ASSERT failing condition, error() is called with the assertation message.
+ *  @param expr Expresion to be checked.
+ *  @param file File where assertation failed.
+ *  @param line Failing assertation line number.
+ */
+void mbed_assert_internal(const char *expr, const char *file, int line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef NDEBUG
+#define MBED_ASSERT(expr) ((void)0)
+
+#else
+#define MBED_ASSERT(expr)                                \
+do {                                                     \
+    if (!(expr)) {                                       \
+        mbed_assert_internal(#expr, __FILE__, __LINE__); \
+    }                                                    \
+} while (0)
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/mbed_debug.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,66 @@
+/* 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_DEBUG_H
+#define MBED_DEBUG_H
+#include "device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_STDIO_MESSAGES
+#include <stdio.h>
+#include <stdarg.h>
+
+/** Output a debug message
+ *
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug(const char *format, ...) {
+    va_list args;
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+}
+
+/** Conditionally output a debug message
+ *
+ * NOTE: If the condition is constant false (!= 1) and the compiler optimization
+ * level is greater than 0, then the whole function will be compiled away.
+ *
+ * @param condition output only if condition is true (== 1)
+ * @param format printf-style format string, followed by variables
+ */
+static inline void debug_if(int condition, const char *format, ...) {
+    if (condition == 1) {
+        va_list args;
+        va_start(args, format);
+        vfprintf(stderr, format, args);
+        va_end(args);
+    }
+}
+
+#else
+static inline void debug(const char *format, ...) {}
+static inline void debug_if(int condition, const char *format, ...) {}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/mbed_error.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,66 @@
+/* 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_ERROR_H
+#define MBED_ERROR_H
+
+/** To generate a fatal compile-time error, you can use the pre-processor #error directive.
+ *
+ * @code
+ * #error "That shouldn't have happened!"
+ * @endcode
+ *
+ * If the compiler evaluates this line, it will report the error and stop the compile.
+ *
+ * For example, you could use this to check some user-defined compile-time variables:
+ *
+ * @code
+ * #define NUM_PORTS 7
+ * #if (NUM_PORTS > 4)
+ *     #error "NUM_PORTS must be less than 4"
+ * #endif
+ * @endcode
+ *
+ * Reporting Run-Time Errors:
+ * To generate a fatal run-time error, you can use the mbed error() function.
+ *
+ * @code
+ * error("That shouldn't have happened!");
+ * @endcode
+ *
+ * If the mbed running the program executes this function, it will print the
+ * message via the USB serial port, and then die with the blue lights of death!
+ *
+ * The message can use printf-style formatting, so you can report variables in the
+ * message too. For example, you could use this to check a run-time condition:
+ *
+ * @code
+ * if(x >= 5) {
+ *     error("expected x to be less than 5, but got %d", x);
+ * }
+ * #endcode
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void error(const char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/mbed_interface.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,114 @@
+/* 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_INTERFACE_H
+#define MBED_INTERFACE_H
+
+#include "device.h"
+
+/* Mbed interface mac address
+ * if MBED_MAC_ADD_x are zero, interface uid sets mac address,
+ * otherwise MAC_ADD_x are used.
+ */
+#define MBED_MAC_ADDR_INTERFACE 0x00
+#define MBED_MAC_ADDR_0  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_1  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_2  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_3  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_4  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDR_5  MBED_MAC_ADDR_INTERFACE
+#define MBED_MAC_ADDRESS_SUM (MBED_MAC_ADDR_0 | MBED_MAC_ADDR_1 | MBED_MAC_ADDR_2 | MBED_MAC_ADDR_3 | MBED_MAC_ADDR_4 | MBED_MAC_ADDR_5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_SEMIHOST
+
+/** Functions to control the mbed interface
+ *
+ * mbed Microcontrollers have a built-in interface to provide functionality such as
+ * drag-n-drop download, reset, serial-over-usb, and access to the mbed local file
+ * system. These functions provide means to control the interface suing semihost
+ * calls it supports.
+ */
+
+/** Determine whether the mbed interface is connected, based on whether debug is enabled
+ *
+ *  @returns
+ *    1 if interface is connected,
+ *    0 otherwise
+ */
+int mbed_interface_connected(void);
+
+/** Instruct the mbed interface to reset, as if the reset button had been pressed
+ *
+ *  @returns
+ *    1 if successful,
+ *    0 otherwise (e.g. interface not present)
+ */
+int mbed_interface_reset(void);
+
+/** This will disconnect the debug aspect of the interface, so semihosting will be disabled.
+ * The interface will still support the USB serial aspect
+ *
+ *  @returns
+ *    0 if successful,
+ *   -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_disconnect(void);
+
+/** This will disconnect the debug aspect of the interface, and if the USB cable is not
+ * connected, also power down the interface. If the USB cable is connected, the interface
+ * will remain powered up and visible to the host
+ *
+ *  @returns
+ *    0 if successful,
+ *   -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_powerdown(void);
+
+/** This returns a string containing the 32-character UID of the mbed interface
+ *  This is a weak function that can be overwritten if required
+ *
+ *  @param uid A 33-byte array to write the null terminated 32-byte string
+ *
+ *  @returns
+ *    0 if successful,
+ *   -1 otherwise (e.g. interface not present)
+ */
+int mbed_interface_uid(char *uid);
+
+#endif
+
+/** This returns a unique 6-byte MAC address, based on the interface UID
+ * If the interface is not present, it returns a default fixed MAC address (00:02:F7:F0:00:00)
+ *
+ * This is a weak function that can be overwritten if you want to provide your own mechanism to
+ * provide a MAC address.
+ *
+ *  @param mac A 6-byte array to write the MAC address
+ */
+void mbed_mac_address(char *mac);
+
+/** Cause the mbed to flash the BLOD (Blue LEDs Of Death) sequence
+ */
+void mbed_die(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/pinmap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,45 @@
+/* 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_PINMAP_H
+#define MBED_PINMAP_H
+
+#include "PinNames.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PinName pin;
+    int peripheral;
+    int function;
+} PinMap;
+
+void pin_function(PinName pin, int function);
+void pin_mode    (PinName pin, PinMode mode);
+
+uint32_t pinmap_peripheral(PinName pin, const PinMap* map);
+uint32_t pinmap_function(PinName pin, const PinMap* map);
+uint32_t pinmap_merge     (uint32_t a, uint32_t b);
+void     pinmap_pinout    (PinName pin, const PinMap *map);
+uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map);
+uint32_t pinmap_find_function(PinName pin, const PinMap* map);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/platform.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,30 @@
+/* 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_PLATFORM_H
+#define MBED_PLATFORM_H
+
+#define MBED_OPERATORS    1
+
+#include "device.h"
+#include "PinNames.h"
+#include "PeripheralNames.h"
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/port_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/* 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_PORTMAP_H
+#define MBED_PORTMAP_H
+
+#include "device.h"
+
+#if DEVICE_PORTIN || DEVICE_PORTOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct port_s port_t;
+
+PinName port_pin(PortName port, int pin_n);
+
+void port_init (port_t *obj, PortName port, int mask, PinDirection dir);
+void port_mode (port_t *obj, PinMode mode);
+void port_dir  (port_t *obj, PinDirection dir);
+void port_write(port_t *obj, int value);
+int  port_read (port_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/pwmout_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,49 @@
+/* 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_PWMOUT_API_H
+#define MBED_PWMOUT_API_H
+
+#include "device.h"
+
+#if DEVICE_PWMOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct pwmout_s pwmout_t;
+
+void pwmout_init         (pwmout_t* obj, PinName pin);
+void pwmout_free         (pwmout_t* obj);
+
+void  pwmout_write       (pwmout_t* obj, float percent);
+float pwmout_read        (pwmout_t* obj);
+
+void pwmout_period       (pwmout_t* obj, float seconds);
+void pwmout_period_ms    (pwmout_t* obj, int ms);
+void pwmout_period_us    (pwmout_t* obj, int us);
+
+void pwmout_pulsewidth   (pwmout_t* obj, float seconds);
+void pwmout_pulsewidth_ms(pwmout_t* obj, int ms);
+void pwmout_pulsewidth_us(pwmout_t* obj, int us);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/rtc_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/* 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_RTC_API_H
+#define MBED_RTC_API_H
+
+#include "device.h"
+
+#if DEVICE_RTC
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rtc_init(void);
+void rtc_free(void);
+int rtc_isenabled(void);
+
+time_t rtc_read(void);
+void rtc_write(time_t t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/rtc_time.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,85 @@
+/* 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 <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Implementation of the C time.h functions
+ *
+ * Provides mechanisms to set and read the current time, based
+ * on the microcontroller Real-Time Clock (RTC), plus some
+ * standard C manipulation and formating functions.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * int main() {
+ *     set_time(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37
+ *
+ *     while(1) {
+ *         time_t seconds = time(NULL);
+ *
+ *         printf("Time as seconds since January 1, 1970 = %d\n", seconds);
+ *
+ *         printf("Time as a basic string = %s", ctime(&seconds));
+ *
+ *         char buffer[32];
+ *         strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
+ *         printf("Time as a custom formatted string = %s", buffer);
+ *
+ *         wait(1);
+ *     }
+ * }
+ * @endcode
+ */
+
+/** Set the current time
+ *
+ * Initialises and sets the time of the microcontroller Real-Time Clock (RTC)
+ * to the time represented by the number of seconds since January 1, 1970
+ * (the UNIX timestamp).
+ *
+ * @param t Number of seconds since January 1, 1970 (the UNIX timestamp)
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * int main() {
+ *     set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
+ * }
+ * @endcode
+ */
+void set_time(time_t t);
+
+/** Attach an external RTC to be used for the C time functions
+ *
+ * Do not call this function from an interrupt while an RTC read/write operation may be occurring 
+ *
+ * @param read_rtc pointer to function which returns current UNIX timestamp
+ * @param write_rtc pointer to function which sets current UNIX timestamp, can be NULL
+ * @param init_rtc pointer to funtion which initializes RTC, can be NULL
+ * @param isenabled_rtc pointer to function wich returns if the rtc is enabled, can be NULL
+ */
+void attach_rtc(time_t (*read_rtc)(void), void (*write_rtc)(time_t), void (*init_rtc)(void), int (*isenabled_rtc)(void));
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/semihost_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,93 @@
+/* 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_SEMIHOST_H
+#define MBED_SEMIHOST_H
+
+#include "device.h"
+#include "toolchain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DEVICE_SEMIHOST
+
+#ifndef __CC_ARM
+
+#if defined(__ICCARM__)
+inline int __semihost(int reason, const void *arg) {
+    return __semihosting(reason, (void*)arg);
+}
+#else
+
+#ifdef __thumb__
+#   define AngelSWI            0xAB
+#   define AngelSWIInsn        "bkpt"
+#   define AngelSWIAsm          bkpt
+#else
+#   define AngelSWI            0x123456
+#   define AngelSWIInsn        "swi"
+#   define AngelSWIAsm          swi
+#endif
+
+static inline int __semihost(int reason, const void *arg) {
+    int value;
+
+    asm volatile (
+       "mov r0, %1"          "\n\t"
+       "mov r1, %2"          "\n\t"
+       AngelSWIInsn " %a3"   "\n\t"
+       "mov %0, r0"
+       : "=r" (value)                                         /* output operands             */
+       : "r" (reason), "r" (arg), "i" (AngelSWI)              /* input operands              */
+       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"   /* list of clobbered registers */
+    );
+
+    return value;
+}
+#endif
+#endif
+
+#if DEVICE_LOCALFILESYSTEM
+FILEHANDLE semihost_open(const char* name, int openmode);
+int semihost_close (FILEHANDLE fh);
+int semihost_read  (FILEHANDLE fh, unsigned char* buffer, unsigned int length, int mode);
+int semihost_write (FILEHANDLE fh, const unsigned char* buffer, unsigned int length, int mode);
+int semihost_ensure(FILEHANDLE fh);
+long semihost_flen (FILEHANDLE fh);
+int semihost_seek  (FILEHANDLE fh, long position);
+int semihost_istty (FILEHANDLE fh);
+
+int semihost_remove(const char *name);
+int semihost_rename(const char *old_name, const char *new_name);
+#endif
+
+int semihost_uid(char *uid);
+int semihost_reset(void);
+int semihost_vbus(void);
+int semihost_powerdown(void);
+int semihost_exit(void);
+
+int semihost_connected(void);
+int semihost_disabledebug(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/serial_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,302 @@
+/* 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_SERIAL_API_H
+#define MBED_SERIAL_API_H
+
+#include "device.h"
+#include "buffer.h"
+#include "dma_api.h"
+
+#if DEVICE_SERIAL
+
+#define SERIAL_EVENT_TX_SHIFT (2)
+#define SERIAL_EVENT_RX_SHIFT (8)
+
+#define SERIAL_EVENT_TX_MASK (0x00FC)
+#define SERIAL_EVENT_RX_MASK (0x3F00)
+
+#define SERIAL_EVENT_ERROR (1 << 1)
+
+/**
+ * @defgroup SerialTXEvents Serial TX Events Macros
+ *
+ * @{
+ */
+#define SERIAL_EVENT_TX_COMPLETE (1 << (SERIAL_EVENT_TX_SHIFT + 0))
+#define SERIAL_EVENT_TX_ALL      (SERIAL_EVENT_TX_COMPLETE)
+/**@}*/
+
+/**
+ * @defgroup SerialRXEvents Serial RX Events Macros
+ *
+ * @{
+ */
+#define SERIAL_EVENT_RX_COMPLETE        (1 << (SERIAL_EVENT_RX_SHIFT + 0))
+#define SERIAL_EVENT_RX_OVERRUN_ERROR   (1 << (SERIAL_EVENT_RX_SHIFT + 1))
+#define SERIAL_EVENT_RX_FRAMING_ERROR   (1 << (SERIAL_EVENT_RX_SHIFT + 2))
+#define SERIAL_EVENT_RX_PARITY_ERROR    (1 << (SERIAL_EVENT_RX_SHIFT + 3))
+#define SERIAL_EVENT_RX_OVERFLOW        (1 << (SERIAL_EVENT_RX_SHIFT + 4))
+#define SERIAL_EVENT_RX_CHARACTER_MATCH (1 << (SERIAL_EVENT_RX_SHIFT + 5))
+#define SERIAL_EVENT_RX_ALL             (SERIAL_EVENT_RX_OVERFLOW | SERIAL_EVENT_RX_PARITY_ERROR | \
+                                         SERIAL_EVENT_RX_FRAMING_ERROR | SERIAL_EVENT_RX_OVERRUN_ERROR | \
+                                         SERIAL_EVENT_RX_COMPLETE | SERIAL_EVENT_RX_CHARACTER_MATCH)
+/**@}*/
+
+#define SERIAL_RESERVED_CHAR_MATCH (255)
+
+typedef enum {
+    ParityNone = 0,
+    ParityOdd = 1,
+    ParityEven = 2,
+    ParityForced1 = 3,
+    ParityForced0 = 4
+} SerialParity;
+
+typedef enum {
+    RxIrq,
+    TxIrq
+} SerialIrq;
+
+typedef enum {
+    FlowControlNone,
+    FlowControlRTS,
+    FlowControlCTS,
+    FlowControlRTSCTS
+} FlowControl;
+
+typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event);
+
+#if DEVICE_SERIAL_ASYNCH
+/** Asynch serial hal structure
+ */
+typedef struct {
+    struct serial_s serial;  /**< Target specific serial structure */
+    struct buffer_s tx_buff; /**< Tx buffer */
+    struct buffer_s rx_buff; /**< Rx buffer */
+    uint8_t char_match;      /**< Character to be matched */
+    uint8_t char_found;      /**< State of the matched character */
+} serial_t;
+
+#else
+/** Non-asynch serial hal structure
+ */
+typedef struct serial_s serial_t;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup GeneralSerial Serial Configuration Functions
+ * @{
+ */
+
+/** Initialize the serial peripheral. It sets the default parameters for serial
+ *  peripheral, and configure its specifieds pins.
+ *
+ * @param obj The serial object
+ * @param tx  The TX pin
+ * @param rx  The RX pin
+ */
+void serial_init(serial_t *obj, PinName tx, PinName rx);
+
+/** Release the serial peripheral, not currently invoked. It requires further
+ *  resource management.
+ *
+ * @param obj The serial object
+ */
+void serial_free(serial_t *obj);
+
+/** Configure the baud rate
+ *
+ * @param obj      The serial object
+ * @param baudrate The baud rate to be configured
+ */
+void serial_baud(serial_t *obj, int baudrate);
+
+/** Configure the format. Set the number of bits, parity and the number of stop bits
+ *
+ * @param obj       The serial object
+ * @param data_bits The number of data bits
+ * @param parity    The parity
+ * @param stop_bits The number of stop bits
+ */
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
+
+/** The serial interrupt handler registration.
+ *
+ * @param obj     The serial object
+ * @param handler The interrupt handler which will be invoked when interrupt fires.
+ * @param id      The SerialBase object
+ */
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id);
+
+/** Configure serial interrupt. This function is used for word-approach
+ *
+ * @param obj    The serial object
+ * @param irq    The serial IRQ type (RX or TX)
+ * @param enable Set to non-zero to enable events, or zero to disable them
+ */
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable);
+
+/** Get character. This is a blocking call, waiting for a character
+ *
+ * @param obj The serial object
+ */
+int  serial_getc(serial_t *obj);
+
+/** Put a character. This is a blocking call, waiting for a peripheral to be available
+ *  for writing
+ *
+ * @param obj The serial object
+ * @param c   The character to be sent
+ */
+void serial_putc(serial_t *obj, int c);
+
+/** Check if the serial peripheral is readable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be read, 0 if nothing to read.
+ */
+int  serial_readable(serial_t *obj);
+
+/** Check if the serial peripheral is writable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be written, 0 otherwise.
+ */
+int  serial_writable(serial_t *obj);
+
+/** Clear the serial peripheral
+ *
+ * @param obj The serial object
+ */
+void serial_clear(serial_t *obj);
+
+/** Set the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_set(serial_t *obj);
+
+/** Clear the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_clear(serial_t *obj);
+
+/** Configure the TX pin for UART function.
+ *
+ * @param tx The pin used for TX
+ */
+void serial_pinout_tx(PinName tx);
+
+/** Configure the serial for the flow control. It sets flow control in the hardware
+ *  if a serial peripheral supports it, otherwise software emulation is used.
+ *
+ * @param obj    The serial object
+ * @param type   The type of the flow control. Look at the available FlowControl types.
+ * @param rxflow The tx pin
+ * @param txflow The rx pin
+ */
+void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow);
+
+#if DEVICE_SERIAL_ASYNCH
+
+/**@}*/
+
+/**
+ * \defgroup AsynchSerial Asynchronous Serial Hardware Abstraction Layer
+ * @{
+ */
+
+/** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
+ *  tx_buff
+ *
+ * @param obj       The serial object
+ * @param tx        The buffer for sending
+ * @param tx_length The number of words to transmit
+ * @param tx_width  The bit width of buffer word
+ * @param handler   The serial handler
+ * @param event     The logical OR of events to be registered
+ * @param hint      A suggestion for how to use DMA with this transfer
+ * @return Returns number of data transfered, or 0 otherwise
+ */
+int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** Begin asynchronous RX transfer (enable interrupt for data collecting)
+ *  The used buffer is specified in the serial object - rx_buff
+ *
+ * @param obj        The serial object
+ * @param rx         The buffer for sending
+ * @param rx_length  The number of words to transmit
+ * @param rx_width   The bit width of buffer word
+ * @param handler    The serial handler
+ * @param event      The logical OR of events to be registered
+ * @param handler    The serial handler
+ * @param char_match A character in range 0-254 to be matched
+ * @param hint       A suggestion for how to use DMA with this transfer
+ */
+void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint);
+
+/** Attempts to determine if the serial peripheral is already in use for TX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_tx_active(serial_t *obj);
+
+/** Attempts to determine if the serial peripheral is already in use for RX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_rx_active(serial_t *obj);
+
+/** The asynchronous TX and RX handler.
+ *
+ * @param obj The serial object
+ * @return Returns event flags if a RX transfer termination condition was met or 0 otherwise
+ */
+int serial_irq_handler_asynch(serial_t *obj);
+
+/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
+ *  flush TX hardware buffer if TX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_tx_abort_asynch(serial_t *obj);
+
+/** Abort the ongoing RX transaction It disables the enabled interrupt for RX and
+ *  flush RX hardware buffer if RX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_rx_abort_asynch(serial_t *obj);
+
+/**@}*/
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/sleep_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,64 @@
+/* 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_SLEEP_API_H
+#define MBED_SLEEP_API_H
+
+#include "device.h"
+
+#if DEVICE_SLEEP
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Send the microcontroller to sleep
+ *
+ * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
+ * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
+ * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
+ * memory state are maintained, and the peripherals continue to work and can generate interrupts.
+ *
+ * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
+ *
+ * @note
+ *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+void sleep(void);
+
+/** Send the microcontroller to deep sleep
+ *
+ * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
+ * has the same sleep features as sleep plus it powers down peripherals and clocks. All state
+ * is still maintained.
+ *
+ * The processor can only be woken up by an external interrupt on a pin or a watchdog timer.
+ *
+ * @note
+ *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+void deepsleep(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/spi_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,213 @@
+/* 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_SPI_API_H
+#define MBED_SPI_API_H
+
+#include "device.h"
+#include "dma_api.h"
+#include "buffer.h"
+
+#if DEVICE_SPI
+
+#define SPI_EVENT_ERROR       (1 << 1)
+#define SPI_EVENT_COMPLETE    (1 << 2)
+#define SPI_EVENT_RX_OVERFLOW (1 << 3)
+#define SPI_EVENT_ALL         (SPI_EVENT_ERROR | SPI_EVENT_COMPLETE | SPI_EVENT_RX_OVERFLOW)
+
+#define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // internal flag to report an event occurred
+
+#define SPI_FILL_WORD         (0xFFFF)
+
+#if DEVICE_SPI_ASYNCH
+/** Asynch spi hal structure
+ */
+typedef struct {
+    struct spi_s spi;        /**< Target specific spi structure */
+    struct buffer_s tx_buff; /**< Tx buffer */
+    struct buffer_s rx_buff; /**< Rx buffer */
+} spi_t;
+
+#else
+/** Non-asynch spi hal structure
+ */
+typedef struct spi_s spi_t;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup GeneralSPI SPI Configuration Functions
+ * @{
+ */
+
+/** Initialize the SPI peripheral
+ *
+ * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
+ * @param[out] obj  The SPI object to initialize
+ * @param[in]  mosi The pin to use for MOSI
+ * @param[in]  miso The pin to use for MISO
+ * @param[in]  sclk The pin to use for SCLK
+ * @param[in]  ssel The pin to use for SSEL
+ */
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
+
+/** Release a SPI object
+ *
+ * TODO: spi_free is currently unimplemented
+ * This will require reference counting at the C++ level to be safe
+ *
+ * Return the pins owned by the SPI object to their reset state
+ * Disable the SPI peripheral
+ * Disable the SPI clock
+ * @param[in] obj The SPI object to deinitialize
+ */
+void spi_free(spi_t *obj);
+
+/** Configure the SPI format
+ *
+ * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode
+ * @param[in,out] obj   The SPI object to configure
+ * @param[in]     bits  The number of bits per frame
+ * @param[in]     mode  The SPI mode (clock polarity, phase, and shift direction)
+ * @param[in]     slave Zero for master mode or non-zero for slave mode
+ */
+void spi_format(spi_t *obj, int bits, int mode, int slave);
+
+/** Set the SPI baud rate
+ *
+ * Actual frequency may differ from the desired frequency due to available dividers and bus clock
+ * Configures the SPI peripheral's baud rate
+ * @param[in,out] obj The SPI object to configure
+ * @param[in]     hz  The baud rate in Hz
+ */
+void spi_frequency(spi_t *obj, int hz);
+
+/**@}*/
+/**
+ * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
+ * @{
+ */
+
+/** Write a byte out in master mode and receive a value
+ *
+ * @param[in] obj   The SPI peripheral to use for sending
+ * @param[in] value The value to send
+ * @return Returns the value received during send
+ */
+int  spi_master_write(spi_t *obj, int value);
+
+/** Check if a value is available to read
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if a value is available
+ */
+int  spi_slave_receive(spi_t *obj);
+
+/** Get a received value out of the SPI receive buffer in slave mode
+ *
+ * Blocks until a value is available
+ * @param[in] obj The SPI peripheral to read
+ * @return The value received
+ */
+int  spi_slave_read(spi_t *obj);
+
+/** Write a value to the SPI peripheral in slave mode
+ *
+ * Blocks until the SPI peripheral can be written to
+ * @param[in] obj   The SPI peripheral to write
+ * @param[in] value The value to write
+ */
+void spi_slave_write(spi_t *obj, int value);
+
+/** Checks if the specified SPI peripheral is in use
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if the peripheral is currently transmitting
+ */
+int  spi_busy(spi_t *obj);
+
+/** Get the module number
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return The module number
+ */
+uint8_t spi_get_module(spi_t *obj);
+
+/**@}*/
+
+#if DEVICE_SPI_ASYNCH
+/**
+ * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
+ * @{
+ */
+
+/** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
+ *
+ * @param[in] obj       The SPI object which holds the transfer information
+ * @param[in] tx        The buffer to send
+ * @param[in] tx_length The number of words to transmit
+ * @param[in] rx        The buffer to receive
+ * @param[in] rx_length The number of words to receive
+ * @param[in] bit_width The bit width of buffer words
+ * @param[in] event     The logical OR of events to be registered
+ * @param[in] handler   SPI interrupt handler
+ * @param[in] hint      A suggestion for how to use DMA with this transfer
+ */
+void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** The asynchronous IRQ handler
+ *
+ * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
+ * conditions, such as buffer overflows or transfer complete.
+ * @param[in] obj     The SPI object which holds the transfer information
+ * @return event flags if a transfer termination condition was met or 0 otherwise.
+ */
+uint32_t spi_irq_handler_asynch(spi_t *obj);
+
+/** Attempts to determine if the SPI peripheral is already in use.
+ *
+ * If a temporary DMA channel has been allocated, peripheral is in use.
+ * If a permanent DMA channel has been allocated, check if the DMA channel is in use.  If not, proceed as though no DMA
+ * channel were allocated.
+ * If no DMA channel is allocated, check whether tx and rx buffers have been assigned.  For each assigned buffer, check
+ * if the corresponding buffer position is less than the buffer length.  If buffers do not indicate activity, check if
+ * there are any bytes in the FIFOs.
+ * @param[in] obj The SPI object to check for activity
+ * @return non-zero if the SPI port is active or zero if it is not.
+ */
+uint8_t spi_active(spi_t *obj);
+
+/** Abort an SPI transfer
+ *
+ * @param obj The SPI peripheral to stop
+ */
+void spi_abort_asynch(spi_t *obj);
+
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // SPI_DEVICE
+
+#endif // MBED_SPI_API_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/ticker_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,108 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_TICKER_API_H
+#define MBED_TICKER_API_H
+
+#include "device.h"
+
+typedef uint32_t timestamp_t;
+
+/** Ticker's event structure
+ */
+typedef struct ticker_event_s {
+    timestamp_t            timestamp; /**< Event's timestamp */
+    uint32_t               id;        /**< TimerEvent object */
+    struct ticker_event_s *next;      /**< Next event in the queue */
+} ticker_event_t;
+
+typedef void (*ticker_event_handler)(uint32_t id);
+
+/** Ticker's interface structure - required API for a ticker
+ */
+typedef struct {
+    void (*init)(void);                           /**< Init function */
+    uint32_t (*read)(void);                       /**< Read function */
+    void (*disable_interrupt)(void);              /**< Disable interrupt function */
+    void (*clear_interrupt)(void);                /**< Clear interrupt function */
+    void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */
+} ticker_interface_t;
+
+/** Tickers events queue structure
+ */
+typedef struct {
+    ticker_event_handler event_handler; /**< Event handler */
+    ticker_event_t *head;               /**< A pointer to head */
+} ticker_event_queue_t;
+
+/** Tickers data structure
+ */
+typedef struct {
+    const ticker_interface_t *interface; /**< Ticker's interface */
+    ticker_event_queue_t *queue;         /**< Ticker's events queue */
+} ticker_data_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize a ticker and sets the event handler
+ *
+ * @param data    The ticker's data
+ * @param handler A handler to be set
+ */
+void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler);
+
+/** Irq handler which goes through the events to trigger events in the past.
+ *
+ * @param data    The ticker's data
+ */
+void ticker_irq_handler(const ticker_data_t *const data);
+
+/** Remove an event from the queue
+ *
+ * @param data The ticker's data
+ * @param obj  The event's queue to be removed
+ */
+void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj);
+
+/** Insert an event from the queue
+ *
+ * @param data      The ticker's data
+ * @param obj       The event's queue to be removed
+ * @param timestamp The event's timestamp
+ * @param id        The event object
+ */
+void ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id);
+
+/** Read the current ticker's timestamp
+ *
+ * @param data The ticker's data
+ * @return The current timestamp
+ */
+timestamp_t ticker_read(const ticker_data_t *const data);
+
+/** Read the next event's timestamp
+ *
+ * @param data The ticker's data
+ * @return 1 if timestamp is pending event, 0 if there's no event pending
+ */
+int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/toolchain.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,35 @@
+/* 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_TOOLCHAIN_H
+#define MBED_TOOLCHAIN_H
+
+#if defined(TOOLCHAIN_ARM)
+#include <rt_sys.h>
+#endif
+
+#ifndef FILEHANDLE
+typedef int FILEHANDLE;
+#endif
+
+#if defined (__ICCARM__)
+#   define WEAK     __weak
+#   define PACKED   __packed
+#else
+#   define WEAK     __attribute__((weak))
+#   define PACKED   __attribute__((packed))
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/us_ticker_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,78 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_US_TICKER_API_H
+#define MBED_US_TICKER_API_H
+
+#include <stdint.h>
+#include "ticker_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup UsTicker Microseconds Ticker Functions
+ * @{
+ */
+
+/** Get ticker's data
+ *
+ * @return The low power ticker data
+ */
+const ticker_data_t* get_us_ticker_data(void);
+
+
+/** The wrapper for ticker_irq_handler, to pass us ticker's data
+ *
+ */
+void us_ticker_irq_handler(void);
+
+/* HAL us ticker */
+
+/** Initialize the ticker
+ *
+ */
+void us_ticker_init(void);
+
+/** Read the current counter
+ *
+ * @return The current timer's counter value in microseconds
+ */
+uint32_t us_ticker_read(void);
+
+/** Set interrupt for specified timestamp
+ *
+ * @param timestamp The time in microseconds to be set
+ */
+void us_ticker_set_interrupt(timestamp_t timestamp);
+
+/** Disable us ticker interrupt
+ *
+ */
+void us_ticker_disable_interrupt(void);
+
+/** Clear us ticker interrupt
+ *
+ */
+void us_ticker_clear_interrupt(void);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/mbed-dev-bin/wait_api.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,66 @@
+/* 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_WAIT_API_H
+#define MBED_WAIT_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Generic wait functions.
+ *
+ * These provide simple NOP type wait capabilities.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * DigitalOut heartbeat(LED1);
+ *
+ * int main() {
+ *     while (1) {
+ *         heartbeat = 1;
+ *         wait(0.5);
+ *         heartbeat = 0;
+ *         wait(0.5);
+ *     }
+ * }
+ */
+
+/** Waits for a number of seconds, with microsecond resolution (within
+ *  the accuracy of single precision floating point).
+ *
+ *  @param s number of seconds to wait
+ */
+void wait(float s);
+
+/** Waits a number of milliseconds.
+ *
+ *  @param ms the whole number of milliseconds to wait
+ */
+void wait_ms(int ms);
+
+/** Waits a number of microseconds.
+ *
+ *  @param us the whole number of microseconds to wait
+ */
+void wait_us(int us);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/module.json	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,29 @@
+{
+  "name": "microbit-dal",
+  "version": "2.0.0-rc4",
+  "license": "MIT",
+  "description": "The runtime library for the BBC micro:bit, developed by Lancaster University",
+  "keywords": [
+    "mbed-classic",
+    "microbit",
+    "runtime",
+    "library",
+    "lancaster",
+    "University"
+  ],
+  "author": "Joe Finney <j.finney@lancaster.ac.uk (mailto:j.finney@lancaster.ac.uk) >",
+  "homepage": "https://github.com/lancaster-university/microbit-dal/",
+  "dependencies": {
+    "mbed-classic": "lancaster-university/mbed-classic#microbit_hfclk+mb5",
+    "ble": "lancaster-university/BLE_API#v2.5.0+mb3",
+    "ble-nrf51822": "lancaster-university/nrf51822#v2.5.0+mb6",
+    "nrf51-sdk": "lancaster-university/nrf51-sdk#v2.2.0+mb4"
+  },
+  "extraIncludes": [
+    "inc/core",
+    "inc/types",
+    "inc/drivers",
+    "inc/bluetooth",
+    "inc/platform"
+  ]
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/LICENSE	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/apache-2.0.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/bootloader/s110_nrf51822_8.0.0_bootloader.hex	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,463 @@
+:020000040003F7
+:20C00000983C002005DD030017DD030019DD03000000000000000000000000000000000057
+:20C0200000000000000000000000000069C1030000000000000000001DDD03001FDD0300D7
+:20C0400021DD030021DD030021DD030021DD030021DD03000000000021DD030021DD0300D9
+:20C0600021DD030021DD030021DD030021DD030021DD030021DD030021DD030021DD0300B8
+:20C0800021DD030057D8030021DD030021DD03006DD8030021DD03004DF4030021DD0300DD
+:20C0A00021DD030021DD03000000000000000000000000000000000000000000000000007E
+:20C0C00000F002F800F040F80CA030C8083824182D18A246671EAB4654465D46AC4201D18E
+:20C0E00000F032F87E460F3E0FCCB6460126334200D0FB1AA246AB463343184710370000C8
+:20C1000030370000103A02D378C878C1FAD8520701D330C830C101D504680C6070470000D3
+:20C120000023002400250026103A01D378C1FBD8520700D330C100D50B6070471FB5C04655
+:20C14000C0461FBD10B510BD03F0E3FA1146FFF7F5FF00F0D3F803F0FBFA03B4FFF7F2FF19
+:20C1600003BC03F0FFFA00000648704502D1EFF3098101E0EFF30881886902380078024A97
+:20C1800010470000FDFFFFFF39D50300401E00BF00BF00BF00BF00BF00BF00BF00BF00BF28
+:20C1A00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BFB4
+:20C1C00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BF94
+:20C1E00000BF00BF00BFF1D170470000056885F3088846680A4AEFF305839A42304602D183
+:20C20000084CA6463047074C064D0646064FF0B4034C034D024E024FF0B404480047000005
+:20C2200000000000FFFFFFFF00000021F9FFFFFF70B505460C46164602E00FCC0FC5103EEE
+:20C24000102EFAD2082E02D303CC03C5083E042E07D301CC01C5361F03E021782970641C63
+:20C260006D1C761EF9D270BD0A4610B50146664803F064F810BD10B502F078FC10BD10B5C6
+:20C28000624C86B01ECC03946C460EC4002807D0684618DF002803D00022114603F04EF864
+:20C2A0000F20800313DF002803D00022114603F045F8574B48225749092003F0A3F80028AB
+:20C2C00003D00022114603F039F800200490059001206946087404A860DF002803D0002251
+:20C2E000114603F02BF84C4803F0A8F8002803D00022114603F022F806B010BD08B547485A
+:20C30000C169B12943D0002445480F2140698903884204D000221146104603F00FF8012068
+:20C320000007006901218902884204D000221146104603F003F83B4800903B4B05220321A1
+:20C34000002001F0BAFA002803D00022114602F0F5FF00F067FC00F0AAFC012500281AD09D
+:20C3600000F0B4FC002803D00022114602F0E6FF20466840FFF783FF00F038F800F0CCFC74
+:20C3800000280ED00022114602F0D8FF09E001240021C161B8E720466840FFF770FF00F002
+:20C3A00025F803252D03002C04D1A86800F090FB002807D100F047FC002803D000221146D5
+:20C3C00002F0BCFFA86800F083FB002806D000F06EFC002802D1A86800F041FCBFF34F8F12
+:20C3E00013491248C860BFF34F8FFEE7094A10B548321421082002F00BFF002803D00022E2
+:20C40000114602F09BFF10BDEFBEADDE8CF703006BF30300342B002077C20300000500404D
+:20C4200000100010EFDC0300F42800200400FA0500ED00E070B5FC4C1E46A06815460229A3
+:20C4400002D0042916D108E0052813D1A369002B10D03246294604200BE002280AD1F348B0
+:20C46000406880470320A060A369002B02D0324629469847280003D00022114602F05EFF98
+:20C4800070BD4CB5E84E0120307005200195009400F058FB4CBD10B5E34C2078002801D057
+:20C4A000082010BD206901F0F4FA002803D00022114602F043FF0F2100228904206901F01E
+:20C4C000ABFA040003D00022114602F037FF204610BDD54910B5D448243141610221816012
+:20C4E000C168243002F059FD002803D00022114602F024FF10BDCC4910B5CB481C31416145
+:20C50000022181600320000380680F218903081A4108C5481C3002F040FD002803D000223D
+:20C52000114602F00BFF10BD704700B589B01822BF4902A8FFF77CFE06980799009001917A
+:20C5400002A80FC800F0FEFA09B000BD00B5B64987B049886A461181032109038968069146
+:20C56000B249012050394A6803928A680492C9680591069A0091019202A90EC900F0E2FA6E
+:20C58000002007B000BD30B5A84CA748503C89B02430E16802F001FD002803D00022114679
+:20C5A00002F0CCFEA048E2681C3041680023083002F0C3FC050012D1182102A802F0E6FFEA
+:20C5C00000209949029049886A469181E1680691079A0091019203A90EC900F0B3FA284601
+:20C5E00009B030BD00B5904987B049886A4611818E49032050394A6803928A680492C9683A
+:20C600000591069A0091019202A90EC900F09AFA0020B6E73EB5864A6B46183207CA07C3A4
+:20C62000814D00246C7029466C802431684602F068FC002801D0AC603EBD03207A4900038F
+:20C6400080682431486024390A46526ACA610F218903091A490840187349764A1C31486068
+:20C6600071480021103001F07BF9002803D00022114602F063FE0F2100228904286901F013
+:20C68000CBF9002803D00022114602F057FE01206C60A86000203EBD63498861704770B59A
+:20C6A000426862481468536891685038D26804604360C26081600078440701D5840705D130
+:20C6C0009C0703D18C0701D1940701D0062070BD5B189A18544D0F239B02EA60994213D81A
+:20C6E0005549564B514CC60709D08868181A90420AD3534820605348606053480FE08968F6
+:20C70000591A4908914201D20C2070BD4F4921604F496160800701D54E4800E04E48A0607B
+:20C72000A868012802D00826304670BDFFF7B3FE0600FAD12168E8688847F5E770B50500F7
+:20C7400004D0287A800703D0102070BD0E2070BD354CA068032805D0042801D0052803D0CB
+:20C76000082070BD0520A0606868E168860060688019884204D90020C04360600C2070BD5C
+:20C78000FFF789FE0028FAD1A96832466368606902F0D3FB0028F2D1616889196160E268EB
+:20C7A0009142ECD0092070BD10B51F4C08206168002900D010BDA1680429FBD11B4861786F
+:20C7C000403802F021FC002802D00021617010BD0521A16010BDF8B5134C0746A068032899
+:20C7E00004D0042804D008252846F8BD0420A0606068002801D00820F8BDFFF74CFE05000E
+:20C80000FAD17868860060788119402901D90920F8BD064AB968403A1018324602F057FE82
+:20C82000607880196070DFE7002800201C2D00209CF7030083C403000030000000C003006D
+:20C84000D3C403002BC503004DC50300F7C4030029C50300E5C5030087C5030010B5894CF1
+:20C86000A068052813D1E168606888420FD10620A060FFF710FE002808D16069E1684068FF
+:20C8800002F0FCFB002801D10721A16010BD082010BD10B57B488168072901D0082010BD63
+:20C8A000006901F0F6F8002803D00022114602F045FD75488068804710BD1CB506200195C2
+:20C8C000009400F03FF91CBDF8B51C4617460D46064600F0C1F8002817D001200003854215
+:20C8E00007D92346291B301B1A46FFF7EDFF00280BD13A462946304600F0B9F8002804D117
+:20C900003A462946304600F0A7F8F8BDF0B589B0684600F015FA049800282AD001210903F7
+:20C92000079A4018904226D9501A45081046049A0C468718024668001618001908900320DF
+:20C9400000038068049988420DD261190846042200F08DF800280CD121460422084600F073
+:20C9600086F8002805D1BA1B2B4630460899FFF7ABFF09B0F0BD049A079800F078F8F8E75C
+:20C9800000B58DB004A800F0DBF9099800280DD0089800280CD008990B984018019000219D
+:20C9A0000998009180080290684618DF0DB000BD0320000380680F218903091A4908ECE7FB
+:20C9C00000B58DB004A800F0BBF909980028EDD00F210898890300280CD0089A0B98019158
+:20C9E0008018029003220998009280080390684618DFDBE70320000380680A1A5208EEE7D2
+:20CA000030B591B0684600F09BF90498002814D001210903079A4018904214D9501A43087B
+:20CA20001046049A5C0082180019611803242403A468049DAC4202D20E2011B030BD121AB5
+:20CA4000FFF742FFF9E703200CAB07C3049880080F900CA818DFF0E71FB5032301909008B3
+:20CA6000039000930291684618DF04B010BD1FB5012301909008039000930291684618DF58
+:20CA8000F3E70000002800201C2D002010B5BB480368012B02D1022900D10160100003D099
+:20CAA0000022114602F04AFC10BD10B5B34C48DF002803D00022114602F040FC02F0FCFB82
+:20CAC0002068022803D0032801D00428EFD110BD38B50068401C19D00024684600F058F96F
+:20CAE00000980168012910D1818800290AD0C168032000038068002202F0CEFA0099898861
+:20CB0000814201D1012400E00024204638BD10B504469A482021001D02F0B9F9002803D00E
+:20CB20000022114602F00AFC9448002320222146001D02F01BF9002803D00022114602F053
+:20CB4000FDFB10BD0FB4F8B5684600F021F96846818B069D0122894CFF238948002D13D090
+:20CB6000012D17D0032D2BD00021022D37D02A46052D46D0042D4ED0062A01D10420206071
+:20CB8000F8BC08BC04B0184781800A9983600260C16010E08180099D089949190A9D49195D
+:20CBA000C160A52183600160089901610999856141610B99C16122607148FFF7A8FFDFE7B9
+:20CBC00000990B6803608B888380C968C160AA21816008990161099941610A990BE0009D60
+:20CBE0002E68A52E09D00660AE888680ED68C5600161836041618161DDE781800360C160C5
+:20CC0000F6E700F085F9002803D00022114602F095FB0320B3E781800360C1600099896807
+:20CC20008160C9E70EB557480090202001900120029002F001F8002804D150496846091D98
+:20CC400002F023F80EBD10B5FFF7E4FC002805D100F02FFB0446FFF728FF204610BD70B58A
+:20CC600011DF002803D00022114602F067FB464900200B68444C012180340A4682401A4206
+:20CC800004D0C506ED0E0A46AA402260401C2028F3D303242403A06813DF002803D000226F
+:20CCA000114602F04BFBA06802F0F2F970BD08B5684600F06DF800980168A52904D0806888
+:20CCC000AA2801D0002008BD012008BD10B5FFF797FE002803D1FFF773FE00281BD064209C
+:20CCE00001F0F2FDFFF712FE002803D00022114602F024FBFFF784FE002803D000221146DD
+:20CD000002F01CFBFFF73CFE040003D00022114602F014FB204610BD00B589B018221B49CA
+:20CD200002A8FFF785FA069807990090019102A80FC8FFF707FFFFF7B8FE002009B000BDB5
+:20CD400010B50E4988B0044600232022091D684602F04FF80098206068468088A08003983A
+:20CD6000E0600298A06004982061059860610698A0610798E06108B010BD00002C280020E6
+:20CD8000282D00208DCA030000E100E0C0F70300014901607047000000FC030008280CD0DC
+:20CDA00004DC002807D006280FD108E00B280AD00C280AD105E001207047022070470320C9
+:20CDC000704704207047042901D0062070470520704770B515460A46032823D0042820D1FF
+:20CDE000FE4C002906D0E088FD49884219D0132176DF10E0284602F0A3F9002803D00022F7
+:20CE0000114602F09BFAE069A8420AD101220321F44801F003F8002803D00022114602F051
+:20CE20008DFA70BD01211046FFF7B8FF02460121EEE7F0B5054608790E4685B081070CD07C
+:20CE400003221146284600F0E9FF002803D00022114602F073FA05B0F0BDE04900901831D9
+:20CE600002F047F9010011D1DC4CB168009AA06902F02DFB009802F097F9010006D1204647
+:20CE80006946183002F09CF9010003D0284600F0AFFAE0E704200190009880080290A06902
+:20CEA000039001A8FFF74AFC07000BD0092F10D0A06902F045F9010002D0284600F098FA04
+:20CEC0003946E3E73079616940186061A069E061C1E7307961694118616160780028BAD073
+:20CEE0006089401E0004000C6081B4D1284601F0E9F8002803D00022114602F01FFA20890D
+:20CF00006081A8E710B50022114602F017FA10BD10B5B24C01202070E088B149884208D01B
+:20CF2000132176DF002810D00022114602F006FA0BE0A078002808D074DF002803D0002282
+:20CF4000114602F0FBF90020A07001F034FC002803D00022114602F0F1F9002010BD70B5E1
+:20CF60000D68044601209D4A2B0002F002FC0A2B3043061320575C466012FFF76FFC0421FD
+:20CF8000FFF70CFF024604212EE00022114602F0D5F970BDFFF7BCFF002803D0002211468A
+:20CFA00002F0CCF9FFF775FC002808D170BDFFF7AFFF002803D00022114602F0BFF9FFF76D
+:20CFC0007CFC70BD106188680078107170BD02201061886800780128F8D1FFF7E5FB02213F
+:20CFE000FFF7DCFE02460221204600F017FF0028CBD170BD0320106170BD12692046012ACC
+:20D0000006D0022A07D0032AF6D1FFF712FF70BD00F001FA70BD00F03BFA70BD50708888D5
+:20D020001081508170BD00205070108170BD2046516901F010F8DAE710B5044669488EB0EB
+:20D0400081796846817068490180342101A802F09DFA022001900021684641728472012131
+:20D0600001820590002101A801F03FFA002803D00022114602F062F90EB010BDF0B5574C10
+:20D080008BB0A07800283AD156481821183802F07DFA2046534CC078183C00250126002875
+:20D0A00037D02746483700950195029510226946F81D039502F0DEF9002822D0F81D08909D
+:20D0C00009976846067509A804906846067708A806900420FFF7B0FF25700220207204A813
+:20D0E000E060282020823F486582183873DF002803D00022114602F021F9384886700BB045
+:20D10000F0BD0520FFF798FF2670676025722582E9E70620FFF790FF257065602572E0E7E2
+:20D1200070B52E4C01880022E588A6B017290AD01EDC11293FD008DC022977D0102902D123
+:20D140008088E080A27026B070BD264C303426461836132951D01429F5D1C289638D002106
+:20D160009A4200D1314600238088E21D82DF1BE0512970D00EDC18296CD01929E3D18079F5
+:20D180000028E0D1A270E068401EE0604FD0FFF775FFD8E7522976D05529D4D18079002871
+:20D1A000D1D11321284676DF0028CCD00022114602F0C4F8C7E78020694688803220E06054
+:20D1C000012301AA06A92846AADF002803D00022114602F0B3F82078002807E038280020A2
+:20D1E000FFFF0000602D00203015000001D1FFF745FF0020C043E080A5E70722C14910A839
+:20D2000002F065F91022E11D0CA802F060F91C22314612A802F05BF90CA80A9012A8099039
+:20D2200006ABB94A852128467FDFBDE70DE01822B64906A8FEF7FCFF0A980B9900900191F8
+:20D2400006A80FC8FFF77EFC7DE70021284667DFAAE700E017E0817900299AD0807A042885
+:20D2600003D0062801D0052893D1022909D0012069460872FF208330888102A92846A8DF82
+:20D2800092E70220F4E700F08DF88DE710B5044601F0C2FA9B482146303800F09AFE2046D3
+:20D2A000FFF73EFF10BD10B50022114602F046F810BD30B5944D87B00024203D2C7094483D
+:20D2C0002C6102F0B3F800286AD19248FFF7E4F901F000FF002863D18A4800F059F900288C
+:20D2E00001D10120E87011206946087207228AA102A87CDF002803D00022114602F01EF8B4
+:20D3000000940C2168460194018018214180FF2184809131C1807ADF002803D0002211469A
+:20D3200002F00CF804206946009408807C4801907C4802907348303800F00BFE002803D046
+:20D340000022114601F0FAFF1C21684602F01EF9754801900120800302900094032168468C
+:20D360000173C4810474714806900594684601F0FEF9002803D00022114601F0DFFF624910
+:20D38000E12208784008400010400C30DF22104008700720487010208870FFF76FFE0020A3
+:20D3A00007B030BD70B5584C614D203CE088A84201D1082070BDE178002914D05149012359
+:20D3C00008223431A9DF0028F4D12A460C21E088A7DF5849884204D0082802D0891C88420E
+:20D3E000E8D1002070BD00231A461946A9DF70BD10B50A46044603211046FFF7CFFC0246AE
+:20D400000321204600F00AFD002803D00022114601F094FF10BD30B5054687B000200090AF
+:20D4200001900290039038486A46203800791070364A0C3A1068926804906846069205900E
+:20D4400008790C2806D003221BE00022114601F075FFA5E78C68204600F049F80190201D5E
+:20D4600000F045F802902046083000F040F8039004A8FFF714F9002892D00121FFF78EFCB9
+:20D4800002460121284600F0C9FC0028DDD187E7FEB50446087982070ED08207920F042385
+:20D4A0009B1A0022154604E08E683554401CC0B2521C9A42F8D30871012000908868029048
+:20D4C0000879800801906846FFF785F900280DD00221FFF763FC02460221204600F09EFCB8
+:20D4E000002803D00022114601F028FFFEBD10B5044602F04DF80002E178000A09060843E0
+:20D5000010BD0000902D002058280020E4F703008DD20300D3CD0300446675546172670031
+:20D520005FCF0300A7D20300CD0C000005CF0300FFFF00000230000010B50C46002802D04D
+:20D540000120086010BD2168002911D01C48421A814212D03C2A0DD23C303C3101220B78B9
+:20D5600003701346491E401E521C3C2BF7D904E00E200BE03C2201F0AAFF00223C211048A9
+:20D5800001F08AFD0E49891E08800020206010BD70B5054600223C21094801F07DFD084C21
+:20D5A000A41E2188884201D00B2070BD3C220449284601F08CFF2088401C2080002070BD87
+:20D5C000823F00208307FF22DB0E9A408907090E994000280BDA0007000F08388308FA484C
+:20D5E0009B001B18D86990430843D86170478308F6489B001B1818689043084318607047AA
+:20D6000070B50124F24960040860F24940108860F04940398860F04D6C602F20FEF7B6FDAC
+:20D62000AC60EE4D00242F206C61FEF7AFFD2C7170BDF0B5E94F2821BC6841430D19396962
+:20D640004A1C09D028224A431619AB68B268934204D8D21AB26069623861F0BD0A4602E066
+:20D660000A46796A9B1B4E1C0BD028264E433719BE689E42F4D328264E433619B768FF1A1A
+:20D68000B760AB60696228214A4311194862F0BD70B5D24C2269A5681346114606E0814212
+:20D6A00007D00A46282671434919496A4E1CF6D170BD002EFCD08A420CD1282043435819EC
+:20D6C000406A2061401C05D1C34B01209860002363616071282041434819282381685A4310
+:20D6E000406A52195062421CE2D028225043401982685118816070BDF8B5B84C2569681CF9
+:20D7000035D0B748002640686169401A07023F0A19E028204543A0682A189068B84214D8D0
+:20D72000A3693F1A8619556A002B09D0116AD0699847002807D00022114601F0FFFD02E048
+:20D74000D169106A8847681CE3D1A178E078814206D1401CC0B2E070022801D10020E07079
+:20D760009E490006800D1C310E5000F0BAF9F8BDF8B50446994800270169009146785CE038
+:20D780009648F100C2688D1851E0601C07D0934A28209268604321468018446A24E0287854
+:20D7A000182141436A68401CC0B252182870A978884200D12F70894B516828209B6848434C
+:20D7C000C0181368012B34D1037E002B31D19368C360D368036113694361526902627F4A52
+:20D7E0005279002A00D0C7607C4BC2685B6996469C46D31A1A027B4B120A9A4202D20369C3
+:20D80000D21808E0724663469A1A12020369120A934202D99A1A826000E08760C76001222E
+:20D8200007610276921E42620846FFF702FF601CABD1287869788842A7D13046761EF6B202
+:20D8400000289DD1654801690098814201D00120F8BD0020F8BD644900200860486088607F
+:20D86000C860614940390860486045E7FEB50020C0435A4D02906869019068462E6900F07B
+:20D8800035F9074600F04FF90446002F08D002AA0199009800F08FF90298FFF769FF06E050
+:20D8A0000298FFF765FF002801D1002C02D0304600F0AAF900206871FEBDFFB59807002448
+:20D8C00081B01E4615460F4600280BD1002E09D0FFF796FE41490A9888610F703246002042
+:20D8E0008E6008E0072005B0F0BD28234343D4509B181C76401CB842F7DB28204743BB19C1
+:20D90000032048700F461846CB6019461830002218232E465E43D3005B181C705C709D708A
+:20D9200058603018521C032AF5DB0020C0433861BC70FC7001242D482405046003211420A9
+:20D94000FFF740FE224880380460254C0198A06003211120FFF736FE606878610020C2E71A
+:20D9600070B51E4CA568002D06D0002A06D0002804D00023247809E0082070BD072070BDBB
+:20D9800028265E43AE59002E04D05B1CA342F7DB042070BD282401265C432E516419E261BF
+:20D9A00061600360002070BD07494868C005C00D2CD010381CD50207120F083A9208920097
+:20D9C0005118C96919E0000000ED00E000E400E080E100E040130140001001406028002054
+:20D9E00000150140FFFF7F004011014080E200E08108B14A8900891809688007C00EC1400B
+:20DA00000806800F012803D0032803D0022070470020704701207047FEB50446A74817469E
+:20DA200082680D46002A0CD001788C4201D2052D01D20720FEBD2146282359435358012B7D
+:20DA400001D00820FEBD8818406801281DD00026FFF7AAFFC00099490190C9684018694684
+:20DA600000F018F9002812D0012144600160944949680830E2C091490198C9684118009877
+:20DA8000487000F02EF80020FEBD2E46E0E70420FEBDF8B5894D0446A868002809D0297844
+:20DAA0008C4201D30720F8BD282161434058012801D00820F8BDFFF777FFC600E86869465B
+:20DAC000301800F0E7F8002809D0022112C0E86831180098487000F004F80020F8BD04206B
+:20DAE000F8BD0120774900050860704710B5734900238A78CC78A24212D0521CD2B28A70D0
+:20DB0000022A00D18B708A786C4B92001C339A580260486910180002000A4861012010BDA3
+:20DB20000360002010BDF8B5644801690091457833E06248E900C0680E1834782AE01820A2
+:20DB400060437168641C0818B178E4B2A14200D100240168022902D003291BD113E0574A00
+:20DB600040682821926841438F18397E002911D0FFF78EFD002038760CE028277843C018B1
+:20DB80000276406A03E04D4900228B680869471CF3D108617078A042D1D128466D1EEDB2D0
+:20DBA0000028C6D1454801690098814201D00120F8BD0020F8BDF7B5404C0025A7682369E0
+:20DBC0001EE028215943C9198E68864202D9301A886017E0801B751900268E600E764E6946
+:20DBE0009C464B6AB646002E0AD0019E76193602360ACE6076460E6116684E626146116045
+:20DC0000591CDED12361FEBDF8B52C4801694A1C3DD028225143826889188E6828494C681F
+:20DC200047690079E11B0D022D0AED1C002815D10120254A00045060234A403A506021491D
+:20DC4000400080310860214908602149012008602F20FEF79BFA194901200871B54200D208
+:20DC60003546E81900021649000A4031086014494968001B091B0902090A0002C91C000A88
+:20DC8000814203D901200F4940040860F8BDFFF7B7FCF8BD42788378521C934200D10022C2
+:20DCA0000378934201D1002070470A6041684078182250430818704700E400E06028002090
+:20DCC0000015014000E200E04013014000E100E00010014010B50446082904D000221146F9
+:20DCE000104601F02BFB21686068884710BD1CB501910090024A0821684601F09DFA1CBD53
+:20DD0000D5DC03000A48026803210A4302600948804709480047FEE7FEE7FEE7FEE7FEE797
+:20DD2000FEE7000005480649064A074B70470000240500404DDD0300C1C003009830002007
+:20DD4000983C00209834002098340020F8B500F035F82B4E002804D02A4870602A49F01300
+:20DD600088612A480124018CC9B201290DD1818C09070AD1018D0906090F042905D1808D56
+:20DD80000006000F01D1224884600027B461214D6F60A8058460686800280ED1C820FEF790
+:20DDA00005FA1D487F1C8742F5D30020B06101208007846068680028FCD0F8BD1348018CB5
+:20DDC000C9B2012917D1818C090714D1018D09060A0F03D1828D1206120F0ED0090F0129C2
+:20DDE00003D1828D1206120F07D0032903D1808D0006000F01D0002070470120704700008E
+:20DE000000050040DFFF07C0006C0040C00F00F000060040000100408813000030B585B071
+:20DE2000002822D00388FE4CA34220D0FD4B1B78002B1CD0FB4B10255B1C1D7059700024C0
+:20DE400001259A70032269460A820094019402940394028A0A808D708C8004A902910393E7
+:20DE600000886946A6DF05B030BD0E20FBE70820F9E7F0B58BB0044602276846077300268B
+:20DE800009968784C68408A80A900D46A18A208809AAA5DF002804D0E16A00291AD08847BE
+:20DEA00018E06846008CC007C00F13D068460682208803A9A8DF002813D1A97E28461B30BA
+:20DEC00001220B0001F055FC09430F1B202224263E284300FF20FE3069460882208803A94D
+:20DEE000A8DF0BB0F0BD00960AE0062219E069460A71029022E0204690470020F1E700920D
+:20DF00002B8B022BF3D2F0E700971DE003201AE0042018E0052016E0298B032905D20322BE
+:20DF200008212046FFF77AFFDBE741780278080210436946888003D006200090A26ADAE784
+:20DF40000720FAE7092000906946A26AD3E70322E7E730B585B00D46040038D0002D36D0EC
+:20DF60006868002833D00020C043AF4B20800FCB049301AB07C3AD4869460880891C01A888
+:20DF800063DF002822D1221D69460120A0DF00281CD168468078A071204600F0CEF8002886
+:20DFA00014D1204600F055F900280FD12946204600F002F9002809D16868A062A868002804
+:20DFC00000D0E06297490120087000204BE70E2049E73EB5002828D0002926D0826A002ABE
+:20DFE00023D00A88102A21D0112A30D0502A1FD0512A1AD104460846891D0A78022A14D196
+:20E000004A88238A9A4210D1807A04280DD006280BD0052809D0891C2046FFF72AFF002860
+:20E0200003D0E16A002900D088473EBD898810E0CA8803899A42F8D1082200928A7F6B4605
+:20E040001A7120310291826A694690473EBD0021C94301803EBDF0B585B00A4605002DD00F
+:20E0600028886F4988422BD06E480078002827D06C4C1020641C2070072060700127A770F8
+:20E080000321684601820026E11C104600F04CF801466846008A0918684601820096019680
+:20E0A00002960396298A01808770868004A80394029028886946A6DF05B0F0BD0E20FBE7D3
+:20E0C0000820F9E7F0B585B00A46050028D028885349884226D053480078002822D0514C3B
+:20E0E0001120641C20700127684607820026611C104600F019F801466846008A0918684638
+:20E1000001820096019602960396298A01808770868004A80394029028886946A6DFCBE782
+:20E120000E20C9E70820C7E70870020A4A70020C8A70000EC8700420704730B58FB0054655
+:20E140001C21684601F022FA694608780421084369460870002401940394049405940694E6
+:20E16000A87908A9887031486946801C0884601C00070794000F0C77103048778A7FF920B4
+:20E180000240921CE7200240012002438A77142109A801F0FBF908A8099007A80A906946D3
+:20E1A0008C851420CC8508860D942B46A888083309AAA2DF0FB030BDF0B58FB00F4605465A
+:20E1C0001C21684601F0E2F968460178022631430170002401940394049405940694A97917
+:20E1E00008A8817011496846091D0184601C0107090F103168460794017700200146684618
+:20E200004177817FF9200140891CE72001400120014368468177142109A801F0B7F907E086
+:20E22000FFFF000088280020FCF703003015000008A8099007A80A9068468685C4850686B5
+:20E240000D972B46A888203309AA6946A2DF0FB0F0BD30B58FB005461C21684601F096F9FD
+:20E2600069460878082108431022104369460870002401940394049405940694A87908A962
+:20E280008870144869460884601C00070794000F0C7710304877887FF9210840801CF72123
+:20E2A000084010430121084369468877142109A801F06CF908A8099007A80A9069468C851A
+:20E2C0001720CC8508860D942B46A888103309AAA2DF6FE731150000FFB583B0074600207F
+:20E2E0000C9C8646267805463AE07868A90041180A88684682804988C1800022694601A8F7
+:20E3000065DF002810D1684601780598814226D17046002801D0002200E002222078891824
+:20E3200041181F2902D90C2007B0F0BD7146002908D1401CC0B2411C069B049A21701A54AF
+:20E3400001208646217806980A18694601A865DF0028E9D1694620780978401820706D1CC0
+:20E360003888A842C1DC7046002804D020780699801B401E88550020D6E7F8B51546069C10
+:20E380001E46074602220094FFF7A6FF002806D133461022294638460094FFF79DFFF8BD07
+:20E3A000F7B582B000260546167000681446002805D02846039900F0CAF8060008D168794D
+:20E3C00000281ED02078039F001D1F2802D90C2005B0F0BD684679DF0028F9D1217803226A
+:20E3E000481C20707A5421781922481C20707A542078C1196846008800F0A4F821784018A0
+:20E400002070A8790223002810D02078039A411C2170135420780399471C012227700A54E5
+:20E420002078AA79471C039927700A54A868002815D00021415620788C460246C01C03992E
+:20E440001F28C4D8501C20708B5422780A23501C20708B5420786246431C23700A54A8899B
+:20E46000002809D028460094062202210C30039BFFF783FF0600ABD1A88A002809D02846D9
+:20E480000094072203211430039BFFF776FF06009ED1A88B002809D0284600941522142137
+:20E4A0001C30039BFFF769FF060091D1686A002805D02246039900F07FF8060088D1A86A01
+:20E4C000002805D02246039900F0B5F8060084D13020405D002806D022462846039900F0F6
+:20E4E000DCF80600C7D1304672E770B50C4692B000216A46117007251171002809D0817927
+:20E5000049070CD502A9FFF74BFF002808D102AE00E00026002C0ED0A079002802D028469D
+:20E5200012B070BD01AA0AA92046FFF739FF0028F6D10AAA00E0002268460379017830463C
+:20E5400072DFEDE70870000A487002207047F8B514780746A01C15460E461F2803D83879BF
+:20E56000801C1F2801D90C20F8BD1D20001B80B26946864608803019801C7DDF0028F3D143
+:20E580003868022805D168460088704501D8092107E038790821002801D0704501D96846F6
+:20E5A0000088421C3255641CE2B2B1542978801C081828700020F8BDF8B50D461178064636
+:20E5C000881D14461F2801D90C20F8BD33880720062BFAD31927FF01BB4202D94D4A9342D6
+:20E5E000F3D17288062AF0D3BA4202D9494FBA42EBD1484FBB4203D0BA4201D09342E4D87E
+:20E60000481C052220706A5420781222411C21702A54207841193088FFF794FF21784018C5
+:20E62000C0B2207041197088FFF78CFF2178401820700020F8BD70B5054600790E46801CD6
+:20E640001446C0B21178821C8A181F2A01D90C2070BD0A46491C401C2170B0542078FF224A
+:20E66000411C21703254207881192888FFF76AFF21784018C0B22070AA88002A09D0A968AC
+:20E68000002908D0801900F022FF2078297940182070002070BD072070BDF7B582B0029894
+:20E6A0001446C06A0F46002832D0029800252030009028E00298C16A0C2068430E18217855
+:20E6C00030794A1CC01C2270785421781622481C20707A542078C1193088FFF733FF217873
+:20E6E0004018C0B22070B288002A09D0B16800290ED0C01900F0EBFE207831794018207087
+:20E700006D1C0098EDB2007CA842D3D800205FE607205DE6FFFF000038B56749674A48883D
+:20E7200090420FD04A78664C521CD2B24A70237B934208D3083175DF002803D0A1690029FF
+:20E7400000D0884738BD00254D70217C002907D03B2176DF002803D0A169002900D0884728
+:20E7600061690029EED068460095884738BD70B5054601461C225248FDF75AFD4E4C002647
+:20E7800026702968002907D00822A01800F09FFE204608307ADF02E0474808307BDF0028C1
+:20E7A00008D1401E608044486670464A0021001DFFF7D6F870BD10B53F484068FFF769F9D5
+:20E7C00010BDF8B53C48103000F069F800263A4D3B4C002806D06169002919D001200090EB
+:20E7E000684614E02878002804D0616900290FD00096F5E7687800280CD0A16800226868B8
+:20E80000FFF70AF9002803D0A169002900D088472E70F8BD6168F1E7F8B5294C028800276B
+:20E82000254DE689102A18D029464968112A21D0122A2DD0502A0FD1801D0288B2420BD1FF
+:20E84000028B022A08D1C27E837E10021843C007C00F13D0FFF7B5FFF8BD81886980014667
+:20E86000154808221631103000F031FE6F70002EF0D0F8BD0020C04368806F700846FFF7BB
+:20E8800008F90028F5D0A1690029F2D08847F8BD811D09480822103000F019FEDAE7418827
+:20E8A000054808300288914204D34088814201D8012070470020704790280020FFFF0000B6
+:20E8C000CC2D002019E7030031B5054C04E0401E00902046FDF77AFC00980028F7D138BDC6
+:20E8E000E703000018225043FE4A00218018017181604161012281610261C1607047FFB577
+:20E9000081B0F94C049B039A054626691A4303200092002E03D1002A0ED001222261276919
+:20E92000039A0126360792003B0000F022FF072707162940526127000222EFE770693269FC
+:20E9400092B25043326933691204920C9BB2594329DF002812D102210FE0084628DF00286A
+:20E960000CD10399002901D0032106E00499002916D12978042946D017E0216105B0F0BDAE
+:20E980007069326992B25043326993B24B4301461846039A29DF0028F0D10499002901D0F4
+:20E9A0000421EAE72978042920D00521E5E773693069366980B2434368681B189B18B6B2C7
+:20E9C0004E43301880181946049A29DF0028E9D0D4E7306980B24843696880188A08696902
+:20E9E00029DF0028CAD1009900290CD00621C4E77069316989B24843316989B200F0D9FD08
+:20EA000028DF0028BAD10721B7E7F8B5B54918230A780F205A435418241DB3492278266970
+:20EA2000CF68022A1BD001252D07042A2AD0052A5BD1286981B2304600F0BBFD0146A36877
+:20EA400028699A1980B24843101A820860681818861928694B1C80B25843801B34E0B8023C
+:20EA600062686169121A0918A3683018181801239B029A4202D2920829DF31E0FF220132BA
+:20EA800029DF2DE0E268974914205043F4314018001D0BC8B04203D160685943814218D02E
+:20EAA000022A16D0286981B2304600F082FD0146286980B24843301A820828694B1C80B208
+:20EAC000584363689B19C01A83082046FFF717FF06E0286981B2304600F06BFDC01928DFED
+:20EAE000002802D17F4901228A70F8BDF8B57D4C069E65780A2D1DD027787D19EDB20A2D5B
+:20EB000001D30A3DEDB218277D432D192871AA6103C9EE60AB6069612861A1780020002978
+:20EB200004D1FFF772FF112800D100206178491C6170F8BD0420F8BD38B5024669481823B1
+:20EB400001785943081803690179022B0AD014246343644CF434E4588368009383691030F7
+:20EB6000A04738BD604B14331C68F5E7F8B55D4B9978012914D100255B499D700A69082A77
+:20EB800005D002280FD003280AD10D2006E0022807D00D7000F025FA002801D0FFF7CCFF37
+:20EBA000F8BD0D61F6E74F48182403784E496343CC681818641C001DCC600378022B05D11F
+:20EBC0004668A102B14201D3012700E00027052B01D1072A03D00021042B02D003E00121C1
+:20EBE000FAE7072A03D00026042B02D007E00126FAE74068A302834201D3002A1AD0002000
+:20EC0000314301433943C5D0374E28463561FFF793FF344C2078FFF765FEF5606078401E1E
+:20EC200060702078401CC0B220700A28B2D30A382070AFE70120E3E770B500252A4C2948D3
+:20EC4000E56025610570457085702E463046FFF749FE761C0A2EF9D3012212076560516952
+:20EC600028461269491E92B25143E560A1601D49F4310D608D600D61CD601B4914310D6090
+:20EC8000888001212170206170BDF8B5164A044610780E46002830D0002C30D0002E2ED058
+:20ECA000206800282BD0012000076768016989B28F4228D8102F26D3A168002923D09568E2
+:20ECC000794343694A19006980B243439A421AD801200007006980B2814212D901200007E1
+:20ECE000006903E0E82D0020A828002080B2394600F05FFC002906D103E00820F8BD0E20B9
+:20ED0000F8BDB80701D00720F8BDBD49486801281CD00F461421BB4A21C641438E18756092
+:20ED2000236853506168B160A168F160A268616800235143012212075B1C14699BB2A4B214
+:20ED40008C4205D21469A4B2091B02E00420F8BD00211469A4B265191469A4B28C42EBD985
+:20ED6000BD60401C336178600020F8BDF8B50446A3481E46007815460F46002807D0002F3D
+:20ED800007D0002C05D02068002817D103E00820F8BD0E20F8BD9B48016800290ED0C268E3
+:20EDA000816840684A4310186268904206D9002D04D0A94202D3A819884201D90720F8BD90
+:20EDC000384600F008F9002811D0304600F003F900280CD0606800F0FEF8002807D02B4637
+:20EDE0003A46214602200096FFF780FEF8BD1020F8BDFFB5824881B000781F4616460D462B
+:20EE0000002808D0002D08D00198002805D02868002817D103E00820B0E50E20AEE5794C91
+:20EE2000206800280ED0E168A0686268414389186A68914206D9002E04D0B04202D3F119AD
+:20EE4000814201D9072099E5019800F0C4F800281BD0384600F0BFF8002816D0686800F025
+:20EE6000BAF8002811D068683246C119019800F02EFB00962868142148432458002203215B
+:20EE80002846019BA047002078E5102076E5F8B505465B480F460078002805D0002D05D012
+:20EEA0002868002821D103E00820F8BD0E20F8BD544C00262068002817D0A168E0684843CC
+:20EEC00061684118686881420FD900F084F800280DD0296814225143091968684A68896834
+:20EEE000801A00F066FB002903D00720F8BD1020F8BD3B460022294604200096FFF7F6FDB5
+:20EF0000F8BD3F4A1278002A0DD000280DD000290BD00268002A08D0394A14321368002B3E
+:20EF200005D004207047082070470E20704702230B600068106000207047F8B504463048AF
+:20EF40001E46007817460D46002807D0002D07D0002C05D0206802281BD103E00820F8BDC3
+:20EF60000E20F8BD264814300068002811D0084600F031F800280ED0304600F02CF800286C
+:20EF800009D03B462A46214602200096FFF7AEFDF8BD0720F8BD1020F8BD08B5184A1278C8
+:20EFA000002A05D0002805D00268022A11D103E0082008BD0E2008BD114A14321268002AD5
+:20EFC00007D00B460022014604200092FFF78EFD08BD072008BD800701D000207047012068
+:20EFE0007047084910B5F43949780020002906D0FFF70BFD002802D0112800D1002010BD48
+:20F00000A8280020DC2E002070B500250C290ED304464318008941000919581A0A38C2B2BD
+:20F020001748022A027002D30A318B4201D2092070BD144800F04BFA134914480A8882422E
+:20F0400002D02388934217D14988814202D06088884211D10D4A0323521E20891B03A842DE
+:20F060000AD9690009194989914203D09E896D1CB142F4D1002070BD0B2070BD00207047C6
+:20F08000C4280020F02E002080100010FFFF000010B5FDF7ABF810BD10B50446002A02D054
+:20F0A0001088002210E00A48FBE7030A00020343A05C584003061B0F43401803584083B2EB
+:20F0C0001806C00C5840521C8A42EED310BD0000FFFF00004B48002101704C484A4A026039
+:20F0E0008160C160016108224161426081610846704710B500291DD000220A60434A5368A8
+:20F10000002B1BD0202817D85B1E5360D0682423401CD060106914684343E3180B60012366
+:20F1200083409169401C19434007400F91611061002010BD0E2010BD0C2010BD042010BD8F
+:20F14000F0B5324A0646916800292BD057691020791A4907490F14680B4624254D436519D6
+:20F16000B54206D1012495698C4065400020956104E0491C4907490F8F42EED1491C4E07DC
+:20F18000760F956901210C469C402B4623420AD19368002B07D05B1E936053685B1C53609D
+:20F1A0003346F0E70420F0BD184A2423117C1268491E4907490F594320315050002070470B
+:20F1C00070B500281AD0002918D0104AD368002B16D05B1ED360936824265B1C936053692A
+:20F1E00015681C467343EE1820330660E858641C08606007400F5061002070BD0E2070BD84
+:20F20000042070BDC5280020FC2E00201C30002030B5CB0008339DB293070024002B01D0E6
+:20F22000072030BD3B4B9A605219DA605C701C7058809980002030BDF7B5364C0E466088D5
+:20F24000814237D8344F00F069F822786078A188884201DA401C00E00020C0B2904202D155
+:20F2600000F062F824E065786078884201DA401C00E00020607000F057F8BD4218D0A0688C
+:20F28000EF000299C151009900290CD0002E0AD0608832464543E068281800F018F9A068B3
+:20F2A0003818868002E00021381881800020FEBD0420FEBD0920FEBD0EB504E068468188A8
+:20F2C000029A0098904702AA01A9684600F003F80028F3D00EBD70B50E4B05241D785E786C
+:20F2E000AE4215D01D781C789E88B44201DA641C00E000241C705C88DE686C43A41904600F
+:20F300009B68E800C418A4880C80185800241060204670BDCC280020FFFF000072B606484F
+:20F320000168491C0160704703490868401E086000D162B670470000DC280020BFF34F8F11
+:20F3400003490248C860BFF34F8FFEE70400FA0500ED00E010B5002904D000221146104619
+:20F36000FFF7ECFF00F010F810BD10B50021024A0846FFF761FF10BD55F3030010B50846E6
+:20F380001146FCF771FF10BDF8B5384C2078002837D02069002807D00026E068002805D0FB
+:20F3A0000025002E04D013E00126F6E70125F8E7684651DF052806D0002806D000221146D2
+:20F3C000FFF7BCFF04E0012602E0216900988847002D12D1608869460880A06861DF0528FA
+:20F3E00006D0002806D000221146FFF7A7FF04E0012502E0E168A0688847002ED8D0002D15
+:20F40000CFD0F8BD70B5002901D08C0701D0072070BD164C0125A16062801549636010DF46
+:20F420000028F5D1257016202EDF70BD002803D00E49C860002070470E207047002803D0A8
+:20F440000A490861002070470E20704710B507484068002807D08047002803D0002211463E
+:20F46000FFF76CFF10BDFFF78FFF10BDE02800207DF30300034610B50B439B070FD1042A66
+:20F480000DD308C810C9121FA342F8D018BA21BA884201D9012010BD0020C04310BD002AAC
+:20F4A00003D0D30703D0521C07E0002010BD03780C78401C491C1B1B07D103780C78401C61
+:20F4C000491C1B1B01D1921EF1D1184610BDF8B5042A2CD3830712D00B78491C0370401C25
+:20F4E000521E83070BD00B78491C0370401C521E830704D00B78491C0370401C521E8B07F9
+:20F500009B0F05D0C91ADF002023DE1B08C90AE0FCF78EFEF8BD1D4608C9FD401C46B440B8
+:20F520002C4310C0121F042AF5D2F308C91A521EF0D40B78491C0370401C521EEAD40B78EC
+:20F54000491C0370401C521EE4D409780170F8BD01E004C0091F0429FBD28B0701D50280F7
+:20F56000801CC90700D00270704700290BD0C30702D00270401C491E022904D3830702D5EE
+:20F580000280801C891EE3E70022EEE70022DFE70378C2781946437812061B0219438378A2
+:20F5A000C0781B04194311430902090A000608437047002203098B422CD3030A8B4211D366
+:20F5C00000239C464EE003460B433CD4002243088B4231D303098B421CD3030A8B4201D39D
+:20F5E00094463FE0C3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B422D
+:20F6000001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524193
+:20F6200083088B4201D38B00C01A524143088B4201D34B00C01A5241411A00D201465241FB
+:20F64000104670475DE0CA0F00D04942031000D34042534000229C4603098B422DD3030A47
+:20F660008B4212D3FC22890112BA030A8B420CD3890192118B4208D3890192118B4204D305
+:20F6800089013AD0921100E08909C3098B4201D3CB01C01A524183098B4201D38B01C01A88
+:20F6A000524143098B4201D34B01C01A524103098B4201D30B01C01A5241C3088B4201D37F
+:20F6C000CB00C01A524183088B4201D38B00C01A5241D9D243088B4201D34B00C01A52417F
+:20F6E000411A00D20146634652415B10104601D34042002B00D54942704763465B1000D31A
+:20F70000404201B50020C046C04602BD704770477047754600F022F8AE460500694653469B
+:20F72000C008C000854618B020B5FEF7FBFA60BC00274908B6460026C0C5C0C5C0C5C0C525
+:20F74000C0C5C0C5C0C5C0C5403D49008D4670470446C046C0462046FCF7FFFC004870479C
+:20F760003830002001491820ABBEFEE726000200704730B47446641E2578641CAB4200D256
+:20F780001D46635D5B00E31830BC184702000000000000000000000000000000040000009F
+:20F7A000000000000000000000000000000000000000000035C4030000000000000000004D
+:20F7C000020000000000000000000000000000000000000000000000030000000000000024
+:20F7E0000000000005000000000000000000000000000000000000000000000023D1BCEA6A
+:20F800005F782315DEEF1212000000002CF8030000280020F400000004C1030020F90300A1
+:20F82000F4280020A413000020C103000000000000000000000000000000000000000000F1
+:20F840000000000000000000000000000000000000000000000000000000000000000000A8
+:20F8600000000000000000000000FFFF000000003200000000000000000000000000000058
+:20F88000000000000000000000000000000000000000000000000000000000000000000068
+:20F8A000000000000000000000000000000000000024F40000000000000000000000000030
+:20F8C000000000000000000000000000000000000000000000000000000000000000000028
+:20F8E000000000000000000000000000000000000000000000000000000000000000000008
+:20F900000000000000000000000000000000000000000000000000000000000000000000E7
+:20FC00000100000000000000FE0000000000000000000000000000000000000000000000E5
+:020000041000EA
+:0410140000C0030015
+:040000050003C0C173
+:00000001FF
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/bootloader/s130_nrf51_1.0.0_bootloader.hex	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,463 @@
+:020000040003F7
+:20C00000983C002005DD030017DD030019DD03000000000000000000000000000000000057
+:20C0200000000000000000000000000069C1030000000000000000001DDD03001FDD0300D7
+:20C0400021DD030021DD030021DD030021DD030021DD03000000000021DD030021DD0300D9
+:20C0600021DD030021DD030021DD030021DD030021DD030021DD030021DD030021DD0300B8
+:20C0800021DD030057D8030021DD030021DD03006DD8030021DD03004DF4030021DD0300DD
+:20C0A00021DD030021DD03000000000000000000000000000000000000000000000000007E
+:20C0C00000F002F800F040F80CA030C8083824182D18A246671EAB4654465D46AC4201D18E
+:20C0E00000F032F87E460F3E0FCCB6460126334200D0FB1AA246AB463343184710370000C8
+:20C1000030370000103A02D378C878C1FAD8520701D330C830C101D504680C6070470000D3
+:20C120000023002400250026103A01D378C1FBD8520700D330C100D50B6070471FB5C04655
+:20C14000C0461FBD10B510BD03F0E3FA1146FFF7F5FF00F0D3F803F0FBFA03B4FFF7F2FF19
+:20C1600003BC03F0FFFA00000648704502D1EFF3098101E0EFF30881886902380078024A97
+:20C1800010470000FDFFFFFF39D50300401E00BF00BF00BF00BF00BF00BF00BF00BF00BF28
+:20C1A00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BFB4
+:20C1C00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BF94
+:20C1E00000BF00BF00BFF1D170470000056885F3088846680A4AEFF305839A42304602D183
+:20C20000084CA6463047074C064D0646064FF0B4034C034D024E024FF0B404480047000005
+:20C2200000000000FFFFFFFF00000021F9FFFFFF70B505460C46164602E00FCC0FC5103EEE
+:20C24000102EFAD2082E02D303CC03C5083E042E07D301CC01C5361F03E021782970641C63
+:20C260006D1C761EF9D270BD0A4610B50146664803F064F810BD10B502F078FC10BD10B5C6
+:20C28000624C86B01ECC03946C460EC4002807D0684618DF002803D00022114603F04EF864
+:20C2A0000F20800313DF002803D00022114603F045F8574B48225749092003F0A3F80028AB
+:20C2C00003D00022114603F039F800200490059001206946087404A860DF002803D0002251
+:20C2E000114603F02BF84C4803F0A8F8002803D00022114603F022F806B010BD08B547485A
+:20C30000C169B12943D0002445480F2140698903884204D000221146104603F00FF8012068
+:20C320000007006901218902884204D000221146104603F003F83B4800903B4B05220321A1
+:20C34000002001F0BAFA002803D00022114602F0F5FF00F067FC00F0AAFC012500281AD09D
+:20C3600000F0B4FC002803D00022114602F0E6FF20466840FFF783FF00F038F800F0CCFC74
+:20C3800000280ED00022114602F0D8FF09E001240021C161B8E720466840FFF770FF00F002
+:20C3A00025F803252D03002C04D1A86800F090FB002807D100F047FC002803D000221146D5
+:20C3C00002F0BCFFA86800F083FB002806D000F06EFC002802D1A86800F041FCBFF34F8F12
+:20C3E00013491248C860BFF34F8FFEE7094A10B548321421082002F00BFF002803D00022E2
+:20C40000114602F09BFF10BDEFBEADDE8CF703006BF30300342B002077C20300000500404D
+:20C4200000100010EFDC0300F42800200400FA0500ED00E070B5FC4C1E46A06815460229A3
+:20C4400002D0042916D108E0052813D1A369002B10D03246294604200BE002280AD1F348B0
+:20C46000406880470320A060A369002B02D0324629469847280003D00022114602F05EFF98
+:20C4800070BD4CB5E84E0120307005200195009400F058FB4CBD10B5E34C2078002801D057
+:20C4A000082010BD206901F0F4FA002803D00022114602F043FF0F2100228904206901F01E
+:20C4C000ABFA040003D00022114602F037FF204610BDD54910B5D448243141610221816012
+:20C4E000C168243002F059FD002803D00022114602F024FF10BDCC4910B5CB481C31416145
+:20C50000022181600320000380680F218903081A4108C5481C3002F040FD002803D000223D
+:20C52000114602F00BFF10BD704700B589B01822BF4902A8FFF77CFE06980799009001917A
+:20C5400002A80FC800F0FEFA09B000BD00B5B64987B049886A461181032109038968069146
+:20C56000B249012050394A6803928A680492C9680591069A0091019202A90EC900F0E2FA6E
+:20C58000002007B000BD30B5A84CA748503C89B02430E16802F001FD002803D00022114679
+:20C5A00002F0CCFEA048E2681C3041680023083002F0C3FC050012D1182102A802F0E6FFEA
+:20C5C00000209949029049886A469181E1680691079A0091019203A90EC900F0B3FA284601
+:20C5E00009B030BD00B5904987B049886A4611818E49032050394A6803928A680492C9683A
+:20C600000591069A0091019202A90EC900F09AFA0020B6E73EB5864A6B46183207CA07C3A4
+:20C62000814D00246C7029466C802431684602F068FC002801D0AC603EBD03207A4900038F
+:20C6400080682431486024390A46526ACA610F218903091A490840187349764A1C31486068
+:20C6600071480021103001F07BF9002803D00022114602F063FE0F2100228904286901F013
+:20C68000CBF9002803D00022114602F057FE01206C60A86000203EBD63498861704770B59A
+:20C6A000426862481468536891685038D26804604360C26081600078440701D5840705D130
+:20C6C0009C0703D18C0701D1940701D0062070BD5B189A18544D0F239B02EA60994213D81A
+:20C6E0005549564B514CC60709D08868181A90420AD3534820605348606053480FE08968F6
+:20C70000591A4908914201D20C2070BD4F4921604F496160800701D54E4800E04E48A0607B
+:20C72000A868012802D00826304670BDFFF7B3FE0600FAD12168E8688847F5E770B50500F7
+:20C7400004D0287A800703D0102070BD0E2070BD354CA068032805D0042801D0052803D0CB
+:20C76000082070BD0520A0606868E168860060688019884204D90020C04360600C2070BD5C
+:20C78000FFF789FE0028FAD1A96832466368606902F0D3FB0028F2D1616889196160E268EB
+:20C7A0009142ECD0092070BD10B51F4C08206168002900D010BDA1680429FBD11B4861786F
+:20C7C000403802F021FC002802D00021617010BD0521A16010BDF8B5134C0746A068032899
+:20C7E00004D0042804D008252846F8BD0420A0606068002801D00820F8BDFFF74CFE05000E
+:20C80000FAD17868860060788119402901D90920F8BD064AB968403A1018324602F057FE82
+:20C82000607880196070DFE7002800201C2D00209CF7030083C403000030000000C003006D
+:20C84000D3C403002BC503004DC50300F7C4030029C50300E5C5030087C5030010B5894CF1
+:20C86000A068052813D1E168606888420FD10620A060FFF710FE002808D16069E1684068FF
+:20C8800002F0FCFB002801D10721A16010BD082010BD10B57B488168072901D0082010BD63
+:20C8A000006901F0F6F8002803D00022114602F045FD75488068804710BD1CB506200195C2
+:20C8C000009400F03FF91CBDF8B51C4617460D46064600F0C1F8002817D001200003854215
+:20C8E00007D92346291B301B1A46FFF7EDFF00280BD13A462946304600F0B9F8002804D117
+:20C900003A462946304600F0A7F8F8BDF0B589B0684600F015FA049800282AD001210903F7
+:20C92000079A4018904226D9501A45081046049A0C468718024668001618001908900320DF
+:20C9400000038068049988420DD261190846042200F08DF800280CD121460422084600F073
+:20C9600086F8002805D1BA1B2B4630460899FFF7ABFF09B0F0BD049A079800F078F8F8E75C
+:20C9800000B58DB004A800F0DBF9099800280DD0089800280CD008990B984018019000219D
+:20C9A0000998009180080290684618DF0DB000BD0320000380680F218903091A4908ECE7FB
+:20C9C00000B58DB004A800F0BBF909980028EDD00F210898890300280CD0089A0B98019158
+:20C9E0008018029003220998009280080390684618DFDBE70320000380680A1A5208EEE7D2
+:20CA000030B591B0684600F09BF90498002814D001210903079A4018904214D9501A43087B
+:20CA20001046049A5C0082180019611803242403A468049DAC4202D20E2011B030BD121AB5
+:20CA4000FFF742FFF9E703200CAB07C3049880080F900CA818DFF0E71FB5032301909008B3
+:20CA6000039000930291684618DF04B010BD1FB5012301909008039000930291684618DF58
+:20CA8000F3E70000002800201C2D002010B5BB480368012B02D1022900D10160100003D099
+:20CAA0000022114602F04AFC10BD10B5B34C48DF002803D00022114602F040FC02F0FCFB82
+:20CAC0002068022803D0032801D00428EFD110BD38B50068401C19D00024684600F058F96F
+:20CAE00000980168012910D1818800290AD0C168032000038068002202F0CEFA0099898861
+:20CB0000814201D1012400E00024204638BD10B504469A482021001D02F0B9F9002803D00E
+:20CB20000022114602F00AFC9448002320222146001D02F01BF9002803D00022114602F053
+:20CB4000FDFB10BD0FB4F8B5684600F021F96846818B069D0122894CFF238948002D13D090
+:20CB6000012D17D0032D2BD00021022D37D02A46052D46D0042D4ED0062A01D10420206071
+:20CB8000F8BC08BC04B0184781800A9983600260C16010E08180099D089949190A9D49195D
+:20CBA000C160A52183600160089901610999856141610B99C16122607148FFF7A8FFDFE7B9
+:20CBC00000990B6803608B888380C968C160AA21816008990161099941610A990BE0009D60
+:20CBE0002E68A52E09D00660AE888680ED68C5600161836041618161DDE781800360C160C5
+:20CC0000F6E700F085F9002803D00022114602F095FB0320B3E781800360C1600099896807
+:20CC20008160C9E70EB557480090202001900120029002F001F8002804D150496846091D98
+:20CC400002F023F80EBD10B5FFF7E4FC002805D100F02FFB0446FFF728FF204610BD70B58A
+:20CC600011DF002803D00022114602F067FB464900200B68444C012180340A4682401A4206
+:20CC800004D0C506ED0E0A46AA402260401C2028F3D303242403A06813DF002803D000226F
+:20CCA000114602F04BFBA06802F0F2F970BD08B5684600F06DF800980168A52904D0806888
+:20CCC000AA2801D0002008BD012008BD10B5FFF797FE002803D1FFF773FE00281BD064209C
+:20CCE00001F0F2FDFFF712FE002803D00022114602F024FBFFF784FE002803D000221146DD
+:20CD000002F01CFBFFF73CFE040003D00022114602F014FB204610BD00B589B018221B49CA
+:20CD200002A8FFF785FA069807990090019102A80FC8FFF707FFFFF7B8FE002009B000BDB5
+:20CD400010B50E4988B0044600232022091D684602F04FF80098206068468088A08003983A
+:20CD6000E0600298A06004982061059860610698A0610798E06108B010BD00002C280020E6
+:20CD8000282D00208DCA030000E100E0C0F70300014901607047000000FC030008280CD0DC
+:20CDA00004DC002807D006280FD108E00B280AD00C280AD105E001207047022070470320C9
+:20CDC000704704207047042901D0062070470520704770B515460A46032823D0042820D1FF
+:20CDE000FE4C002906D0E088FD49884219D0132176DF10E0284602F0A3F9002803D00022F7
+:20CE0000114602F09BFAE069A8420AD101220321F44801F003F8002803D00022114602F051
+:20CE20008DFA70BD01211046FFF7B8FF02460121EEE7F0B5054608790E4685B081070CD07C
+:20CE400003221146284600F0E9FF002803D00022114602F073FA05B0F0BDE04900901831D9
+:20CE600002F047F9010011D1DC4CB168009AA06902F02DFB009802F097F9010006D1204647
+:20CE80006946183002F09CF9010003D0284600F0AFFAE0E704200190009880080290A06902
+:20CEA000039001A8FFF74AFC07000BD0092F10D0A06902F045F9010002D0284600F098FA04
+:20CEC0003946E3E73079616940186061A069E061C1E7307961694118616160780028BAD073
+:20CEE0006089401E0004000C6081B4D1284601F0E9F8002803D00022114602F01FFA20890D
+:20CF00006081A8E710B50022114602F017FA10BD10B5B24C01202070E088B149884208D01B
+:20CF2000132176DF002810D00022114602F006FA0BE0A078002808D074DF002803D0002282
+:20CF4000114602F0FBF90020A07001F034FC002803D00022114602F0F1F9002010BD70B5E1
+:20CF60000D68044601209D4A2B0002F002FC0A2B3043061320575C466012FFF76FFC0421FD
+:20CF8000FFF70CFF024604212EE00022114602F0D5F970BDFFF7BCFF002803D0002211468A
+:20CFA00002F0CCF9FFF775FC002808D170BDFFF7AFFF002803D00022114602F0BFF9FFF76D
+:20CFC0007CFC70BD106188680078107170BD02201061886800780128F8D1FFF7E5FB02213F
+:20CFE000FFF7DCFE02460221204600F017FF0028CBD170BD0320106170BD12692046012ACC
+:20D0000006D0022A07D0032AF6D1FFF712FF70BD00F001FA70BD00F03BFA70BD50708888D5
+:20D020001081508170BD00205070108170BD2046516901F010F8DAE710B5044669488EB0EB
+:20D0400081796846817068490180342101A802F09DFA022001900021684641728472012131
+:20D0600001820590002101A801F03FFA002803D00022114602F062F90EB010BDF0B5574C10
+:20D080008BB0A07800283AD156481821183802F07DFA2046534CC078183C00250126002875
+:20D0A00037D02746483700950195029510226946F81D039502F0DEF9002822D0F81D08909D
+:20D0C00009976846067509A804906846067708A806900420FFF7B0FF25700220207204A813
+:20D0E000E060282020823F486582183873DF002803D00022114602F021F9384886700BB045
+:20D10000F0BD0520FFF798FF2670676025722582E9E70620FFF790FF257065602572E0E7E2
+:20D1200070B52E4C01880022E588A6B017290AD01EDC11293FD008DC022977D0102902D123
+:20D140008088E080A27026B070BD264C303426461836132951D01429F5D1C289638D002106
+:20D160009A4200D1314600238088E21D82DF1BE0512970D00EDC18296CD01929E3D18079F5
+:20D180000028E0D1A270E068401EE0604FD0FFF775FFD8E7522976D05529D4D18079002871
+:20D1A000D1D11321284676DF0028CCD00022114602F0C4F8C7E78020694688803220E06054
+:20D1C000012301AA06A92846AADF002803D00022114602F0B3F82078002807E038280020A2
+:20D1E000FFFF0000602D00203015000001D1FFF745FF0020C043E080A5E70722C14910A839
+:20D2000002F065F91022E11D0CA802F060F91C22314612A802F05BF90CA80A9012A8099039
+:20D2200006ABB94A852128467FDFBDE70DE01822B64906A8FEF7FCFF0A980B9900900191F8
+:20D2400006A80FC8FFF77EFC7DE70021284667DFAAE700E017E0817900299AD0807A042885
+:20D2600003D0062801D0052893D1022909D0012069460872FF208330888102A92846A8DF82
+:20D2800092E70220F4E700F08DF88DE710B5044601F0C2FA9B482146303800F09AFE2046D3
+:20D2A000FFF73EFF10BD10B50022114602F046F810BD30B5944D87B00024203D2C7094483D
+:20D2C0002C6102F0B3F800286AD19248FFF7E4F901F000FF002863D18A4800F059F900288C
+:20D2E00001D10120E87011206946087207228AA102A87CDF002803D00022114602F01EF8B4
+:20D3000000940C2168460194018018214180FF2184809131C1807ADF002803D0002211469A
+:20D3200002F00CF804206946009408807C4801907C4802907348303800F00BFE002803D046
+:20D340000022114601F0FAFF1C21684602F01EF9754801900120800302900094032168468C
+:20D360000173C4810474714806900594684601F0FEF9002803D00022114601F0DFFF624910
+:20D38000E12208784008400010400C30DF22104008700720487010208870FFF76FFE0020A3
+:20D3A00007B030BD70B5584C614D203CE088A84201D1082070BDE178002914D05149012359
+:20D3C00008223431A9DF0028F4D12A460C21E088A7DF5849884204D0082802D0891C88420E
+:20D3E000E8D1002070BD00231A461946A9DF70BD10B50A46044603211046FFF7CFFC0246AE
+:20D400000321204600F00AFD002803D00022114601F094FF10BD30B5054687B000200090AF
+:20D4200001900290039038486A46203800791070364A0C3A1068926804906846069205900E
+:20D4400008790C2806D003221BE00022114601F075FFA5E78C68204600F049F80190201D5E
+:20D4600000F045F802902046083000F040F8039004A8FFF714F9002892D00121FFF78EFCB9
+:20D4800002460121284600F0C9FC0028DDD187E7FEB50446087982070ED08207920F042385
+:20D4A0009B1A0022154604E08E683554401CC0B2521C9A42F8D30871012000908868029048
+:20D4C0000879800801906846FFF785F900280DD00221FFF763FC02460221204600F09EFCB8
+:20D4E000002803D00022114601F028FFFEBD10B5044602F04DF80002E178000A09060843E0
+:20D5000010BD0000902D002058280020E4F703008DD20300D3CD0300446675546172670031
+:20D520005FCF0300A7D20300CD0C000005CF0300FFFF00000230000010B50C46002802D04D
+:20D540000120086010BD2168002911D01C48421A814212D03C2A0DD23C303C3101220B78B9
+:20D5600003701346491E401E521C3C2BF7D904E00E200BE03C2201F0AAFF00223C211048A9
+:20D5800001F08AFD0E49891E08800020206010BD70B5054600223C21094801F07DFD084C21
+:20D5A000A41E2188884201D00B2070BD3C220449284601F08CFF2088401C2080002070BD87
+:20D5C000823F00208307FF22DB0E9A408907090E994000280BDA0007000F08388308FA484C
+:20D5E0009B001B18D86990430843D86170478308F6489B001B1818689043084318607047AA
+:20D6000070B50124F24960040860F24940108860F04940398860F04D6C602F20FEF7B6FDAC
+:20D62000AC60EE4D00242F206C61FEF7AFFD2C7170BDF0B5E94F2821BC6841430D19396962
+:20D640004A1C09D028224A431619AB68B268934204D8D21AB26069623861F0BD0A4602E066
+:20D660000A46796A9B1B4E1C0BD028264E433719BE689E42F4D328264E433619B768FF1A1A
+:20D68000B760AB60696228214A4311194862F0BD70B5D24C2269A5681346114606E0814212
+:20D6A00007D00A46282671434919496A4E1CF6D170BD002EFCD08A420CD1282043435819EC
+:20D6C000406A2061401C05D1C34B01209860002363616071282041434819282381685A4310
+:20D6E000406A52195062421CE2D028225043401982685118816070BDF8B5B84C2569681CF9
+:20D7000035D0B748002640686169401A07023F0A19E028204543A0682A189068B84214D8D0
+:20D72000A3693F1A8619556A002B09D0116AD0699847002807D00022114601F0FFFD02E048
+:20D74000D169106A8847681CE3D1A178E078814206D1401CC0B2E070022801D10020E07079
+:20D760009E490006800D1C310E5000F0BAF9F8BDF8B50446994800270169009146785CE038
+:20D780009648F100C2688D1851E0601C07D0934A28209268604321468018446A24E0287854
+:20D7A000182141436A68401CC0B252182870A978884200D12F70894B516828209B6848434C
+:20D7C000C0181368012B34D1037E002B31D19368C360D368036113694361526902627F4A52
+:20D7E0005279002A00D0C7607C4BC2685B6996469C46D31A1A027B4B120A9A4202D20369C3
+:20D80000D21808E0724663469A1A12020369120A934202D99A1A826000E08760C76001222E
+:20D8200007610276921E42620846FFF702FF601CABD1287869788842A7D13046761EF6B202
+:20D8400000289DD1654801690098814201D00120F8BD0020F8BD644900200860486088607F
+:20D86000C860614940390860486045E7FEB50020C0435A4D02906869019068462E6900F07B
+:20D8800035F9074600F04FF90446002F08D002AA0199009800F08FF90298FFF769FF06E050
+:20D8A0000298FFF765FF002801D1002C02D0304600F0AAF900206871FEBDFFB59807002448
+:20D8C00081B01E4615460F4600280BD1002E09D0FFF796FE41490A9888610F703246002042
+:20D8E0008E6008E0072005B0F0BD28234343D4509B181C76401CB842F7DB28204743BB19C1
+:20D90000032048700F461846CB6019461830002218232E465E43D3005B181C705C709D708A
+:20D9200058603018521C032AF5DB0020C0433861BC70FC7001242D482405046003211420A9
+:20D94000FFF740FE224880380460254C0198A06003211120FFF736FE606878610020C2E71A
+:20D9600070B51E4CA568002D06D0002A06D0002804D00023247809E0082070BD072070BDBB
+:20D9800028265E43AE59002E04D05B1CA342F7DB042070BD282401265C432E516419E261BF
+:20D9A00061600360002070BD07494868C005C00D2CD010381CD50207120F083A9208920097
+:20D9C0005118C96919E0000000ED00E000E400E080E100E040130140001001406028002054
+:20D9E00000150140FFFF7F004011014080E200E08108B14A8900891809688007C00EC1400B
+:20DA00000806800F012803D0032803D0022070470020704701207047FEB50446A74817469E
+:20DA200082680D46002A0CD001788C4201D2052D01D20720FEBD2146282359435358012B7D
+:20DA400001D00820FEBD8818406801281DD00026FFF7AAFFC00099490190C9684018694684
+:20DA600000F018F9002812D0012144600160944949680830E2C091490198C9684118009877
+:20DA8000487000F02EF80020FEBD2E46E0E70420FEBDF8B5894D0446A868002809D0297844
+:20DAA0008C4201D30720F8BD282161434058012801D00820F8BDFFF777FFC600E86869465B
+:20DAC000301800F0E7F8002809D0022112C0E86831180098487000F004F80020F8BD04206B
+:20DAE000F8BD0120774900050860704710B5734900238A78CC78A24212D0521CD2B28A70D0
+:20DB0000022A00D18B708A786C4B92001C339A580260486910180002000A4861012010BDA3
+:20DB20000360002010BDF8B5644801690091457833E06248E900C0680E1834782AE01820A2
+:20DB400060437168641C0818B178E4B2A14200D100240168022902D003291BD113E0574A00
+:20DB600040682821926841438F18397E002911D0FFF78EFD002038760CE028277843C018B1
+:20DB80000276406A03E04D4900228B680869471CF3D108617078A042D1D128466D1EEDB2D0
+:20DBA0000028C6D1454801690098814201D00120F8BD0020F8BDF7B5404C0025A7682369E0
+:20DBC0001EE028215943C9198E68864202D9301A886017E0801B751900268E600E764E6946
+:20DBE0009C464B6AB646002E0AD0019E76193602360ACE6076460E6116684E626146116045
+:20DC0000591CDED12361FEBDF8B52C4801694A1C3DD028225143826889188E6828494C681F
+:20DC200047690079E11B0D022D0AED1C002815D10120254A00045060234A403A506021491D
+:20DC4000400080310860214908602149012008602F20FEF79BFA194901200871B54200D208
+:20DC60003546E81900021649000A4031086014494968001B091B0902090A0002C91C000A88
+:20DC8000814203D901200F4940040860F8BDFFF7B7FCF8BD42788378521C934200D10022C2
+:20DCA0000378934201D1002070470A6041684078182250430818704700E400E06028002090
+:20DCC0000015014000E200E04013014000E100E00010014010B50446082904D000221146F9
+:20DCE000104601F02BFB21686068884710BD1CB501910090024A0821684601F09DFA1CBD53
+:20DD0000D5DC03000A48026803210A4302600948804709480047FEE7FEE7FEE7FEE7FEE797
+:20DD2000FEE7000005480649064A074B70470000240500404DDD0300C1C003009830002007
+:20DD4000983C00209834002098340020F8B500F035F82B4E002804D02A4870602A49F01300
+:20DD600088612A480124018CC9B201290DD1818C09070AD1018D0906090F042905D1808D56
+:20DD80000006000F01D1224884600027B461214D6F60A8058460686800280ED1C820FEF790
+:20DDA00005FA1D487F1C8742F5D30020B06101208007846068680028FCD0F8BD1348018CB5
+:20DDC000C9B2012917D1818C090714D1018D09060A0F03D1828D1206120F0ED0090F0129C2
+:20DDE00003D1828D1206120F07D0032903D1808D0006000F01D0002070470120704700008E
+:20DE000000050040DFFF07C0006C0040C00F00F000060040000100408813000030B585B071
+:20DE2000002822D00388FE4CA34220D0FD4B1B78002B1CD0FB4B10255B1C1D7059700024C0
+:20DE400001259A70032269460A820094019402940394028A0A808D708C8004A902910393E7
+:20DE600000886946A6DF05B030BD0E20FBE70820F9E7F0B58BB0044602276846077300268B
+:20DE800009968784C68408A80A900D46A18A208809AAA5DF002804D0E16A00291AD08847BE
+:20DEA00018E06846008CC007C00F13D068460682208803A9A8DF002813D1A97E28461B30BA
+:20DEC00001220B0001F055FC09430F1B202224263E284300FF20FE3069460882208803A94D
+:20DEE000A8DF0BB0F0BD00960AE0062219E069460A71029022E0204690470020F1E700920D
+:20DF00002B8B022BF3D2F0E700971DE003201AE0042018E0052016E0298B032905D20322BE
+:20DF200008212046FFF77AFFDBE741780278080210436946888003D006200090A26ADAE784
+:20DF40000720FAE7092000906946A26AD3E70322E7E730B585B00D46040038D0002D36D0EC
+:20DF60006868002833D00020C043AF4B20800FCB049301AB07C3AD4869460880891C01A888
+:20DF800063DF002822D1221D69460120A0DF00281CD168468078A071204600F0CEF8002886
+:20DFA00014D1204600F055F900280FD12946204600F002F9002809D16868A062A868002804
+:20DFC00000D0E06297490120087000204BE70E2049E73EB5002828D0002926D0826A002ABE
+:20DFE00023D00A88102A21D0112A30D0502A1FD0512A1AD104460846891D0A78022A14D196
+:20E000004A88238A9A4210D1807A04280DD006280BD0052809D0891C2046FFF72AFF002860
+:20E0200003D0E16A002900D088473EBD898810E0CA8803899A42F8D1082200928A7F6B4605
+:20E040001A7120310291826A694690473EBD0021C94301803EBDF0B585B00A4605002DD00F
+:20E0600028886F4988422BD06E480078002827D06C4C1020641C2070072060700127A770F8
+:20E080000321684601820026E11C104600F04CF801466846008A0918684601820096019680
+:20E0A00002960396298A01808770868004A80394029028886946A6DF05B0F0BD0E20FBE7D3
+:20E0C0000820F9E7F0B585B00A46050028D028885349884226D053480078002822D0514C3B
+:20E0E0001120641C20700127684607820026611C104600F019F801466846008A0918684638
+:20E1000001820096019602960396298A01808770868004A80394029028886946A6DFCBE782
+:20E120000E20C9E70820C7E70870020A4A70020C8A70000EC8700420704730B58FB0054655
+:20E140001C21684601F022FA694608780421084369460870002401940394049405940694E6
+:20E16000A87908A9887031486946801C0884601C00070794000F0C77103048778A7FF920B4
+:20E180000240921CE7200240012002438A77142109A801F0FBF908A8099007A80A906946D3
+:20E1A0008C851420CC8508860D942B46A888083309AAA2DF0FB030BDF0B58FB00F4605465A
+:20E1C0001C21684601F0E2F968460178022631430170002401940394049405940694A97917
+:20E1E00008A8817011496846091D0184601C0107090F103168460794017700200146684618
+:20E200004177817FF9200140891CE72001400120014368468177142109A801F0B7F907E086
+:20E22000FFFF000088280020FCF703003015000008A8099007A80A9068468685C4850686B5
+:20E240000D972B46A888203309AA6946A2DF0FB0F0BD30B58FB005461C21684601F096F9FD
+:20E2600069460878082108431022104369460870002401940394049405940694A87908A962
+:20E280008870144869460884601C00070794000F0C7710304877887FF9210840801CF72123
+:20E2A000084010430121084369468877142109A801F06CF908A8099007A80A9069468C851A
+:20E2C0001720CC8508860D942B46A888103309AAA2DF6FE731150000FFB583B0074600207F
+:20E2E0000C9C8646267805463AE07868A90041180A88684682804988C1800022694601A8F7
+:20E3000065DF002810D1684601780598814226D17046002801D0002200E002222078891824
+:20E3200041181F2902D90C2007B0F0BD7146002908D1401CC0B2411C069B049A21701A54AF
+:20E3400001208646217806980A18694601A865DF0028E9D1694620780978401820706D1CC0
+:20E360003888A842C1DC7046002804D020780699801B401E88550020D6E7F8B51546069C10
+:20E380001E46074602220094FFF7A6FF002806D133461022294638460094FFF79DFFF8BD07
+:20E3A000F7B582B000260546167000681446002805D02846039900F0CAF8060008D168794D
+:20E3C00000281ED02078039F001D1F2802D90C2005B0F0BD684679DF0028F9D1217803226A
+:20E3E000481C20707A5421781922481C20707A542078C1196846008800F0A4F821784018A0
+:20E400002070A8790223002810D02078039A411C2170135420780399471C012227700A54E5
+:20E420002078AA79471C039927700A54A868002815D00021415620788C460246C01C03992E
+:20E440001F28C4D8501C20708B5422780A23501C20708B5420786246431C23700A54A8899B
+:20E46000002809D028460094062202210C30039BFFF783FF0600ABD1A88A002809D02846D9
+:20E480000094072203211430039BFFF776FF06009ED1A88B002809D0284600941522142137
+:20E4A0001C30039BFFF769FF060091D1686A002805D02246039900F07FF8060088D1A86A01
+:20E4C000002805D02246039900F0B5F8060084D13020405D002806D022462846039900F0F6
+:20E4E000DCF80600C7D1304672E770B50C4692B000216A46117007251171002809D0817927
+:20E5000049070CD502A9FFF74BFF002808D102AE00E00026002C0ED0A079002802D028469D
+:20E5200012B070BD01AA0AA92046FFF739FF0028F6D10AAA00E0002268460379017830463C
+:20E5400072DFEDE70870000A487002207047F8B514780746A01C15460E461F2803D83879BF
+:20E56000801C1F2801D90C20F8BD1D20001B80B26946864608803019801C7DDF0028F3D143
+:20E580003868022805D168460088704501D8092107E038790821002801D0704501D96846F6
+:20E5A0000088421C3255641CE2B2B1542978801C081828700020F8BDF8B50D461178064636
+:20E5C000881D14461F2801D90C20F8BD33880720062BFAD31927FF01BB4202D94D4A9342D6
+:20E5E000F3D17288062AF0D3BA4202D9494FBA42EBD1484FBB4203D0BA4201D09342E4D87E
+:20E60000481C052220706A5420781222411C21702A54207841193088FFF794FF21784018C5
+:20E62000C0B2207041197088FFF78CFF2178401820700020F8BD70B5054600790E46801CD6
+:20E640001446C0B21178821C8A181F2A01D90C2070BD0A46491C401C2170B0542078FF224A
+:20E66000411C21703254207881192888FFF76AFF21784018C0B22070AA88002A09D0A968AC
+:20E68000002908D0801900F022FF2078297940182070002070BD072070BDF7B582B0029894
+:20E6A0001446C06A0F46002832D0029800252030009028E00298C16A0C2068430E18217855
+:20E6C00030794A1CC01C2270785421781622481C20707A542078C1193088FFF733FF217873
+:20E6E0004018C0B22070B288002A09D0B16800290ED0C01900F0EBFE207831794018207087
+:20E700006D1C0098EDB2007CA842D3D800205FE607205DE6FFFF000038B56749674A48883D
+:20E7200090420FD04A78664C521CD2B24A70237B934208D3083175DF002803D0A1690029FF
+:20E7400000D0884738BD00254D70217C002907D03B2176DF002803D0A169002900D0884728
+:20E7600061690029EED068460095884738BD70B5054601461C225248FDF75AFD4E4C002647
+:20E7800026702968002907D00822A01800F09FFE204608307ADF02E0474808307BDF0028C1
+:20E7A00008D1401E608044486670464A0021001DFFF7D6F870BD10B53F484068FFF769F9D5
+:20E7C00010BDF8B53C48103000F069F800263A4D3B4C002806D06169002919D001200090EB
+:20E7E000684614E02878002804D0616900290FD00096F5E7687800280CD0A16800226868B8
+:20E80000FFF70AF9002803D0A169002900D088472E70F8BD6168F1E7F8B5294C028800276B
+:20E82000254DE689102A18D029464968112A21D0122A2DD0502A0FD1801D0288B2420BD1FF
+:20E84000028B022A08D1C27E837E10021843C007C00F13D0FFF7B5FFF8BD81886980014667
+:20E86000154808221631103000F031FE6F70002EF0D0F8BD0020C04368806F700846FFF7BB
+:20E8800008F90028F5D0A1690029F2D08847F8BD811D09480822103000F019FEDAE7418827
+:20E8A000054808300288914204D34088814201D8012070470020704790280020FFFF0000B6
+:20E8C000CC2D002019E7030031B5054C04E0401E00902046FDF77AFC00980028F7D138BDC6
+:20E8E000E703000018225043FE4A00218018017181604161012281610261C1607047FFB577
+:20E9000081B0F94C049B039A054626691A4303200092002E03D1002A0ED001222261276919
+:20E92000039A0126360792003B0000F022FF072707162940526127000222EFE770693269FC
+:20E9400092B25043326933691204920C9BB2594329DF002812D102210FE0084628DF00286A
+:20E960000CD10399002901D0032106E00499002916D12978042946D017E0216105B0F0BDAE
+:20E980007069326992B25043326993B24B4301461846039A29DF0028F0D10499002901D0F4
+:20E9A0000421EAE72978042920D00521E5E773693069366980B2434368681B189B18B6B2C7
+:20E9C0004E43301880181946049A29DF0028E9D0D4E7306980B24843696880188A08696902
+:20E9E00029DF0028CAD1009900290CD00621C4E77069316989B24843316989B200F0D9FD08
+:20EA000028DF0028BAD10721B7E7F8B5B54918230A780F205A435418241DB3492278266970
+:20EA2000CF68022A1BD001252D07042A2AD0052A5BD1286981B2304600F0BBFD0146A36877
+:20EA400028699A1980B24843101A820860681818861928694B1C80B25843801B34E0B8023C
+:20EA600062686169121A0918A3683018181801239B029A4202D2920829DF31E0FF220132BA
+:20EA800029DF2DE0E268974914205043F4314018001D0BC8B04203D160685943814218D02E
+:20EAA000022A16D0286981B2304600F082FD0146286980B24843301A820828694B1C80B208
+:20EAC000584363689B19C01A83082046FFF717FF06E0286981B2304600F06BFDC01928DFED
+:20EAE000002802D17F4901228A70F8BDF8B57D4C069E65780A2D1DD027787D19EDB20A2D5B
+:20EB000001D30A3DEDB218277D432D192871AA6103C9EE60AB6069612861A1780020002978
+:20EB200004D1FFF772FF112800D100206178491C6170F8BD0420F8BD38B5024669481823B1
+:20EB400001785943081803690179022B0AD014246343644CF434E4588368009383691030F7
+:20EB6000A04738BD604B14331C68F5E7F8B55D4B9978012914D100255B499D700A69082A77
+:20EB800005D002280FD003280AD10D2006E0022807D00D7000F025FA002801D0FFF7CCFF37
+:20EBA000F8BD0D61F6E74F48182403784E496343CC681818641C001DCC600378022B05D11F
+:20EBC0004668A102B14201D3012700E00027052B01D1072A03D00021042B02D003E00121C1
+:20EBE000FAE7072A03D00026042B02D007E00126FAE74068A302834201D3002A1AD0002000
+:20EC0000314301433943C5D0374E28463561FFF793FF344C2078FFF765FEF5606078401E1E
+:20EC200060702078401CC0B220700A28B2D30A382070AFE70120E3E770B500252A4C2948D3
+:20EC4000E56025610570457085702E463046FFF749FE761C0A2EF9D3012212076560516952
+:20EC600028461269491E92B25143E560A1601D49F4310D608D600D61CD601B4914310D6090
+:20EC8000888001212170206170BDF8B5164A044610780E46002830D0002C30D0002E2ED058
+:20ECA000206800282BD0012000076768016989B28F4228D8102F26D3A168002923D09568E2
+:20ECC000794343694A19006980B243439A421AD801200007006980B2814212D901200007E1
+:20ECE000006903E0E82D0020A828002080B2394600F05FFC002906D103E00820F8BD0E20B9
+:20ED0000F8BDB80701D00720F8BDBD49486801281CD00F461421BB4A21C641438E18756092
+:20ED2000236853506168B160A168F160A268616800235143012212075B1C14699BB2A4B214
+:20ED40008C4205D21469A4B2091B02E00420F8BD00211469A4B265191469A4B28C42EBD985
+:20ED6000BD60401C336178600020F8BDF8B50446A3481E46007815460F46002807D0002F3D
+:20ED800007D0002C05D02068002817D103E00820F8BD0E20F8BD9B48016800290ED0C268E3
+:20EDA000816840684A4310186268904206D9002D04D0A94202D3A819884201D90720F8BD90
+:20EDC000384600F008F9002811D0304600F003F900280CD0606800F0FEF8002807D02B4637
+:20EDE0003A46214602200096FFF780FEF8BD1020F8BDFFB5824881B000781F4616460D462B
+:20EE0000002808D0002D08D00198002805D02868002817D103E00820B0E50E20AEE5794C91
+:20EE2000206800280ED0E168A0686268414389186A68914206D9002E04D0B04202D3F119AD
+:20EE4000814201D9072099E5019800F0C4F800281BD0384600F0BFF8002816D0686800F025
+:20EE6000BAF8002811D068683246C119019800F02EFB00962868142148432458002203215B
+:20EE80002846019BA047002078E5102076E5F8B505465B480F460078002805D0002D05D012
+:20EEA0002868002821D103E00820F8BD0E20F8BD544C00262068002817D0A168E0684843CC
+:20EEC00061684118686881420FD900F084F800280DD0296814225143091968684A68896834
+:20EEE000801A00F066FB002903D00720F8BD1020F8BD3B460022294604200096FFF7F6FDB5
+:20EF0000F8BD3F4A1278002A0DD000280DD000290BD00268002A08D0394A14321368002B3E
+:20EF200005D004207047082070470E20704702230B600068106000207047F8B504463048AF
+:20EF40001E46007817460D46002807D0002D07D0002C05D0206802281BD103E00820F8BDC3
+:20EF60000E20F8BD264814300068002811D0084600F031F800280ED0304600F02CF800286C
+:20EF800009D03B462A46214602200096FFF7AEFDF8BD0720F8BD1020F8BD08B5184A1278C8
+:20EFA000002A05D0002805D00268022A11D103E0082008BD0E2008BD114A14321268002AD5
+:20EFC00007D00B460022014604200092FFF78EFD08BD072008BD800701D000207047012068
+:20EFE0007047084910B5F43949780020002906D0FFF70BFD002802D0112800D1002010BD48
+:20F00000A8280020DC2E002070B500250C290ED304464318008941000919581A0A38C2B2BD
+:20F020001748022A027002D30A318B4201D2092070BD144800F04BFA134914480A8882422E
+:20F0400002D02388934217D14988814202D06088884211D10D4A0323521E20891B03A842DE
+:20F060000AD9690009194989914203D09E896D1CB142F4D1002070BD0B2070BD00207047C6
+:20F08000C4280020F02E002080100010FFFF000010B5FDF7ABF810BD10B50446002A02D054
+:20F0A0001088002210E00A48FBE7030A00020343A05C584003061B0F43401803584083B2EB
+:20F0C0001806C00C5840521C8A42EED310BD0000FFFF00004B48002101704C484A4A026039
+:20F0E0008160C160016108224161426081610846704710B500291DD000220A60434A5368A8
+:20F10000002B1BD0202817D85B1E5360D0682423401CD060106914684343E3180B60012366
+:20F1200083409169401C19434007400F91611061002010BD0E2010BD0C2010BD042010BD8F
+:20F14000F0B5324A0646916800292BD057691020791A4907490F14680B4624254D436519D6
+:20F16000B54206D1012495698C4065400020956104E0491C4907490F8F42EED1491C4E07DC
+:20F18000760F956901210C469C402B4623420AD19368002B07D05B1E936053685B1C53609D
+:20F1A0003346F0E70420F0BD184A2423117C1268491E4907490F594320315050002070470B
+:20F1C00070B500281AD0002918D0104AD368002B16D05B1ED360936824265B1C936053692A
+:20F1E00015681C467343EE1820330660E858641C08606007400F5061002070BD0E2070BD84
+:20F20000042070BDC5280020FC2E00201C30002030B5CB0008339DB293070024002B01D0E6
+:20F22000072030BD3B4B9A605219DA605C701C7058809980002030BDF7B5364C0E466088D5
+:20F24000814237D8344F00F069F822786078A188884201DA401C00E00020C0B2904202D155
+:20F2600000F062F824E065786078884201DA401C00E00020607000F057F8BD4218D0A0688C
+:20F28000EF000299C151009900290CD0002E0AD0608832464543E068281800F018F9A068B3
+:20F2A0003818868002E00021381881800020FEBD0420FEBD0920FEBD0EB504E068468188A8
+:20F2C000029A0098904702AA01A9684600F003F80028F3D00EBD70B50E4B05241D785E786C
+:20F2E000AE4215D01D781C789E88B44201DA641C00E000241C705C88DE686C43A41904600F
+:20F300009B68E800C418A4880C80185800241060204670BDCC280020FFFF000072B606484F
+:20F320000168491C0160704703490868401E086000D162B670470000DC280020BFF34F8F11
+:20F3400003490248C860BFF34F8FFEE70400FA0500ED00E010B5002904D000221146104619
+:20F36000FFF7ECFF00F010F810BD10B50021024A0846FFF761FF10BD55F3030010B50846E6
+:20F380001146FCF771FF10BDF8B5384C2078002837D02069002807D00026E068002805D0FB
+:20F3A0000025002E04D013E00126F6E70125F8E7684651DF052806D0002806D000221146D2
+:20F3C000FFF7BCFF04E0012602E0216900988847002D12D1608869460880A06861DF0528FA
+:20F3E00006D0002806D000221146FFF7A7FF04E0012502E0E168A0688847002ED8D0002D15
+:20F40000CFD0F8BD70B5002901D08C0701D0072070BD164C0125A16062801549636010DF46
+:20F420000028F5D1257016202EDF70BD002803D00E49C860002070470E207047002803D0A8
+:20F440000A490861002070470E20704710B507484068002807D08047002803D0002211463E
+:20F46000FFF76CFF10BDFFF78FFF10BDE02800207DF30300034610B50B439B070FD1042A66
+:20F480000DD308C810C9121FA342F8D018BA21BA884201D9012010BD0020C04310BD002AAC
+:20F4A00003D0D30703D0521C07E0002010BD03780C78401C491C1B1B07D103780C78401C61
+:20F4C000491C1B1B01D1921EF1D1184610BDF8B5042A2CD3830712D00B78491C0370401C25
+:20F4E000521E83070BD00B78491C0370401C521E830704D00B78491C0370401C521E8B07F9
+:20F500009B0F05D0C91ADF002023DE1B08C90AE0FCF78EFEF8BD1D4608C9FD401C46B440B8
+:20F520002C4310C0121F042AF5D2F308C91A521EF0D40B78491C0370401C521EEAD40B78EC
+:20F54000491C0370401C521EE4D409780170F8BD01E004C0091F0429FBD28B0701D50280F7
+:20F56000801CC90700D00270704700290BD0C30702D00270401C491E022904D3830702D5EE
+:20F580000280801C891EE3E70022EEE70022DFE70378C2781946437812061B0219438378A2
+:20F5A000C0781B04194311430902090A000608437047002203098B422CD3030A8B4211D366
+:20F5C00000239C464EE003460B433CD4002243088B4231D303098B421CD3030A8B4201D39D
+:20F5E00094463FE0C3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B422D
+:20F6000001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524193
+:20F6200083088B4201D38B00C01A524143088B4201D34B00C01A5241411A00D201465241FB
+:20F64000104670475DE0CA0F00D04942031000D34042534000229C4603098B422DD3030A47
+:20F660008B4212D3FC22890112BA030A8B420CD3890192118B4208D3890192118B4204D305
+:20F6800089013AD0921100E08909C3098B4201D3CB01C01A524183098B4201D38B01C01A88
+:20F6A000524143098B4201D34B01C01A524103098B4201D30B01C01A5241C3088B4201D37F
+:20F6C000CB00C01A524183088B4201D38B00C01A5241D9D243088B4201D34B00C01A52417F
+:20F6E000411A00D20146634652415B10104601D34042002B00D54942704763465B1000D31A
+:20F70000404201B50020C046C04602BD704770477047754600F022F8AE460500694653469B
+:20F72000C008C000854618B020B5FEF7FBFA60BC00274908B6460026C0C5C0C5C0C5C0C525
+:20F74000C0C5C0C5C0C5C0C5403D49008D4670470446C046C0462046FCF7FFFC004870479C
+:20F760003830002001491820ABBEFEE726000200704730B47446641E2578641CAB4200D256
+:20F780001D46635D5B00E31830BC184702000000000000000000000000000000040000009F
+:20F7A000000000000000000000000000000000000000000035C4030000000000000000004D
+:20F7C000020000000000000000000000000000000000000000000000030000000000000024
+:20F7E0000000000005000000000000000000000000000000000000000000000023D1BCEA6A
+:20F800005F782315DEEF1212000000002CF8030000280020F400000004C1030020F90300A1
+:20F82000F4280020A413000020C103000000000000000000000000000000000000000000F1
+:20F840000000000000000000000000000000000000000000000000000000000000000000A8
+:20F8600000000000000000000000FFFF000000003200000000000000000000000000000058
+:20F88000000000000000000000000000000000000000000000000000000000000000000068
+:20F8A000000000000000000000000000000000000024F40000000000000000000000000030
+:20F8C000000000000000000000000000000000000000000000000000000000000000000028
+:20F8E000000000000000000000000000000000000000000000000000000000000000000008
+:20F900000000000000000000000000000000000000000000000000000000000000000000E7
+:20FC00000100000000000000FE0000000000000000000000000000000000000000000000E5
+:020000041000EA
+:0410140000C0030015
+:040000050003C0C173
+:00000001FF
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/bootloader/softdevice_nrf51822_licence_agreement.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
+ *
+ * /
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/module.json	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,36 @@
+{
+  "name": "ble-nrf51822",
+  "version": "2.5.0",
+  "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.3.0",
+    "nrf51-sdk": "^2.1.0"
+  },
+  "extraIncludes": [
+    "source/btle",
+    "source/btle/custom",
+    "source/common"
+  ],
+  "targetDependencies": {}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/BSD-3clause-Nordic.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/LICENSE	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,6 @@
+Many of the files in this module have been inherited from the Nordic SDK for
+nRF51822; they come with a BSD-like license 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 BSD-like Nordic license can be found in BSD-3clause-Nordic.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/README.md	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,30 @@
+# nrf51-sdk
+Module to contain files provided by the nordic nRF51 SDK. The latest version of this module uses files from Nordic SDK 10.0.0. The files are extracted from [here](https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v10.x.x/nRF51_SDK_10.0.0_dc26b5e.zip).
+
+## Changes made to Nordic files
+The files are kept the same as much as possible to the Nordic SDK. Modifications are made in order to integrate with mbed.
+    - ble/common/ble_conn_state.c: Preprocessor tests regarding S110, S120 or S130 macro should be replace by TARGET_MCU_NRF51_XXK_SXXX tests
+
+## Porting new versions of Nordic SDK
+A list of files currently requierd by mbed is maintained in [script/required_files.txt](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/required_files.txt). [A python script](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/pick_nrf51_files.py) is written to help porting from nordic sdk releases. **required_files.txt** is parsed to find a list of filenames. The script searches for these filenames in the sdk folder, and copy then into the yotta module mirroring the folder structure in the sdk. **extraIncludes** is automatically added to module.json to allow direct inclusion of noridc headers with just the filename.
+
+### Script usage
+```
+python pick_nrf51_files.py [options] <full-noridc-sdk-path> <nrf51-sdk-yotta-module-path>
+options: --purge   : to delete all existing files and start again
+         --dry-run : to list the files to be copied but not actually copy them
+```
+
+There are files in the sdk with the same filename but in different folder. This is dealt with by excluding certain directories. The excluded directories are listed in [pick_nrf51_files.py](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/pick_nrf51_files.py).
+
+After running the script, the changes in [the previous section](#changes-made-to-nordic-files) will have to be applied manually again.
+
+Folder structure or even file name can change between releases of the nordic sdk, hence a degree of manual adjustment is needed when porting.
+
+## Using Noridc Headers
+The nordic sdk is written in C and yotta modules support C++. If you are trying to include Nordic files in a cpp program, you need to use the `extern "C"` keyword around the includes.
+```c
+extern "C" {
+#include "softdevice_handler.h"
+}
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/module.json	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,51 @@
+{
+  "name": "nrf51-sdk",
+  "version": "2.2.0",
+  "description": "Module to contain files provided by the nordic nRF51 SDK",
+  "keywords": [
+    "nordic",
+    "nrf51",
+    "sdk"
+  ],
+  "author": "",
+  "repository": {
+    "url": "git@github.com:ARMmbed/nrf51-sdk.git",
+    "type": "git"
+  },
+  "license": "nordic",
+  "targetDependencies": {
+    "mbed-classic": {
+      "mbed-classic": "~0.0.1"
+    },
+    "mbed-os": {
+      "mbed-drivers": "*"
+    }
+  },
+  "extraIncludes": [
+    "source/nordic_sdk/components/ble/ble_radio_notification",
+    "source/nordic_sdk/components/ble/ble_services/ble_dfu",
+    "source/nordic_sdk/components/ble/common",
+    "source/nordic_sdk/components/ble/device_manager",
+    "source/nordic_sdk/components/ble/device_manager/config",
+    "source/nordic_sdk/components/ble/peer_manager",
+    "source/nordic_sdk/components/device",
+    "source/nordic_sdk/components/drivers_nrf/ble_flash",
+    "source/nordic_sdk/components/drivers_nrf/delay",
+    "source/nordic_sdk/components/drivers_nrf/hal",
+    "source/nordic_sdk/components/drivers_nrf/pstorage",
+    "source/nordic_sdk/components/drivers_nrf/pstorage/config",
+    "source/nordic_sdk/components/libraries/bootloader_dfu",
+    "source/nordic_sdk/components/libraries/bootloader_dfu/hci_transport",
+    "source/nordic_sdk/components/libraries/crc16",
+    "source/nordic_sdk/components/libraries/hci",
+    "source/nordic_sdk/components/libraries/scheduler",
+    "source/nordic_sdk/components/libraries/timer",
+    "source/nordic_sdk/components/libraries/util",
+    "source/nordic_sdk/components/libraries/fds",
+    "source/nordic_sdk/components/libraries/fstorage",
+    "source/nordic_sdk/components/libraries/experimental_section_vars",
+    "source/nordic_sdk/components/softdevice/common/softdevice_handler",
+    "source/nordic_sdk/components/softdevice/s130/headers",
+    "source/nordic_sdk/components/toolchain"
+  ]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/script/copyright_header.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/script/pick_nrf51_files.py	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+
+import os, shutil, json, pprint, sys
+from collections import OrderedDict
+
+help_text = """
+Usage: python {} [options] <full-noridc-sdk-path> <nrf51-sdk-yotta-module-path>
+options: --purge   : to delete all existing files and start again
+         --dry-run : to list the files to be copied but not actually copy them
+""".format(os.path.basename(__file__))
+
+# exclude path to avoid confusion over files of the same name
+exclude_path = ["examples", "SVD", "s110", "s120", "s210", "s310", "nrf_soc_nosd", "serialization/connectivity",
+                'components/libraries/hci/config', 'components/libraries/bootloader_dfu/ble_transport']
+
+def find(name, path):
+    paths = []
+    for root, dirs, files in os.walk(path):
+        if True not in [x in root for x in exclude_path]:
+            if name in files:
+                paths.append(os.path.join(root, name))
+
+    if len(paths) == 0:
+        print "-"*30
+        print "Warning! No {} found!!!!".format(name)
+        print "-"*30
+        return None
+    elif len(paths) > 1:
+        print "-"*30
+        print "Warning! More than one {} found!!!!".format(name)
+        print paths
+        print "-"*30
+        return None
+    else:
+        return paths[0]
+
+def find_dir(dir_name, path):
+    paths = []
+    for root, dirs, files in os.walk(path):
+        if dir_name in root:
+            for fn in files:
+                paths.append(os.path.join(root, fn))
+    return paths
+
+if __name__ == "__main__":
+    # define source and destination of copy
+    arg_valid = True
+    if len(sys.argv) not in [3, 4]:
+        arg_valid = False
+    else:
+        src_folder = sys.argv[-2]
+        yt_module_dir = sys.argv[-1]
+
+        for d in [src_folder, yt_module_dir]:
+            if not os.path.isdir(d):
+                arg_valid = False
+                print src_folder, "is not a folder"
+
+    purge = ("--purge" in sys.argv)
+    dry_run = ("--dry-run" in sys.argv)
+
+    if not arg_valid:
+        print help_text
+        sys.exit(1)
+
+    dst_folder = os.path.join(yt_module_dir, "source/nordic_sdk")
+
+    # build a file_list from required_files.txt
+    file_list = []
+    with open("required_files.txt", "r") as fd:
+        for line in fd:
+            line = line.strip()
+            if line.startswith("D "):
+                directory = line.split(" ")[-1]
+                file_list += find_dir(directory, src_folder)
+            elif not line.startswith("#") and line != '':
+                fn = os.path.basename(line).strip()
+                fn = find(fn, src_folder)
+                file_list.append(fn)
+
+    # remove everything from the destination folder
+    if purge and not dry_run and os.path.exists(dst_folder):
+        shutil.rmtree(dst_folder)
+
+    # copy files
+    extra_includes = []
+    for src in file_list:
+        if src:
+            rel_dst = os.path.relpath(src, src_folder)
+            dst = os.path.join(dst_folder, rel_dst)
+            print src, "->", dst
+
+            directory = os.path.dirname(dst)
+            if not os.path.exists(directory):
+                print "Creating directory:", directory
+                if not dry_run:
+                    os.makedirs(directory)
+            if not os.path.isfile(dst):
+                print "Copying file", dst
+                if not dry_run:
+                    shutil.copyfile(src, dst)
+
+            # build a list of extra includes to be added to module.json
+            if dst.endswith(".h"):
+                inc_rel_path = os.path.relpath(dst, yt_module_dir)
+                inc_dir_path = os.path.dirname(inc_rel_path)
+                if inc_dir_path not in extra_includes:
+                    extra_includes.append(inc_dir_path)
+
+    # write extraIncludes in the module.json file
+    mod_json = os.path.join(yt_module_dir, "module.json")
+    print "-"*30
+    print "Writing extra_includes to {}".format(mod_json)
+    print "-"*30
+    for n in sorted(extra_includes):
+        print n
+
+    if not dry_run:
+        with open(mod_json, 'r+') as fd:
+            jobj = json.loads(fd.read(), object_pairs_hook=OrderedDict)
+            jobj['extraIncludes'] = sorted(extra_includes)
+            jdump = json.dumps(jobj, indent=2, separators=(',', ': '))
+            fd.seek(0)
+            fd.write(jdump)
+            fd.write("\n")
+            fd.truncate()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/script/replace_headers.py	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,23 @@
+import os
+
+with open("copyright_header.txt", "r") as fd:
+	header = fd.read()
+
+path = "../source/nordic_sdk"
+for root, dirs, files in os.walk(path):
+	for fn in [os.path.join(root, x) for x in files]:
+		with open(fn, "r+") as fd:
+			print "+"*35
+			print fn
+			s = fd.read()
+			start = s.find("/*")
+			end = s.find("*/")
+			copyright_str = s[start:end+2]
+			if "copyright (c)" not in copyright_str.lower():
+				s = header + "\n\n" + s
+			elif copyright_str is not header:
+				s = s.replace(copyright_str, header)
+
+			fd.seek(0)
+			fd.write(s)
+			fd.truncate()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/script/required_files.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,136 @@
+# from cmsis-core-nrf51822:
+	cmsis-core-nrf51822/compiler_abstraction.h
+	cmsis-core-nrf51822/nrf.h
+	cmsis-core-nrf51822/nrf51.h
+	cmsis-core-nrf51822/nrf51_bitfields.h
+	cmsis-core-nrf51822/nrf_delay.h
+	cmsis-core-nrf51822/system_nrf51.h
+	source/system_nrf51.c
+
+# from ble-nrf51822
+	source/nordic-sdk/components/ble/ble_radio_notification/ble_radio_notification.c
+	source/nordic-sdk/components/ble/ble_radio_notification/ble_radio_notification.h
+	source/nordic-sdk/components/ble/ble_services/ble_dfu/ble_dfu.c
+	source/nordic-sdk/components/ble/ble_services/ble_dfu/ble_dfu.h
+	source/nordic-sdk/components/ble/common/ble_advdata.c
+	source/nordic-sdk/components/ble/common/ble_advdata.h
+	source/nordic-sdk/components/ble/common/ble_advdata_parser.c
+	source/nordic-sdk/components/ble/common/ble_advdata_parser.h
+	source/nordic-sdk/components/ble/peer_manager/id_manager.h
+	source/nordic-sdk/components/ble/peer_manager/id_manager.c
+	source/nordic-sdk/components/ble/peer_manager/peer_manager_types.h
+	source/nordic-sdk/components/ble/peer_manager/ble_gatt_db.h
+	source/nordic-sdk/components/ble/peer_manager/ble_conn_state.h
+	source/nordic-sdk/components/ble/peer_manager/sdk_mapped_flags.h
+	source/nordic-sdk/components/ble/peer_manager/peer_database.h
+# source/nordic-sdk/components/ble/common/ble_conn_params.cpp the file is called
+	source/nordic-sdk/components/ble/common/ble_conn_params.c
+	source/nordic-sdk/components/ble/common/ble_conn_params.h
+	source/nordic-sdk/components/ble/common/ble_date_time.h
+	source/nordic-sdk/components/ble/common/ble_sensor_location.h
+	source/nordic-sdk/components/ble/common/ble_srv_common.c
+	source/nordic-sdk/components/ble/common/ble_srv_common.h
+	source/nordic-sdk/components/ble/device_manager/config/device_manager_cnfg.h
+	source/nordic-sdk/components/ble/device_manager/device_manager.h
+	source/nordic-sdk/components/ble/device_manager/device_manager_peripheral.c
+	source/nordic-sdk/components/drivers_nrf/ble_flash/ble_flash.c
+	source/nordic-sdk/components/drivers_nrf/ble_flash/ble_flash.h
+	source/nordic-sdk/components/drivers_nrf/hal/compiler_abstraction.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf51.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf51_bitfields.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf51_deprecated.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_delay.c
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_ecb.c
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_ecb.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_gpio.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_gpiote.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_nvmc.c
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_nvmc.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_temp.h
+	source/nordic-sdk/components/drivers_nrf/pstorage/config/pstorage_platform.h
+	source/nordic-sdk/components/drivers_nrf/pstorage/pstorage.c
+	source/nordic-sdk/components/drivers_nrf/pstorage/pstorage.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/bootloader.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_types.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util.h
+# source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c new file is called:
+	source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util.c
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_bank_internal.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_ble_svc.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_init.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_init_template.c
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_transport.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/dfu_types.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/experimental/dfu_app_handler.c
+	source/nordic-sdk/components/libraries/bootloader_dfu/experimental/dfu_app_handler.h
+	source/nordic-sdk/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h
+	source/nordic-sdk/components/libraries/crc16/crc16.c
+	source/nordic-sdk/components/libraries/hci/hci_mem_pool.c
+	source/nordic-sdk/components/libraries/hci/hci_mem_pool.h
+	source/nordic-sdk/components/libraries/scheduler/app_scheduler.c
+	source/nordic-sdk/components/libraries/util/app_error.c
+	source/nordic-sdk/components/libraries/util/app_util_platform.c
+	source/nordic-sdk/components/libraries/util/app_util_platform.h
+	source/nordic-sdk/components/libraries/util/common.h
+	source/nordic-sdk/components/libraries/util/nordic_common.h
+	source/nordic-sdk/components/libraries/util/nrf_assert.c
+	source/nordic-sdk/components/libraries/util/nrf_assert.h
+	source/nordic-sdk/components/libraries/util/sdk_common.h
+	source/nordic-sdk/components/libraries/util/sdk_errors.h
+	source/nordic-sdk/components/libraries/util/sdk_os.h
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler.c
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler.h
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c
+	source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h
+# source/nordic-sdk/components/softdevice/s130/doc/ble_api.dox uncertain of the origin of this file
+	source/nordic-sdk/components/softdevice/s130/include/ble.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_err.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_gap.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_gatt.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_gattc.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_gatts.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_hci.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_l2cap.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_ranges.h
+	source/nordic-sdk/components/softdevice/s130/include/ble_types.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_error.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_error_sdm.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_error_soc.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_mbr.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_sdm.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_soc.h
+	source/nordic-sdk/components/softdevice/s130/include/nrf_svc.h
+	source/nordic-sdk/components/softdevice/s130/include/softdevice_assert.h
+	source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h
+	source/nordic-sdk/components/ble/common/ble_conn_state.c
+	source/nordic-sdk/components/ble/peer_manager/peer_data.c
+	source/nordic-sdk/components/ble/peer_manager/peer_data.h
+	source/nordic-sdk/components/ble/peer_manager/peer_data_storage.c
+	source/nordic-sdk/components/ble/peer_manager/peer_data_storage.h
+	source/nordic-sdk/components/ble/peer_manager/peer_database.c
+	source/nordic-sdk/components/ble/peer_manager/peer_id.c
+	source/nordic-sdk/components/ble/peer_manager/peer_id.h
+	source/nordic-sdk/components/ble/peer_manager/pm_buffer.c
+	source/nordic-sdk/components/ble/peer_manager/pm_buffer.h
+	source/nordic-sdk/components/ble/peer_manager/pm_mutex.c
+	source/nordic-sdk/components/ble/peer_manager/pm_mutex.h
+	source/nordic-sdk/components/libraries/experimental_section_vars/
+	source/nordic-sdk/components/libraries/fds/
+	source/nordic-sdk/components/libraries/fstorage/
+	source/nordic-sdk/components/libraries/util/sdk_mapped_flags.c
+
+
+# from mbed-hal-nrf51822-mcu
+	mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/crc16/crc16.h
+	mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/scheduler/app_scheduler.h
+	mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/util/app_error.h
+	mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/util/app_util.h
+
+# included from ble_conn_params.c
+	app_timer.h
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_radio_notification/ble_radio_notification.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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>
+
+
+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(nrf_app_irq_priority_t               irq_priority,
+                                     nrf_radio_notification_distance_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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_radio_notification/ble_radio_notification.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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"
+
+/**@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(nrf_app_irq_priority_t               irq_priority,
+                                     nrf_radio_notification_distance_t    distance,
+                                     ble_radio_notification_evt_handler_t evt_handler);
+
+#endif // BLE_RADIO_NOTIFICATION_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_services/ble_dfu/ble_dfu.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_dfu.h"
+#include "nrf_error.h"
+#include "ble_types.h"
+#include "ble_gatts.h"
+#include "app_util.h"
+#include "ble_srv_common.h"
+#include "nordic_common.h"
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+
+#define MAX_DFU_PKT_LEN         20                                              /**< Maximum length (in bytes) of the DFU Packet characteristic. */
+#define PKT_START_DFU_PARAM_LEN 2                                               /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
+#define PKT_INIT_DFU_PARAM_LEN  2                                               /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
+#define PKT_RCPT_NOTIF_REQ_LEN  3                                               /**< Length (in bytes) of the Packet Receipt Notification Request. */
+#define MAX_PKTS_RCPT_NOTIF_LEN 6                                               /**< Maximum length (in bytes) of the Packets Receipt Notification. */
+#define MAX_RESPONSE_LEN        7                                               /**< Maximum length (in bytes) of the response to a Control Point command. */
+#define MAX_NOTIF_BUFFER_LEN    MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN)  /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */
+
+enum
+{
+    OP_CODE_START_DFU          = 1,                                             /**< Value of the Op code field for 'Start DFU' command.*/
+    OP_CODE_RECEIVE_INIT       = 2,                                             /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
+    OP_CODE_RECEIVE_FW         = 3,                                             /**< Value of the Op code field for 'Receive firmware image' command.*/
+    OP_CODE_VALIDATE           = 4,                                             /**< Value of the Op code field for 'Validate firmware' command.*/
+    OP_CODE_ACTIVATE_N_RESET   = 5,                                             /**< Value of the Op code field for 'Activate & Reset' command.*/
+    OP_CODE_SYS_RESET          = 6,                                             /**< Value of the Op code field for 'Reset System' command.*/
+    OP_CODE_IMAGE_SIZE_REQ     = 7,                                             /**< Value of the Op code field for 'Report received image size' command.*/
+    OP_CODE_PKT_RCPT_NOTIF_REQ = 8,                                             /**< Value of the Op code field for 'Request packet receipt notification.*/
+    OP_CODE_RESPONSE           = 16,                                            /**< Value of the Op code field for 'Response.*/
+    OP_CODE_PKT_RCPT_NOTIF     = 17                                             /**< Value of the Op code field for 'Packets Receipt Notification'.*/
+};
+
+static bool     m_is_dfu_service_initialized = false;                           /**< Variable to check if the DFU service was initialized by the application.*/
+static uint8_t  m_notif_buffer[MAX_NOTIF_BUFFER_LEN];                           /**< Buffer used for sending notifications to peer. */
+
+/**@brief       Function for adding DFU Packet characteristic to the BLE Stack.
+ *
+ * @param[in]   p_dfu DFU Service structure.
+ *
+ * @return      NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
+{
+    ble_gatts_char_md_t char_md;
+    ble_gatts_attr_t    attr_char_value;
+    ble_uuid_t          char_uuid;
+    ble_gatts_attr_md_t attr_md;
+
+    memset(&char_md, 0, sizeof(char_md));
+
+    char_md.char_props.write_wo_resp = 1;
+    char_md.p_char_user_desc         = NULL;
+    char_md.p_char_pf                = NULL;
+    char_md.p_user_desc_md           = NULL;
+    char_md.p_cccd_md                = NULL;
+    char_md.p_sccd_md                = NULL;
+
+    char_uuid.type = p_dfu->uuid_type;
+    char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;
+
+    memset(&attr_md, 0, sizeof(attr_md));
+
+    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+
+    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
+    attr_md.rd_auth = 0;
+    attr_md.wr_auth = 0;
+    attr_md.vlen    = 1;
+
+    memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+    attr_char_value.p_uuid    = &char_uuid;
+    attr_char_value.p_attr_md = &attr_md;
+    attr_char_value.init_len  = 0;
+    attr_char_value.init_offs = 0;
+    attr_char_value.max_len   = MAX_DFU_PKT_LEN;
+    attr_char_value.p_value   = NULL;
+
+    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+                                           &char_md,
+                                           &attr_char_value,
+                                           &p_dfu->dfu_pkt_handles);
+}
+
+
+/**@brief       Function for adding DFU Revision characteristic to the BLE Stack.
+ *
+ * @param[in]   p_dfu DFU Service structure.
+ *
+ * @return      NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init)
+{
+    ble_gatts_char_md_t char_md;
+    ble_gatts_attr_t    attr_char_value;
+    ble_uuid_t          char_uuid;
+    ble_gatts_attr_md_t attr_md;
+
+    memset(&char_md, 0, sizeof(char_md));
+
+    char_md.char_props.read          = 1;
+    char_md.p_char_user_desc         = NULL;
+    char_md.p_char_pf                = NULL;
+    char_md.p_user_desc_md           = NULL;
+    char_md.p_cccd_md                = NULL;
+    char_md.p_sccd_md                = NULL;
+
+    char_uuid.type = p_dfu->uuid_type;
+    char_uuid.uuid = BLE_DFU_REV_CHAR_UUID;
+
+    memset(&attr_md, 0, sizeof(attr_md));
+
+    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+
+    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
+    attr_md.rd_auth = 0;
+    attr_md.wr_auth = 0;
+    attr_md.vlen    = 1;
+
+    memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+    attr_char_value.p_uuid    = &char_uuid;
+    attr_char_value.p_attr_md = &attr_md;
+    attr_char_value.init_len  = sizeof(uint16_t);
+    attr_char_value.init_offs = 0;
+    attr_char_value.max_len   = sizeof(uint16_t);
+    attr_char_value.p_value   = (uint8_t *)&p_dfu_init->revision;
+
+    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+                                           &char_md,
+                                           &attr_char_value,
+                                           &p_dfu->dfu_rev_handles);
+}
+
+
+/**@brief       Function for adding DFU Control Point characteristic to the BLE Stack.
+ *
+ * @param[in]   p_dfu DFU Service structure.
+ *
+ * @return      NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
+{
+    ble_gatts_char_md_t char_md;
+    ble_gatts_attr_t    attr_char_value;
+    ble_uuid_t          char_uuid;
+    ble_gatts_attr_md_t attr_md;
+
+    memset(&char_md, 0, sizeof(char_md));
+
+    char_md.char_props.write  = 1;
+    char_md.char_props.notify = 1;
+    char_md.p_char_user_desc  = NULL;
+    char_md.p_char_pf         = NULL;
+    char_md.p_user_desc_md    = NULL;
+    char_md.p_cccd_md         = NULL;
+    char_md.p_sccd_md         = NULL;
+
+    char_uuid.type = p_dfu->uuid_type;
+    char_uuid.uuid = BLE_DFU_CTRL_PT_UUID;
+
+    memset(&attr_md, 0, sizeof(attr_md));
+
+    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+
+    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
+    attr_md.rd_auth = 0;
+    attr_md.wr_auth = 1;
+    attr_md.vlen    = 1;
+
+    memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+    attr_char_value.p_uuid    = &char_uuid;
+    attr_char_value.p_attr_md = &attr_md;
+    attr_char_value.init_len  = 0;
+    attr_char_value.init_offs = 0;
+    attr_char_value.max_len   = BLE_L2CAP_MTU_DEF;
+    attr_char_value.p_value   = NULL;
+
+    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+                                           &char_md,
+                                           &attr_char_value,
+                                           &p_dfu->dfu_ctrl_pt_handles);
+}
+
+
+/**@brief     Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
+ *
+ * @param[in] p_dfu     DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
+{
+    p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief     Function for checking if the CCCD of DFU Control point is configured for Notification.
+ *
+ * @details   This function checks if the CCCD of DFU Control Point characteristic is configured
+ *            for Notification by the DFU Controller.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return    True if the CCCD of DFU Control Point characteristic is configured for Notification.
+ *            False otherwise.
+ */
+static bool is_cccd_configured(ble_dfu_t * p_dfu)
+{
+    // Check if the CCCDs are configured.
+    uint8_t  cccd_val_buf[BLE_CCCD_VALUE_LEN];
+    ble_gatts_value_t gatts_value;
+
+    // Initialize value struct.
+    memset(&gatts_value, 0, sizeof(gatts_value));
+
+    gatts_value.len     = BLE_CCCD_VALUE_LEN;
+    gatts_value.offset  = 0;
+    gatts_value.p_value = cccd_val_buf;
+
+    // Check the CCCD Value of DFU Control Point.
+    uint32_t err_code = sd_ble_gatts_value_get(p_dfu->conn_handle,
+                                               p_dfu->dfu_ctrl_pt_handles.cccd_handle,
+                                               &gatts_value);
+    if (err_code != NRF_SUCCESS)
+    {
+        if (p_dfu->error_handler != NULL)
+        {
+            p_dfu->error_handler(err_code);
+        }
+        return false;
+    }
+
+    return ble_srv_is_notification_enabled(cccd_val_buf);
+}
+
+
+/**@brief     Function for handling a Write event on the Control Point characteristic.
+ *
+ * @param[in] p_dfu             DFU Service Structure.
+ * @param[in] p_ble_write_evt   Pointer to the write event received from BLE stack.
+ *
+ * @return    NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
+ */
+static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
+{
+    ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
+
+    write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+    if (!is_cccd_configured(p_dfu))
+    {
+        // Send an error response to the peer indicating that the CCCD is improperly configured.
+        write_authorize_reply.params.write.gatt_status =
+            BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
+
+        return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
+
+    }
+    else
+    {
+        uint32_t err_code;
+
+        write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+        err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
+
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    ble_dfu_evt_t ble_dfu_evt;
+
+    switch (p_ble_write_evt->data[0])
+    {
+        case OP_CODE_START_DFU:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
+
+            if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
+            {
+                return ble_dfu_response_send(p_dfu,
+                                             (ble_dfu_procedure_t) p_ble_write_evt->data[0],
+                                             BLE_DFU_RESP_VAL_OPER_FAILED);
+            }
+
+            ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
+            ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_RECEIVE_INIT:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
+
+            if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
+            {
+                return ble_dfu_response_send(p_dfu,
+                                             (ble_dfu_procedure_t) p_ble_write_evt->data[0],
+                                             BLE_DFU_RESP_VAL_OPER_FAILED);
+            }
+            
+            ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
+            ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_RECEIVE_FW:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA;
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_VALIDATE:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE;
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_ACTIVATE_N_RESET:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET;
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_SYS_RESET:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET;
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        case OP_CODE_PKT_RCPT_NOTIF_REQ:
+            if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN)
+            {
+                return (ble_dfu_response_send(p_dfu,
+                                              BLE_DFU_PKT_RCPT_REQ_PROCEDURE,
+                                              BLE_DFU_RESP_VAL_NOT_SUPPORTED));
+            }
+
+            ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts =
+                uint16_decode(&(p_ble_write_evt->data[1]));
+
+            if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0)
+            {
+                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
+            }
+            else
+            {
+                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
+            }
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+
+            break;
+
+        case OP_CODE_IMAGE_SIZE_REQ:
+            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND;
+
+            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+            break;
+
+        default:
+            // Unsupported op code.
+            return ble_dfu_response_send(p_dfu,
+                                         (ble_dfu_procedure_t) p_ble_write_evt->data[0],
+                                         BLE_DFU_RESP_VAL_NOT_SUPPORTED);
+    }
+    return NRF_SUCCESS;
+}
+
+
+/**@brief     Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110
+ *            Stack.
+ *
+ * @param[in] p_dfu     DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
+{
+    ble_gatts_evt_rw_authorize_request_t * p_authorize_request;
+
+    p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
+
+    if (
+        (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+        &&
+        (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle)
+        && 
+        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)
+        &&
+        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+        &&
+        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+       )
+    {
+        uint32_t err_code;
+
+        err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write));
+
+        if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL)
+        {
+            p_dfu->error_handler(err_code);
+        }
+    }
+}
+
+
+/**@brief     Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
+ *
+ * @param[in] p_dfu     DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
+{
+    if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle)
+    {
+        // DFU Packet written
+
+        ble_dfu_evt_t ble_dfu_evt;
+
+        ble_dfu_evt.ble_dfu_evt_type             = BLE_DFU_PACKET_WRITE;
+        ble_dfu_evt.evt.ble_dfu_pkt_write.len    = p_ble_evt->evt.gatts_evt.params.write.len;
+        ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data;
+
+        p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
+    }
+}
+
+
+/**@brief     Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
+ *
+ * @param[in] p_dfu     DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
+{
+    p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)
+{
+    if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+    ble_uuid_t service_uuid;
+    uint32_t   err_code;
+
+    const ble_uuid128_t base_uuid128 =
+    {
+        {
+            0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
+            0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
+        }
+    };
+
+    service_uuid.uuid = BLE_DFU_SERVICE_UUID;
+
+    err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+                                        &service_uuid,
+                                        &(p_dfu->service_handle));
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    p_dfu->uuid_type = service_uuid.type;
+
+    err_code = dfu_pkt_char_add(p_dfu);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    err_code = dfu_ctrl_pt_add(p_dfu);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    err_code = dfu_rev_char_add(p_dfu, p_dfu_init);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    p_dfu->evt_handler = p_dfu_init->evt_handler;
+
+    if (p_dfu_init->error_handler != NULL)
+    {
+        p_dfu->error_handler = p_dfu_init->error_handler;
+    }
+
+    m_is_dfu_service_initialized = true;
+
+    return NRF_SUCCESS;
+}
+
+
+void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
+{
+    if ((p_dfu == NULL) || (p_ble_evt == NULL))
+    {
+        return;
+    }
+
+    if (p_dfu->evt_handler != NULL)
+    {
+        switch (p_ble_evt->header.evt_id)
+        {
+            case BLE_GAP_EVT_CONNECTED:
+                on_connect(p_dfu, p_ble_evt);
+                break;
+
+            case BLE_GATTS_EVT_WRITE:
+                on_write(p_dfu, p_ble_evt);
+                break;
+
+            case BLE_GAP_EVT_DISCONNECTED:
+                on_disconnect(p_dfu, p_ble_evt);
+                break;
+
+            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+                on_rw_authorize_req(p_dfu, p_ble_evt);
+                break;
+
+            default:
+                // No implementation needed.
+                break;
+        }
+    }
+}
+
+
+uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
+{
+    if (p_dfu == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    ble_gatts_hvx_params_t hvx_params;
+    uint16_t               index = 0;
+
+    // Encode the Op Code.
+    m_notif_buffer[index++] = OP_CODE_RESPONSE;
+
+    // Encode the Reqest Op Code.
+    m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
+
+    // Encode the Response Value.
+    m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
+
+    index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
+
+    memset(&hvx_params, 0, sizeof(hvx_params));
+
+    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
+    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    hvx_params.offset = 0;
+    hvx_params.p_len  = &index;
+    hvx_params.p_data = m_notif_buffer;
+
+    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
+}
+
+
+uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
+{
+    if (p_dfu == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    ble_gatts_hvx_params_t hvx_params;
+    uint16_t               index = 0;
+
+    m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
+
+    index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
+
+    memset(&hvx_params, 0, sizeof(hvx_params));
+
+    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
+    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    hvx_params.offset = 0;
+    hvx_params.p_len  = &index;
+    hvx_params.p_data = m_notif_buffer;
+
+    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
+}
+
+
+uint32_t ble_dfu_response_send(ble_dfu_t         * p_dfu,
+                               ble_dfu_procedure_t dfu_proc,
+                               ble_dfu_resp_val_t  resp_val)
+{
+    if (p_dfu == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    ble_gatts_hvx_params_t hvx_params;
+    uint16_t               index = 0;
+
+    m_notif_buffer[index++] = OP_CODE_RESPONSE;
+
+    // Encode the Request Op code
+    m_notif_buffer[index++] = (uint8_t)dfu_proc;
+
+    // Encode the Response Value.
+    m_notif_buffer[index++] = (uint8_t)resp_val;
+
+    memset(&hvx_params, 0, sizeof(hvx_params));
+
+    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
+    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    hvx_params.offset = 0;
+    hvx_params.p_len  = &index;
+    hvx_params.p_data = m_notif_buffer;
+
+    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/ble_services/ble_dfu/ble_dfu.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_sdk_srv_dfu Device Firmware Update Service
+ * @{
+ * @ingroup  ble_sdk_srv
+ * @brief    Device Firmware Update Service
+ *
+ * @details  The Device Firmware Update (DFU) service is a GATT based service that can be used for
+ *           performing firmware updates over BLE. Note that this implementation uses vendor
+ *           specific UUIDs for service and characteristics and is intended to demonstrate the
+ *           firmware updates over BLE. Refer @ref bledfu_transport_bleservice and @ref
+ *            bledfu_transport_bleprofile for more information on the service and profile respectively.
+ */
+
+#ifndef BLE_DFU_H__
+#define BLE_DFU_H__
+
+#include <stdint.h>
+#include "ble_gatts.h"
+#include "ble_gap.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+
+#define BLE_DFU_SERVICE_UUID                 0x1530                       /**< The UUID of the DFU Service. */
+#define BLE_DFU_PKT_CHAR_UUID                0x1532                       /**< The UUID of the DFU Packet Characteristic. */
+#define BLE_DFU_CTRL_PT_UUID                 0x1531                       /**< The UUID of the DFU Control Point. */
+#define BLE_DFU_STATUS_REP_UUID              0x1533                       /**< The UUID of the DFU Status Report Characteristic. */
+#define BLE_DFU_REV_CHAR_UUID                0x1534                       /**< The UUID of the DFU Revision Characteristic. */
+
+/**@brief   DFU Event type.
+ *
+ * @details This enumeration contains the types of events that will be received from the DFU Service.
+ */
+typedef enum
+{
+    BLE_DFU_START,                                                      /**< The event indicating that the peer wants the application to prepare for a new firmware update. */
+    BLE_DFU_RECEIVE_INIT_DATA,                                          /**< The event indicating that the peer wants the application to prepare to receive init parameters. */
+    BLE_DFU_RECEIVE_APP_DATA,                                           /**< The event indicating that the peer wants the application to prepare to receive the new firmware image. */
+    BLE_DFU_VALIDATE,                                                   /**< The event indicating that the peer wants the application to validate the newly received firmware image. */
+    BLE_DFU_ACTIVATE_N_RESET,                                           /**< The event indicating that the peer wants the application to undergo activate new firmware and restart with new valid application */
+    BLE_DFU_SYS_RESET,                                                  /**< The event indicating that the peer wants the application to undergo a reset and start the currently valid application image.*/
+    BLE_DFU_PKT_RCPT_NOTIF_ENABLED,                                     /**< The event indicating that the peer has enabled packet receipt notifications. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify each time the number of packets indicated by num_of_pkts field in @ref ble_dfu_evt_t is received.*/
+    BLE_DFU_PKT_RCPT_NOTIF_DISABLED,                                    /**< The event indicating that the peer has disabled the packet receipt notifications.*/
+    BLE_DFU_PACKET_WRITE,                                               /**< The event indicating that the peer has written a value to the 'DFU Packet' characteristic. The data received from the peer will be present in the @ref BLE_DFU_PACKET_WRITE element contained within @ref ble_dfu_evt_t.*/
+    BLE_DFU_BYTES_RECEIVED_SEND                                         /**< The event indicating that the peer is requesting for the number of bytes of firmware data last received by the application. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify in response to this event. */
+} ble_dfu_evt_type_t;
+
+/**@brief   DFU Procedure type.
+ *
+ * @details This enumeration contains the types of DFU procedures.
+ */
+typedef enum
+{
+    BLE_DFU_START_PROCEDURE        = 1,                                 /**< DFU Start procedure.*/
+    BLE_DFU_INIT_PROCEDURE         = 2,                                 /**< DFU Initialization procedure.*/
+    BLE_DFU_RECEIVE_APP_PROCEDURE  = 3,                                 /**< Firmware receiving procedure.*/
+    BLE_DFU_VALIDATE_PROCEDURE     = 4,                                 /**< Firmware image validation procedure .*/
+    BLE_DFU_PKT_RCPT_REQ_PROCEDURE = 8                                  /**< Packet receipt notification request procedure. */
+} ble_dfu_procedure_t;
+
+/**@brief   DFU Response value type.
+ */
+typedef enum
+{
+    BLE_DFU_RESP_VAL_SUCCESS = 1,                                       /**< Success.*/
+    BLE_DFU_RESP_VAL_INVALID_STATE,                                     /**< Invalid state.*/
+    BLE_DFU_RESP_VAL_NOT_SUPPORTED,                                     /**< Operation not supported.*/
+    BLE_DFU_RESP_VAL_DATA_SIZE,                                         /**< Data size exceeds limit.*/
+    BLE_DFU_RESP_VAL_CRC_ERROR,                                         /**< CRC Error.*/
+    BLE_DFU_RESP_VAL_OPER_FAILED                                        /**< Operation failed.*/
+} ble_dfu_resp_val_t;
+
+
+/**@brief   DFU Packet structure.
+ *
+ * @details This structure contains the value of the DFU Packet characteristic as written by the
+ *          peer and the length of the value written. It will be filled by the DFU Service when the
+ *          peer writes to the DFU Packet characteristic.
+ */
+typedef struct
+{
+    uint8_t *                    p_data;                                /**< Pointer to the received packet. This will point to a word aligned memory location.*/
+    uint8_t                      len;                                   /**< Length of the packet received. */
+} ble_dfu_pkt_write_t;
+
+/**@brief   Packet receipt notification request structure.
+ *
+ * @details This structure contains the contents of the packet receipt notification request
+ *          sent by the DFU Controller.
+ */
+typedef struct
+{
+    uint16_t                     num_of_pkts;                           /**< The number of packets of firmware data to be received by application before sending the next Packet Receipt Notification to the peer. */
+} ble_pkt_rcpt_notif_req_t;
+
+/**@brief   DFU Event structure.
+ *
+ * @details This structure contains the event generated by the DFU Service based on the data
+ *          received from the peer.
+ */
+typedef struct
+{
+    ble_dfu_evt_type_t           ble_dfu_evt_type;                      /**< Type of the event.*/
+    union
+    {
+        ble_dfu_pkt_write_t      ble_dfu_pkt_write;                     /**< The DFU packet received. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PACKET_WRITE.*/
+        ble_pkt_rcpt_notif_req_t pkt_rcpt_notif_req;                    /**< Packet receipt notification request. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED.*/
+    } evt;
+} ble_dfu_evt_t;
+
+// Forward declaration of the ble_dfu_t type.
+typedef struct ble_dfu_s ble_dfu_t;
+
+/**@brief DFU Service event handler type. */
+typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
+
+/**@brief   DFU service structure.
+ *
+ * @details This structure contains status information related to the service.
+ */
+struct ble_dfu_s
+{
+    uint16_t                     conn_handle;                           /**< Handle of the current connection (as provided by the S110 SoftDevice). This will be BLE_CONN_HANDLE_INVALID when not in a connection. */
+    uint16_t                     revision;                              /**< Handle of DFU Service (as provided by the S110 SoftDevice). */
+    uint16_t                     service_handle;                        /**< Handle of DFU Service (as provided by the S110 SoftDevice). */
+    uint8_t                      uuid_type;                             /**< UUID type assigned for DFU Service by the S110 SoftDevice. */
+    ble_gatts_char_handles_t     dfu_pkt_handles;                       /**< Handles related to the DFU Packet characteristic. */
+    ble_gatts_char_handles_t     dfu_ctrl_pt_handles;                   /**< Handles related to the DFU Control Point characteristic. */
+    ble_gatts_char_handles_t     dfu_status_rep_handles;                /**< Handles related to the DFU Status Report characteristic. */
+    ble_gatts_char_handles_t     dfu_rev_handles;                       /**< Handles related to the DFU Revision characteristic. */
+    ble_dfu_evt_handler_t        evt_handler;                           /**< The event handler to be called when an event is to be sent to the application.*/
+    ble_srv_error_handler_t      error_handler;                         /**< Function to be called in case of an error. */
+};
+
+/**@brief      DFU service initialization structure.
+ *
+ * @details    This structure contains the initialization information for the DFU Service. The
+ *             application needs to fill this structure and pass it to the DFU Service using the
+ *             @ref ble_dfu_init function.
+ */
+typedef struct
+{
+    uint16_t                     revision;                              /**< Revision number to be exposed by the DFU service. */
+    ble_dfu_evt_handler_t        evt_handler;                           /**< Event handler to be called for handling events in the Device Firmware Update Service. */
+    ble_srv_error_handler_t      error_handler;                         /**< Function to be called in case of an error. */
+} ble_dfu_init_t;
+
+/**@brief      Function for handling a BLE event.
+ *
+ * @details    The DFU service expects the application to call this function each time an event
+ *             is received from the S110 SoftDevice. This function processes the event, if it is
+ *             relevant for the DFU service and calls the DFU event handler of the application if
+ *             necessary.
+ *
+ * @param[in]  p_dfu        Pointer to the DFU service structure.
+ * @param[in]  p_ble_evt    Pointer to the event received from S110 SoftDevice.
+ */
+void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt);
+
+/**@brief      Function for initializing the DFU service.
+ *
+ * @param[out] p_dfu        Device Firmware Update service structure. This structure will have to be
+ *                          supplied by the application. It will be initialized by this function,
+ *                          and will later be used to identify the service instance.
+ * @param[in]  p_dfu_init   Information needed to initialize the service.
+ *
+ * @return     NRF_SUCCESS if the DFU service and its characteristics were successfully added to the
+ *             S110 SoftDevice. Otherwise an error code.
+ *             This function returns NRF_ERROR_NULL if the value of evt_handler in p_dfu_init
+ *             structure provided is NULL or if the pointers supplied as input are NULL.
+ */
+uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init);
+
+/**@brief       Function for sending response to a control point command.
+ *
+ * @details     This function will encode a DFU Control Point response using the given input
+ *              parameters and will send a notification of the same to the peer.
+ *
+ * @param[in]   p_dfu       Pointer to the DFU service structure.
+ * @param[in]   dfu_proc    Procedure for which this response is to be sent.
+ * @param[in]   resp_val    Response value.
+ *
+ * @return      NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to
+ *              send the notification. Otherwise an error code.
+ *              This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
+ *              peer or if the DFU service is not initialized or if the notification of the DFU
+ *              Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
+ *              if the pointer p_dfu is NULL.
+ */
+uint32_t ble_dfu_response_send(ble_dfu_t *          p_dfu,
+                               ble_dfu_procedure_t  dfu_proc,
+                               ble_dfu_resp_val_t   resp_val);
+
+/**@brief      Function for notifying the peer about the number of bytes of firmware data received.
+ *
+ * @param[in]  p_dfu                      Pointer to the DFU service structure.
+ * @param[in]  num_of_firmware_bytes_rcvd Number of bytes.
+ *
+ * @return     NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send
+ *             the notification. Otherwise an error code.
+ *             This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
+ *             peer or if the DFU service is not initialized or if the notification of the DFU
+ *             Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
+ *             if the pointer p_dfu is NULL.
+ */
+uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
+
+/**@brief      Function for sending Packet Receipt Notification to the peer.
+ *
+ *             This function will encode the number of bytes received as input parameter into a
+ *             notification of the control point characteristic and send it to the peer.
+ *
+ * @param[in]  p_dfu                      Pointer to the DFU service structure.
+ * @param[in]  num_of_firmware_bytes_rcvd Number of bytes of firmware image received.
+ *
+ * @return     NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send
+ *             the notification. Otherwise an error code.
+ *             This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
+ *             peer or if the DFU service is not initialized or if the notification of the DFU
+ *             Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
+ *             if the pointer p_dfu is NULL.
+ */
+uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
+
+#endif // BLE_DFU_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_advdata.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,861 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_advdata.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "ble_gap.h"
+#include "ble_srv_common.h"
+#include "app_util.h"
+
+// NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
+
+// Types of LE Bluetooth Device Address AD type
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
+
+static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
+                                uint8_t                * p_encoded_data,
+                                uint16_t               * p_offset,
+                                uint16_t                 max_size)
+{
+    int8_t i;
+
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode LE Role.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+
+    for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++)
+    {
+        p_encoded_data[*p_offset] = p_tk_value->tk[i];
+    }
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t le_role_encode(ble_advdata_le_role_t   le_role,
+                               uint8_t               * p_encoded_data,
+                               uint16_t              * p_offset,
+                               uint16_t                max_size)
+{
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode LE Role.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_ROLE;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    switch(le_role)
+    {
+        case BLE_ADVDATA_ROLE_ONLY_PERIPH:
+            p_encoded_data[*p_offset] = 0;
+            break;
+        case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
+            p_encoded_data[*p_offset] = 1;
+            break;
+        case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
+            p_encoded_data[*p_offset] = 2;
+            break;
+        case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
+            p_encoded_data[*p_offset] = 3;
+            break;
+        default:
+            return NRF_ERROR_INVALID_PARAM;
+    }
+    *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t ble_device_addr_encode(uint8_t  * p_encoded_data,
+                                       uint16_t * p_offset,
+                                       uint16_t   max_size)
+{
+    uint32_t err_code;
+    ble_gap_addr_t device_addr;
+
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Get BLE address
+    err_code = sd_ble_gap_address_get(&device_addr);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    // Encode LE Bluetooth Device Address
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
+                                               AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
+    *p_offset                 += BLE_GAP_ADDR_LEN;
+    if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
+    {
+        p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
+    }
+    else
+    {
+        p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
+    }
+    *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t name_encode(const ble_advdata_t * p_advdata,
+                            uint8_t             * p_encoded_data,
+                            uint16_t            * p_offset,
+                            uint16_t              max_size)
+{
+    uint32_t err_code;
+    uint16_t rem_adv_data_len;
+    uint16_t actual_length;
+    uint8_t  adv_data_format;
+
+
+    // Validate parameters
+    if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    // Check for buffer overflow.
+    if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) ||
+         ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
+           (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET;
+    actual_length    = rem_adv_data_len;
+
+    // Get GAP device name and length
+    err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET],
+                                          &actual_length);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+    
+    // Check if device intend to use short name and it can fit available data size.
+    if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
+    {
+        // Complete device name can fit, setting Complete Name in Adv Data.
+        adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
+    }
+    else
+    {
+        // Else short name needs to be used. Or application has requested use of short name.
+        adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
+
+        // If application has set a preference on the short name size, it needs to be considered,
+        // else fit what can be fit.
+        if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
+                (p_advdata->short_name_len <= rem_adv_data_len))
+        {
+            // Short name fits available size.
+            actual_length = p_advdata->short_name_len;
+        }
+        // Else whatever can fit the data buffer will be packed.
+        else
+        {
+            actual_length = rem_adv_data_len;
+        }
+    }
+
+    // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE)
+    if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Complete name field in encoded data.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = adv_data_format;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    *p_offset                 += actual_length;
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t appearance_encode(uint8_t  * p_encoded_data,
+                                  uint16_t * p_offset,
+                                  uint16_t   max_size)
+{
+    uint32_t err_code;
+    uint16_t appearance;
+
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Get GAP appearance field.
+    err_code = sd_ble_gap_appearance_get(&appearance);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    // Encode Length, AD Type and Appearance.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_APPEARANCE;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    *p_offset                 += uint16_encode(appearance, &p_encoded_data[*p_offset]);
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t flags_encode(int8_t     flags,
+                             uint8_t  * p_encoded_data,
+                             uint16_t * p_offset,
+                             uint16_t   max_size)
+{
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode flags.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_FLAGS;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = flags;
+    *p_offset                 += AD_TYPE_FLAGS_DATA_SIZE;
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t sec_mgr_oob_flags_encode(uint8_t    oob_flags,
+                                         uint8_t  * p_encoded_data,
+                                         uint16_t * p_offset,
+                                         uint16_t   max_size)
+{
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode flags.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = oob_flags;
+    *p_offset                 += AD_TYPE_OOB_FLAGS_DATA_SIZE;
+
+    return NRF_SUCCESS;
+}
+
+static uint32_t tx_power_level_encode(int8_t     tx_power_level,
+                                      uint8_t  * p_encoded_data,
+                                      uint16_t * p_offset,
+                                      uint16_t   max_size)
+{
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode TX Power Level.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
+                                                  AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = tx_power_level;
+    *p_offset                 += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
+                                       uint8_t                         adv_type,
+                                       uint8_t                         uuid_size,
+                                       uint8_t                       * p_encoded_data,
+                                       uint16_t                      * p_offset,
+                                       uint16_t                        max_size)
+{
+    int      i;
+    bool     is_heading_written = false;
+    uint16_t start_pos          = *p_offset;
+    uint16_t length;
+
+    for (i = 0; i < p_uuid_list->uuid_cnt; i++)
+    {
+        uint32_t   err_code;
+        uint8_t    encoded_size;
+        ble_uuid_t uuid = p_uuid_list->p_uuids[i];
+        
+        // Find encoded uuid size.
+        err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+
+        // Check size.
+        if (encoded_size == uuid_size)
+        {
+            uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET;
+            
+            // Check for buffer overflow
+            if (((*p_offset) + encoded_size + heading_bytes) > max_size)
+            {
+                return NRF_ERROR_DATA_SIZE;
+            }
+
+            if (!is_heading_written)
+            {
+                // Write AD structure heading.
+                *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+                p_encoded_data[*p_offset]  = adv_type;
+                *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+                is_heading_written         = true;
+            }
+
+            // Write UUID.
+            err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
+            if (err_code != NRF_SUCCESS)
+            {
+                return err_code;
+            }
+            *p_offset += encoded_size;
+        }
+    }
+
+    if (is_heading_written)
+    {
+        // Write length.
+        length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE);
+        // There is only 1 byte intended to encode length
+        if(length > 0x00FF)
+        {
+            return NRF_ERROR_DATA_SIZE;
+        }
+        p_encoded_data[start_pos] = (uint8_t)length;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
+                                 uint8_t                         adv_type_16,
+                                 uint8_t                         adv_type_128,
+                                 uint8_t                       * p_encoded_data,
+                                 uint16_t                      * p_offset,
+                                 uint16_t                        max_size)
+{
+    uint32_t err_code;
+
+    // Encode 16 bit UUIDs.
+    err_code = uuid_list_sized_encode(p_uuid_list,
+                                      adv_type_16,
+                                      sizeof(uint16_le_t),
+                                      p_encoded_data,
+                                      p_offset,
+                                      max_size);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    // Encode 128 bit UUIDs.
+    err_code = uuid_list_sized_encode(p_uuid_list,
+                                      adv_type_128,
+                                      sizeof(ble_uuid128_t),
+                                      p_encoded_data,
+                                      p_offset,
+                                      max_size);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
+{
+    // Check Minimum Connection Interval.
+    if ((p_conn_int->min_conn_interval < 0x0006) ||
+        (
+            (p_conn_int->min_conn_interval > 0x0c80) &&
+            (p_conn_int->min_conn_interval != 0xffff)
+        )
+       )
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    // Check Maximum Connection Interval.
+    if ((p_conn_int->max_conn_interval < 0x0006) || 
+        (
+            (p_conn_int->max_conn_interval > 0x0c80) && 
+            (p_conn_int->max_conn_interval != 0xffff)
+        )
+       )
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
+    if ((p_conn_int->min_conn_interval != 0xffff) &&
+        (p_conn_int->max_conn_interval != 0xffff) &&
+        (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
+        )
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
+                                uint8_t                      * p_encoded_data,
+                                uint16_t                     * p_offset,
+                                uint16_t                       max_size)
+{
+    uint32_t err_code;
+
+    // Check for buffer overflow.
+    if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Check parameters.
+    err_code = conn_int_check(p_conn_int);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    // Encode Length and AD Type.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+
+    // Encode Minimum and Maximum Connection Intervals.
+    *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
+    *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
+                                           uint8_t                        * p_encoded_data,
+                                           uint16_t                       * p_offset,
+                                           uint16_t                         max_size)
+{
+    uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
+
+    // Check for buffer overflow.
+    if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
+    if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    // Encode Length and AD Type.
+    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
+    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
+    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+    
+    // Encode Company Identifier.
+    *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
+    
+    // Encode additional manufacturer specific data.
+    if (p_manuf_sp_data->data.size > 0)
+    {
+        if (p_manuf_sp_data->data.p_data == NULL)
+        {
+            return NRF_ERROR_INVALID_PARAM;
+        }
+        memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
+        *p_offset += p_manuf_sp_data->data.size;
+    }
+
+    return NRF_SUCCESS;
+}
+
+// Implemented only for 16-bit UUIDs
+static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
+                                    uint8_t             * p_encoded_data,
+                                    uint16_t            * p_offset,
+                                    uint16_t              max_size)
+{
+    uint8_t i;
+
+    // Check parameter consistency.
+    if (p_advdata->p_service_data_array == NULL)
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    for (i = 0; i < p_advdata->service_data_count; i++)
+    {
+        ble_advdata_service_data_t * p_service_data;
+        uint32_t                     data_size;
+
+        p_service_data = &p_advdata->p_service_data_array[i];
+        // For now implemented only for 16-bit UUIDs
+        data_size      = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
+
+        // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
+        if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
+        {
+            return NRF_ERROR_DATA_SIZE;
+        }
+
+        // Encode Length and AD Type.
+        p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
+        *p_offset                 += ADV_LENGTH_FIELD_SIZE;
+        p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SERVICE_DATA;
+        *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
+
+        // Encode service 16-bit UUID.
+        *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
+
+        // Encode additional service data.
+        if (p_service_data->data.size > 0)
+        {
+            if (p_service_data->data.p_data == NULL)
+            {
+                return NRF_ERROR_INVALID_PARAM;
+            }
+            memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
+            *p_offset += p_service_data->data.size;
+        }
+    }
+
+    return NRF_SUCCESS;
+}
+
+uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
+                         uint8_t             * const p_encoded_data,
+                         uint16_t            * const p_len)
+{
+    uint32_t err_code = NRF_SUCCESS;
+    uint16_t max_size = *p_len;
+    *p_len = 0;
+
+    //Encode Security Manager OOB Flags
+    if (p_advdata->p_sec_mgr_oob_flags != NULL)
+    {
+        err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
+                                             p_encoded_data,
+                                             p_len,
+                                             max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+		
+    // Encode Security Manager TK value
+    if (NULL != p_advdata->p_tk_value)
+    {
+        err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode LE Role
+    if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
+    {
+        err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode LE Bluetooth Device Address
+    if (p_advdata->include_ble_device_addr)
+    {
+        err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode appearance.
+    if (p_advdata->include_appearance)
+    {
+        err_code = appearance_encode(p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    //Encode Flags
+    if(p_advdata->flags != 0 )
+    {
+        err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    } 
+
+    // Encode TX power level.
+    if (p_advdata->p_tx_power_level != NULL)
+    {
+        err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
+                                         p_encoded_data,
+                                         p_len,
+                                         max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+    
+    // Encode 'more available' uuid list.
+    if (p_advdata->uuids_more_available.uuid_cnt > 0)
+    {
+        err_code = uuid_list_encode(&p_advdata->uuids_more_available,
+                                    BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
+                                    BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
+                                    p_encoded_data,
+                                    p_len,
+                                    max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode 'complete' uuid list.
+    if (p_advdata->uuids_complete.uuid_cnt > 0)
+    {
+        err_code = uuid_list_encode(&p_advdata->uuids_complete,
+                                    BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
+                                    BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
+                                    p_encoded_data,
+                                    p_len,
+                                    max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode 'solicited service' uuid list.
+    if (p_advdata->uuids_solicited.uuid_cnt > 0)
+    {
+        err_code = uuid_list_encode(&p_advdata->uuids_solicited,
+                                    BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
+                                    BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
+                                    p_encoded_data,
+                                    p_len,
+                                    max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode Slave Connection Interval Range.
+    if (p_advdata->p_slave_conn_int != NULL)
+    {
+        err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode Manufacturer Specific Data.
+    if (p_advdata->p_manuf_specific_data != NULL)
+    {
+        err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
+                                              p_encoded_data,
+                                              p_len,
+                                              max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode Service Data.
+    if (p_advdata->service_data_count > 0)
+    {
+        err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
+    if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
+    {
+        err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    return err_code;
+}
+
+
+static uint32_t advdata_check(const ble_advdata_t * p_advdata)
+{
+    // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
+    if (
+        ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
+       )
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+static uint32_t srdata_check(const ble_advdata_t * p_srdata)
+{
+    // Flags shall not be included in the scan response data.
+    if (p_srdata->flags)
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
+{
+    uint32_t  err_code;
+    uint16_t  len_advdata = BLE_GAP_ADV_MAX_SIZE;
+    uint16_t  len_srdata  = BLE_GAP_ADV_MAX_SIZE;
+    uint8_t   encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
+    uint8_t   encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
+    uint8_t * p_encoded_advdata;
+    uint8_t * p_encoded_srdata;
+
+    // Encode advertising data (if supplied).
+    if (p_advdata != NULL)
+    {
+        err_code = advdata_check(p_advdata);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+
+        err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+        p_encoded_advdata = encoded_advdata;
+    }
+    else
+    {
+        p_encoded_advdata = NULL;
+        len_advdata = 0;
+    }
+
+    // Encode scan response data (if supplied).
+    if (p_srdata != NULL)
+    {
+        err_code = srdata_check(p_srdata);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+
+        err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+        p_encoded_srdata = encoded_srdata;
+    }
+    else
+    {
+        p_encoded_srdata = NULL;
+        len_srdata = 0;
+    }
+
+    // Pass encoded advertising data and/or scan response data to the stack.
+    return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_advdata.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_sdk_lib_advdata Advertising and Scan Response Data Encoder
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Functions for encoding data in the Advertising and Scan Response Data format,
+ *        and for passing the data to the stack.
+ */
+
+#ifndef BLE_ADVDATA_H__
+#define BLE_ADVDATA_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "ble.h"
+#include "app_util.h"
+
+
+#define ADV_LENGTH_FIELD_SIZE              1UL                                 /**< Advertising Data and Scan Response format contains 1 octet for the length. */
+#define ADV_AD_TYPE_FIELD_SIZE             1UL                                 /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */
+#define ADV_AD_DATA_OFFSET                 (ADV_LENGTH_FIELD_SIZE + \
+                                            ADV_AD_TYPE_FIELD_SIZE)            /**< Offset for the AD data field of the Advertising Data and Scan Response format. */
+#define AD_TYPE_TK_VALUE_DATA_SIZE         (sizeof(ble_advdata_tk_value_t))    /**< Data size (in octets) of the Security Manager TK value AD type. */
+#define AD_TYPE_TK_VALUE_SIZE              (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_TK_VALUE_DATA_SIZE)        /**< Size (in octets) of the Security Manager TK value AD type. */
+#define AD_TYPE_LE_ROLE_DATA_SIZE          1UL                                 /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_LE_ROLE_SIZE               (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_LE_ROLE_DATA_SIZE)         /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE  1UL                                 /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE  (BLE_GAP_ADDR_LEN + \
+                                            AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_BLE_DEVICE_ADDR_SIZE       (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_APPEARANCE_DATA_SIZE       2UL                                 /**< Data size (in octets) of the Appearance AD type. */
+#define AD_TYPE_APPEARANCE_SIZE            (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_APPEARANCE_DATA_SIZE)      /**< Size (in octets) of the Appearance AD type. */
+#define AD_TYPE_FLAGS_DATA_SIZE            1UL                                 /**< Data size (in octets) of the Flags AD type. */
+#define AD_TYPE_FLAGS_SIZE                 (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_FLAGS_DATA_SIZE)           /**< Size (in octets) of the Flags AD type. */
+#define AD_TYPE_TX_POWER_LEVEL_DATA_SIZE   1UL                                 /**< Data size (in octets) of the TX Power Level AD type. */
+#define AD_TYPE_TX_POWER_LEVEL_SIZE        (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_TX_POWER_LEVEL_DATA_SIZE)  /**< Size (in octets) of the TX Power Level AD type. */
+#define AD_TYPE_CONN_INT_DATA_SIZE         4UL                                 /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
+#define AD_TYPE_CONN_INT_SIZE              (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_CONN_INT_DATA_SIZE)        /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
+#define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE    2UL                                 /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */
+#define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE  2UL                                 /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */
+#define AD_TYPE_OOB_FLAGS_DATA_SIZE        1UL                                 /**< Data size (in octets) of the Security Manager OOB Flags AD type. */
+#define AD_TYPE_OOB_FLAGS_SIZE             (ADV_AD_DATA_OFFSET + \
+                                            AD_TYPE_OOB_FLAGS_DATA_SIZE)       /**< Size (in octets) of the Security Manager OOB Flags AD type. */
+
+#define AD_TYPE_SEC_MGR_OOB_FLAG_SET                   1U                      /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR                 0U                      /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS  0UL                     /**< Security Manager OOB Data Present Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS  1UL                     /**< Security Manager OOB Low Energy Supported Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS     2UL                     /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC        0UL                     /**< Security Manager OOB Public Address type. */
+#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM        1UL                     /**< Security Manager OOB Random Address type. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS      3UL                     /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */
+
+
+/**@brief Security Manager TK value. */
+typedef struct
+{
+  uint8_t tk[BLE_GAP_SEC_KEY_LEN];   /**< Array containing TK value. */
+} ble_advdata_tk_value_t;
+
+/**@brief Advertising data LE Role types. This enumeration contains the options available for the LE role inside
+ *        the advertising data. */
+typedef enum
+{
+    BLE_ADVDATA_ROLE_NOT_PRESENT = 0,                                 /**< LE Role AD structure not present. */
+    BLE_ADVDATA_ROLE_ONLY_PERIPH,                                     /**< Only Peripheral Role supported. */
+    BLE_ADVDATA_ROLE_ONLY_CENTRAL,                                    /**< Only Central Role supported. */
+    BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED,                           /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */
+    BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED                           /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */
+} ble_advdata_le_role_t;
+
+/**@brief Advertising data name type. This enumeration contains the options available for the device name inside
+ *        the advertising data. */
+typedef enum
+{
+    BLE_ADVDATA_NO_NAME,                                              /**< Include no device name in advertising data. */
+    BLE_ADVDATA_SHORT_NAME,                                           /**< Include short device name in advertising data. */
+    BLE_ADVDATA_FULL_NAME                                             /**< Include full device name in advertising data. */
+} ble_advdata_name_type_t;
+
+/**@brief UUID list type. */
+typedef struct
+{
+    uint16_t                     uuid_cnt;                            /**< Number of UUID entries. */
+    ble_uuid_t *                 p_uuids;                             /**< Pointer to UUID array entries. */
+} ble_advdata_uuid_list_t;
+
+/**@brief Connection interval range structure. */
+typedef struct
+{
+    uint16_t                     min_conn_interval;                   /**< Minimum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). */
+    uint16_t                     max_conn_interval;                   /**< Maximum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). The value 0xFFFF indicates no specific maximum. */
+} ble_advdata_conn_int_t;
+
+/**@brief Manufacturer specific data structure. */
+typedef struct
+{
+    uint16_t                     company_identifier;                  /**< Company identifier code. */
+    uint8_array_t                data;                                /**< Additional manufacturer specific data. */
+} ble_advdata_manuf_data_t;
+
+/**@brief Service data structure. */
+typedef struct
+{
+    uint16_t                     service_uuid;                        /**< Service UUID. */
+    uint8_array_t                data;                                /**< Additional service data. */
+} ble_advdata_service_data_t;
+
+/**@brief Advertising data structure. This structure contains all options and data needed for encoding and
+ *        setting the advertising data. */
+typedef struct
+{
+    ble_advdata_name_type_t      name_type;                           /**< Type of device name. */
+    uint8_t                      short_name_len;                      /**< Length of short device name (if short type is specified). */
+    bool                         include_appearance;                  /**< Determines if Appearance shall be included. */
+    uint8_t                      flags;                               /**< Advertising data Flags field. */
+    int8_t *                     p_tx_power_level;                    /**< TX Power Level field. */
+    ble_advdata_uuid_list_t      uuids_more_available;                /**< List of UUIDs in the 'More Available' list. */
+    ble_advdata_uuid_list_t      uuids_complete;                      /**< List of UUIDs in the 'Complete' list. */
+    ble_advdata_uuid_list_t      uuids_solicited;                     /**< List of solicited UUIDs. */
+    ble_advdata_conn_int_t *     p_slave_conn_int;                    /**< Slave Connection Interval Range. */
+    ble_advdata_manuf_data_t *   p_manuf_specific_data;               /**< Manufacturer specific data. */
+    ble_advdata_service_data_t * p_service_data_array;                /**< Array of Service data structures. */
+    uint8_t                      service_data_count;                  /**< Number of Service data structures. */
+    bool                         include_ble_device_addr;             /**< Determines if LE Bluetooth Device Address shall be included. */
+    ble_advdata_le_role_t        le_role;                             /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT.*/
+    ble_advdata_tk_value_t *     p_tk_value;                          /**< Security Manager TK value field. Included when different from NULL.*/
+    uint8_t *                    p_sec_mgr_oob_flags;                 /**< Security Manager Out Of Band Flags field. Included when different from NULL.*/
+} ble_advdata_t;
+
+/**@brief Function for encoding data in the Advertising and Scan Response data format
+ *        (AD structures).
+ *
+ * @details This function encodes data into the Advertising and Scan Response data format
+ *          (AD structures) based on the selections in the supplied structures. This function can be used to
+ *          create a payload of Advertising packet or Scan Response packet, or a payload of NFC
+ *          message intended for initiating the Out-of-Band pairing.
+ *
+ * @param[in]      p_advdata       Pointer to the structure for specifying the content of encoded data.
+ * @param[out]     p_encoded_data  Pointer to the buffer where encoded data will be returned.
+ * @param[in,out]  p_len           \c in: Size of \p p_encoded_data buffer.
+ *                                 \c out: Length of encoded data.
+ *
+ * @retval NRF_SUCCESS             If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
+ * @retval NRF_ERROR_DATA_SIZE     If the operation failed because not all the requested data could fit into the
+ *                                 provided buffer or some encoded AD structure is too long and its
+ *                                 length cannot be encoded with one octet.
+ *
+ * @warning This API may override the application's request to use the long name and use a short name
+ * instead. This truncation will occur in case the long name does not fit the provided buffer size.
+ * The application can specify a preferred short name length if truncation is required.
+ * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
+ * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
+ * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
+ * However, it should be noted that this is just a preference that the application can specify, and
+ * if the preference is too large to fit in the provided buffer, the name can be truncated further.
+ */
+uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
+                         uint8_t             * const p_encoded_data,
+                         uint16_t            * const p_len);
+
+/**@brief Function for encoding and setting the advertising data and/or scan response data.
+ *
+ * @details This function encodes advertising data and/or scan response data based on the selections
+ *          in the supplied structures, and passes the encoded data to the stack.
+ *
+ * @param[in]   p_advdata   Structure for specifying the content of the advertising data.
+ *                          Set to NULL if advertising data is not to be set.
+ * @param[in]   p_srdata    Structure for specifying the content of the scan response data.
+ *                          Set to NULL if scan response data is not to be set.
+ *
+ * @retval NRF_SUCCESS             If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
+ * @retval NRF_ERROR_DATA_SIZE     If the operation failed because not all the requested data could fit into the
+ *                                 advertising packet. The maximum size of the advertisement packet
+ *                                 is @ref BLE_GAP_ADV_MAX_SIZE.
+ *
+ * @warning This API may override the application's request to use the long name and use a short name
+ * instead. This truncation will occur in case the long name does not fit the provided buffer size.
+ * The application can specify a preferred short name length if truncation is required.
+ * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
+ * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
+ * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
+ * However, it should be noted that this is just a preference that the application can specify, and
+ * if the preference is too large to fit in the provided buffer, the name can be truncated further.
+ */
+uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata);
+
+#endif // BLE_ADVDATA_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_params.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_conn_params.h"
+#include <stdlib.h>
+#include "nordic_common.h"
+#include "ble_hci.h"
+#include "ble_srv_common.h"
+#include "app_util.h"
+
+#ifdef USE_APP_TIMER
+#include "app_timer.h"
+#else
+    #ifdef YOTTA_CFG_MBED_OS
+        #include "mbed-drivers/mbed.h"
+    #else
+        #include "mbed.h"
+    #endif
+#endif
+
+static ble_conn_params_init_t m_conn_params_config;     /**< Configuration as specified by the application. */
+static ble_gap_conn_params_t  m_preferred_conn_params;  /**< Connection parameters preferred by the application. */
+static uint8_t                m_update_count;           /**< Number of Connection Parameter Update messages that has currently been sent. */
+static uint16_t               m_conn_handle;            /**< Current connection handle. */
+static ble_gap_conn_params_t  m_current_conn_params;    /**< Connection parameters received in the most recent Connect event. */
+#ifdef USE_APP_TIMER
+static app_timer_id_t         m_conn_params_timer_id;   /**< Connection parameters timer. */
+#else
+static Ticker                 m_conn_params_timer;
+#endif
+
+static bool m_change_param = false;
+
+static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params)
+{
+    // Check if interval is within the acceptable range.
+    // NOTE: Using max_conn_interval in the received event data because this contains
+    //       the client's connection interval.
+    if (
+        (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval)
+        && 
+        (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)
+       )
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+#ifdef USE_APP_TIMER
+static void update_timeout_handler(void * p_context)
+{
+    UNUSED_PARAMETER(p_context);
+
+#else /* #if !USE_APP_TIMER */
+static void update_timeout_handler(void)
+{
+    m_conn_params_timer.detach(); /* this is supposed to be a single-shot timer callback */
+#endif /* #if !USE_APP_TIMER */
+    if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+    {
+        // Check if we have reached the maximum number of attempts
+        m_update_count++;
+        if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
+        {
+            uint32_t err_code;
+
+            // Parameters are not ok, send connection parameters update request.
+            err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
+            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
+            {
+                m_conn_params_config.error_handler(err_code);
+            }
+        }
+        else
+        {
+            m_update_count = 0;
+
+            // Negotiation failed, disconnect automatically if this has been configured
+            if (m_conn_params_config.disconnect_on_fail)
+            {
+                uint32_t err_code;
+
+                err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
+                if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
+                {
+                    m_conn_params_config.error_handler(err_code);
+                }
+            }
+
+            // Notify the application that the procedure has failed
+            if (m_conn_params_config.evt_handler != NULL)
+            {
+                ble_conn_params_evt_t evt;
+
+                evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
+                m_conn_params_config.evt_handler(&evt);
+            }
+        }
+    }
+}
+
+
+uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
+{
+    uint32_t err_code;
+
+    m_conn_params_config = *p_init;
+    m_change_param = false;
+    if (p_init->p_conn_params != NULL)
+    {
+        m_preferred_conn_params = *p_init->p_conn_params;
+
+        // Set the connection params in stack
+        err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+    else
+    {
+        // Fetch the connection params from stack
+        err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    m_conn_handle  = BLE_CONN_HANDLE_INVALID;
+    m_update_count = 0;
+
+#ifdef USE_APP_TIMER
+    return app_timer_create(&m_conn_params_timer_id,
+                            APP_TIMER_MODE_SINGLE_SHOT,
+                            update_timeout_handler);
+#else
+    return NRF_SUCCESS;
+#endif
+}
+
+
+uint32_t ble_conn_params_stop(void)
+{
+#ifdef USE_APP_TIMER
+    return app_timer_stop(m_conn_params_timer_id);
+#else /* #if !USE_APP_TIMER */
+    m_conn_params_timer.detach();
+    return NRF_SUCCESS;
+#endif /* #if !USE_APP_TIMER */
+}
+
+
+static void conn_params_negotiation(void)
+{
+    // Start negotiation if the received connection parameters are not acceptable
+    if (!is_conn_params_ok(&m_current_conn_params))
+    {
+#ifdef USE_APP_TIMER
+        uint32_t err_code;
+#endif
+        uint32_t timeout_ticks;
+
+        if (m_change_param)
+        {
+            // Notify the application that the procedure has failed
+            if (m_conn_params_config.evt_handler != NULL)
+            {
+                ble_conn_params_evt_t evt;
+
+                evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
+                m_conn_params_config.evt_handler(&evt);
+            }
+        }
+        else
+        {
+            if (m_update_count == 0)
+            {
+                // First connection parameter update
+                timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
+            }
+            else
+            {
+                timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
+            }
+
+#ifdef USE_APP_TIMER
+            err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
+            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
+            {
+                m_conn_params_config.error_handler(err_code);
+            }
+#else
+            m_conn_params_timer.attach(update_timeout_handler, timeout_ticks / 32768);
+#endif
+        }
+    }
+    else
+    {
+        // Notify the application that the procedure has succeded
+        if (m_conn_params_config.evt_handler != NULL)
+        {
+            ble_conn_params_evt_t evt;
+
+            evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
+            m_conn_params_config.evt_handler(&evt);
+        }
+    }
+    m_change_param = false;
+}
+
+
+static void on_connect(ble_evt_t * p_ble_evt)
+{
+    // Save connection parameters
+    m_conn_handle         = p_ble_evt->evt.gap_evt.conn_handle;
+    m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
+    m_update_count        = 0;  // Connection parameter negotiation should re-start every connection
+
+    // Check if we shall handle negotiation on connect
+    if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
+    {
+        conn_params_negotiation();
+    }
+}
+
+
+static void on_disconnect(ble_evt_t * p_ble_evt)
+{
+#ifdef USE_APP_TIMER
+    uint32_t err_code;
+#endif
+
+    m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+    // Stop timer if running
+    m_update_count = 0; // Connection parameters updates should happen during every connection
+
+#ifdef USE_APP_TIMER
+    err_code = app_timer_stop(m_conn_params_timer_id);
+    if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
+    {
+        m_conn_params_config.error_handler(err_code);
+    }
+#else
+    m_conn_params_timer.detach();
+#endif
+}
+
+
+static void on_write(ble_evt_t * p_ble_evt)
+{
+    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+    // Check if this the correct CCCD
+    if (
+        (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
+        &&
+        (p_evt_write->len == 2)
+       )
+    {
+        // Check if this is a 'start notification'
+        if (ble_srv_is_notification_enabled(p_evt_write->data))
+        {
+            // Do connection parameter negotiation if necessary
+            conn_params_negotiation();
+        }
+        else
+        {
+#ifdef USE_APP_TIMER
+            uint32_t err_code;
+
+            // Stop timer if running
+            err_code = app_timer_stop(m_conn_params_timer_id);
+            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
+            {
+                m_conn_params_config.error_handler(err_code);
+            }
+#else /* #if !USE_APP_TIMER */
+            m_conn_params_timer.detach();
+#endif /* #if !USE_APP_TIMER */
+        }
+    }
+}
+
+
+static void on_conn_params_update(ble_evt_t * p_ble_evt)
+{
+    // Copy the parameters
+    m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
+
+    conn_params_negotiation();
+}
+
+
+void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
+{
+    switch (p_ble_evt->header.evt_id)
+    {
+        case BLE_GAP_EVT_CONNECTED:
+            on_connect(p_ble_evt);
+            break;
+
+        case BLE_GAP_EVT_DISCONNECTED:
+            on_disconnect(p_ble_evt);
+            break;
+
+        case BLE_GATTS_EVT_WRITE:
+            on_write(p_ble_evt);
+            break;
+
+        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+            on_conn_params_update(p_ble_evt);
+            break;
+
+        default:
+            // No implementation needed.
+            break;
+    }
+}
+
+
+uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t * new_params)
+{
+    uint32_t err_code;
+
+    m_preferred_conn_params = *new_params;
+    // Set the connection params in stack
+    err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
+    if (err_code == NRF_SUCCESS)
+    {
+        if (!is_conn_params_ok(&m_current_conn_params))
+        {
+            m_change_param = true;
+            err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
+            m_update_count = 1;
+        }
+        else
+        {
+            // Notify the application that the procedure has succeded
+            if (m_conn_params_config.evt_handler != NULL)
+            {
+                ble_conn_params_evt_t evt;
+
+                evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
+                m_conn_params_config.evt_handler(&evt);
+            }
+            err_code = NRF_SUCCESS;
+        }
+    }
+    return err_code;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_params.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_sdk_lib_conn_params Connection Parameters Negotiation
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for initiating and executing a connection parameters negotiation procedure.
+ */
+
+#ifndef BLE_CONN_PARAMS_H__
+#define BLE_CONN_PARAMS_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+
+/**@brief Connection Parameters Module event type. */
+typedef enum
+{
+    BLE_CONN_PARAMS_EVT_FAILED   ,                                  /**< Negotiation procedure failed. */
+    BLE_CONN_PARAMS_EVT_SUCCEEDED                                   /**< Negotiation procedure succeeded. */
+} ble_conn_params_evt_type_t;
+
+/**@brief Connection Parameters Module event. */
+typedef struct
+{
+    ble_conn_params_evt_type_t evt_type;                            /**< Type of event. */
+} ble_conn_params_evt_t;
+
+/**@brief Connection Parameters Module event handler type. */
+typedef void (*ble_conn_params_evt_handler_t) (ble_conn_params_evt_t * p_evt);
+
+/**@brief Connection Parameters Module init structure. This contains all options and data needed for
+ *        initialization of the connection parameters negotiation module. */
+typedef struct
+{
+    ble_gap_conn_params_t *       p_conn_params;                    /**< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host. */
+    uint32_t                      first_conn_params_update_delay;   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks). */
+    uint32_t                      next_conn_params_update_delay;    /**< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0. */
+    uint8_t                       max_conn_params_update_count;     /**< Number of attempts before giving up the negotiation. */
+    uint16_t                      start_on_notify_cccd_handle;      /**< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event. */
+    bool                          disconnect_on_fail;               /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise. */
+    ble_conn_params_evt_handler_t evt_handler;                      /**< Event handler to be called for handling events in the Connection Parameters. */
+    ble_srv_error_handler_t       error_handler;                    /**< Function to be called in case of an error. */
+} ble_conn_params_init_t;
+
+
+/**@brief Function for initializing the Connection Parameters module.
+ *
+ * @note If the negotiation procedure should be triggered when notification/indication of 
+ *       any characteristic is enabled by the peer, then this function must be called after
+ *       having initialized the services.
+ *
+ * @param[in]   p_init  This contains information needed to initialize this module.
+ *
+ * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init);
+
+/**@brief Function for stopping the Connection Parameters module.
+ *
+ * @details This function is intended to be used by the application to clean up the connection
+ *          parameters update module. This will stop the connection parameters update timer if
+ *          running, thereby preventing any impending connection parameters update procedure. This
+ *          function must be called by the application when it needs to clean itself up (for
+ *          example, before disabling the bluetooth SoftDevice) so that an unwanted timer expiry
+ *          event can be avoided.
+ *
+ * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_conn_params_stop(void);
+
+/**@brief Function for changing the current connection parameters to a new set.
+ *
+ *  @details Use this function to change the connection parameters to a new set of parameter 
+ *       (ie different from the ones given at init of the module).
+ *       This function is usefull for scenario where most of the time the application
+ *       needs a relatively big connection interval, and just sometimes, for a temporary
+ *       period requires shorter connection interval, for example to transfer a higher
+ *       amount of data.
+ *       If the given parameters does not match the current connection's parameters
+ *       this function initiates a new negotiation.
+ *
+ * @param[in]   new_params  This contains the new connections parameters to setup.
+ *
+ * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params);
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack that are of interest to this module.
+ *
+ * @param[in]   p_ble_evt  The event received from the BLE stack.
+ */
+void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt);
+
+#endif // BLE_CONN_PARAMS_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_state.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_conn_state.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "ble.h"
+#include "sdk_mapped_flags.h"
+#include "app_error.h"
+
+
+#if defined(__CC_ARM)
+  #pragma push
+  #pragma anon_unions
+#elif defined(__ICCARM__)
+  #pragma language=extended
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#endif
+
+
+#define BLE_CONN_STATE_N_DEFAULT_FLAGS 5                                                       /**< The number of flags kept for each connection, excluding user flags. */
+#define BLE_CONN_STATE_N_FLAGS (BLE_CONN_STATE_N_DEFAULT_FLAGS + BLE_CONN_STATE_N_USER_FLAGS)  /**< The number of flags kept for each connection, including user flags. */
+
+
+/**@brief Structure containing all the flag collections maintained by the Connection State module.
+ */
+typedef struct
+{
+    sdk_mapped_flags_t valid_flags;                                 /**< Flags indicating which connection handles are valid. */
+    sdk_mapped_flags_t connected_flags;                             /**< Flags indicating which connections are connected, since disconnected connection handles will not immediately be invalidated. */
+    sdk_mapped_flags_t central_flags;                               /**< Flags indicating in which connections the local device is the central. */
+    sdk_mapped_flags_t encrypted_flags;                             /**< Flags indicating which connections are encrypted. */
+    sdk_mapped_flags_t mitm_protected_flags;                        /**< Flags indicating which connections have encryption with protection from man-in-the-middle attacks. */
+    sdk_mapped_flags_t user_flags[BLE_CONN_STATE_N_USER_FLAGS];     /**< Flags that can be reserved by the user. The flags will be cleared when a connection is invalidated, otherwise, the user is wholly responsible for the flag states. */
+} ble_conn_state_flag_collections_t;
+
+
+/**@brief Structure containing the internal state of the Connection State module.
+ */
+typedef struct
+{
+    uint16_t           acquired_flags;                              /**< Bitmap for keeping track of which user flags have been acquired. */
+    uint16_t           valid_conn_handles[SDK_MAPPED_FLAGS_N_KEYS]; /**< List of connection handles used as keys for the sdk_mapped_flags module. */
+    union
+    {
+        ble_conn_state_flag_collections_t flags;                              /**< Flag collections kept by the Connection State module. */
+        sdk_mapped_flags_t                flag_array[BLE_CONN_STATE_N_FLAGS]; /**< Flag collections as array to allow use of @ref sdk_mapped_flags_bulk_update_by_key() when setting all flags. */
+    };
+} ble_conn_state_t;
+
+
+#if defined(__CC_ARM)
+  #pragma pop
+#elif defined(__ICCARM__)
+  /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#endif
+
+
+static ble_conn_state_t m_bcs = {0}; /**< Instantiation of the internal state. */
+
+
+/**@brief Function for resetting all internal memory to the values it had at initialization.
+ */
+void bcs_internal_state_reset(void)
+{
+    memset( &m_bcs, 0, sizeof(ble_conn_state_t) );
+}
+
+
+/**@brief Function for activating a connection record.
+ *
+ * @param p_record     The record to activate.
+ * @param conn_handle  The connection handle to copy into the record.
+ * @param role         The role of the connection.
+ *
+ * @return whether the record was activated successfully.
+ */
+static bool record_activate(uint16_t conn_handle)
+{
+    uint16_t available_index = sdk_mapped_flags_first_key_index_get(~m_bcs.flags.valid_flags);
+
+    if (available_index != SDK_MAPPED_FLAGS_INVALID_INDEX)
+    {
+        m_bcs.valid_conn_handles[available_index] = conn_handle;
+        sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
+                                      &m_bcs.flags.connected_flags,
+                                       conn_handle,
+                                       1);
+        sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
+                                      &m_bcs.flags.valid_flags,
+                                       conn_handle,
+                                       1);
+
+        return true;
+    }
+
+    return false;
+}
+
+
+/**@brief Function for marking a connection record as invalid and resetting the values.
+ *
+ * @param p_record  The record to invalidate.
+ */
+static void record_invalidate(uint16_t conn_handle)
+{
+    sdk_mapped_flags_bulk_update_by_key(m_bcs.valid_conn_handles,
+                                        m_bcs.flag_array,
+                                        BLE_CONN_STATE_N_FLAGS,
+                                        conn_handle,
+                                        0);
+}
+
+
+/**@brief Function for marking a connection as disconnected. See @ref BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @param p_record   The record of the connection to set as disconnected.
+ */
+static void record_set_disconnected(uint16_t conn_handle)
+{
+    sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
+                                  &m_bcs.flags.connected_flags,
+                                   conn_handle,
+                                   0);
+}
+
+
+/**@brief Function for invalidating records with a @ref BLE_CONN_STATUS_DISCONNECTED
+ *        connection status
+ */
+static void record_purge_disconnected()
+{
+    sdk_mapped_flags_key_list_t disconnected_list;
+
+    disconnected_list = sdk_mapped_flags_key_list_get(
+                                   m_bcs.valid_conn_handles,
+                                 (~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags));
+
+    for (int i = 0; i < disconnected_list.len; i++)
+    {
+        record_invalidate(disconnected_list.flag_keys[i]);
+    }
+}
+
+
+/**@brief Function for checking if a user flag has been acquired.
+ *
+ * @param[in]  flag_id  Which flag to check.
+ *
+ * @return  Whether the flag has been acquired.
+ */
+static bool user_flag_is_acquired(ble_conn_state_user_flag_id_t flag_id)
+{
+    return ((m_bcs.acquired_flags & (1 << flag_id)) != 0);
+}
+
+
+/**@brief Function for marking a user flag as acquired.
+ *
+ * @param[in]  flag_id  Which flag to mark.
+ */
+static void user_flag_acquire(ble_conn_state_user_flag_id_t flag_id)
+{
+    m_bcs.acquired_flags |= (1 << flag_id);
+}
+
+
+void ble_conn_state_init(void)
+{
+    bcs_internal_state_reset();
+}
+
+
+void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt)
+{
+    switch (p_ble_evt->header.evt_id)
+    {
+        case BLE_GAP_EVT_CONNECTED:
+            record_purge_disconnected();
+
+            if ( !record_activate(p_ble_evt->evt.gap_evt.conn_handle) )
+            {
+                // No more records available. Should not happen.
+                APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
+            }
+            else
+            {
+#if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110)
+                bool is_central = false;
+#elif defined(TARGET_MCU_NRF51_16K_S120) || defined(TARGET_MCU_NRF51_32K_S120)
+                bool is_central = true;
+#else
+                bool is_central =
+                        (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL);
+#endif
+
+                sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
+                                              &m_bcs.flags.central_flags,
+                                               p_ble_evt->evt.gap_evt.conn_handle,
+                                               is_central);
+            }
+
+            break;
+
+        case BLE_GAP_EVT_DISCONNECTED:
+            record_set_disconnected(p_ble_evt->evt.gap_evt.conn_handle);
+            break;
+
+        case BLE_GAP_EVT_CONN_SEC_UPDATE:
+            sdk_mapped_flags_update_by_key(
+                          m_bcs.valid_conn_handles,
+                         &m_bcs.flags.encrypted_flags,
+                          p_ble_evt->evt.gap_evt.conn_handle,
+                         (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 1));
+            sdk_mapped_flags_update_by_key(
+                          m_bcs.valid_conn_handles,
+                         &m_bcs.flags.mitm_protected_flags,
+                          p_ble_evt->evt.gap_evt.conn_handle,
+                         (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 2));
+            break;
+    }
+}
+
+
+bool ble_conn_state_valid(uint16_t conn_handle)
+{
+    return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                       m_bcs.flags.valid_flags,
+                                       conn_handle);
+}
+
+
+uint8_t ble_conn_state_role(uint16_t conn_handle)
+{
+    uint8_t role = BLE_GAP_ROLE_INVALID;
+
+    if ( sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags, conn_handle) )
+    {
+        bool central = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                                   m_bcs.flags.central_flags,
+                                                   conn_handle);
+
+        role = central ? BLE_GAP_ROLE_CENTRAL : BLE_GAP_ROLE_PERIPH;
+    }
+
+    return role;
+}
+
+
+ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle)
+{
+    ble_conn_state_status_t conn_status = BLE_CONN_STATUS_INVALID;
+    bool valid = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                             m_bcs.flags.valid_flags,
+                                             conn_handle);
+
+    if (valid)
+    {
+        bool connected = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                                     m_bcs.flags.connected_flags,
+                                                     conn_handle);
+
+        conn_status = connected ? BLE_CONN_STATUS_CONNECTED : BLE_CONN_STATUS_DISCONNECTED;
+    }
+
+    return conn_status;
+}
+
+
+bool ble_conn_state_encrypted(uint16_t conn_handle)
+{
+    return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                       m_bcs.flags.encrypted_flags,
+                                       conn_handle);
+}
+
+
+bool ble_conn_state_mitm_protected(uint16_t conn_handle)
+{
+    return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                       m_bcs.flags.mitm_protected_flags,
+                                       conn_handle);
+}
+
+
+uint32_t ble_conn_state_n_connections(void)
+{
+    return sdk_mapped_flags_n_flags_set(m_bcs.flags.connected_flags);
+}
+
+
+uint32_t ble_conn_state_n_centrals(void)
+{
+    return sdk_mapped_flags_n_flags_set((m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
+}
+
+
+uint32_t ble_conn_state_n_peripherals(void)
+{
+    return sdk_mapped_flags_n_flags_set((~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
+}
+
+
+sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void)
+{
+    return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags);
+}
+
+
+sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void)
+{
+    return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles,
+                                        (m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
+}
+
+
+sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void)
+{
+    return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles,
+                                        (~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
+}
+
+
+ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void)
+{
+    for (ble_conn_state_user_flag_id_t i = BLE_CONN_STATE_USER_FLAG0;
+                                       i < BLE_CONN_STATE_N_USER_FLAGS;
+                                       i++)
+    {
+        if ( !user_flag_is_acquired(i) )
+        {
+            user_flag_acquire(i);
+            return i;
+        }
+    }
+
+    return BLE_CONN_STATE_USER_FLAG_INVALID;
+}
+
+
+bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id)
+{
+    if (user_flag_is_acquired(flag_id))
+    {
+        return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
+                                           m_bcs.flags.user_flags[flag_id],
+                                           conn_handle);
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+void ble_conn_state_user_flag_set(uint16_t                      conn_handle,
+                                  ble_conn_state_user_flag_id_t flag_id,
+                                  bool                          value)
+{
+    if (user_flag_is_acquired(flag_id))
+    {
+        sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
+                                      &m_bcs.flags.user_flags[flag_id],
+                                       conn_handle,
+                                       value);
+    }
+}
+
+
+sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id)
+{
+    if ( user_flag_is_acquired(flag_id) )
+    {
+        return m_bcs.flags.user_flags[flag_id];
+    }
+    else
+    {
+        return 0;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_conn_state.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_conn_state Connection state
+ * @ingroup ble_sdk_lib
+ * @{
+ * @brief Module for storing data on BLE connections.
+ *
+ * @details This module stores certain states for each connection, which can be queried by
+ *          connection handle. The module uses BLE events to keep the states updated.
+ *
+ *          In addition to the preprogrammed states, this module can also keep track of a number of
+ *          binary user states, or <i>user flags</i>. These are reset to 0 for new connections, but
+ *          otherwise not touched by this module.
+ *
+ *          This module uses the @ref sdk_mapped_flags module, with connection handles as keys and
+ *          the connection states as flags.
+ *
+ * @note A connection handle is not immediately invalidated when it is disconnected. Certain states,
+ *       such as the role, can still be queried until the next time a new connection is established
+ *       to any device.
+ *
+ *          To function properly, this module must be provided with BLE events from the SoftDevice
+ *          through the @ref ble_conn_state_on_ble_evt() function. This module should be the first
+ *          to receive BLE events if they are dispatched to multiple modules.
+ */
+
+#ifndef BLE_CONN_STATE_H__
+#define BLE_CONN_STATE_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "ble.h"
+#include "sdk_mapped_flags.h"
+
+/**@brief Connection handle statuses.
+ */
+typedef enum
+{
+    BLE_CONN_STATUS_INVALID,       /**< The connection handle is invalid. */
+    BLE_CONN_STATUS_DISCONNECTED,  /**< The connection handle refers to a connection that has been disconnected, but not yet invalidated. */
+    BLE_CONN_STATUS_CONNECTED,     /**< The connection handle refers to an active connection. */
+} ble_conn_state_status_t;
+
+#define BLE_CONN_STATE_N_USER_FLAGS 16  /**< The number of available user flags. */
+
+
+/**@brief One ID for each user flag collection.
+ *
+ * @details These IDs are used to identify user flag collections in the API calls.
+ */
+typedef enum
+{
+    BLE_CONN_STATE_USER_FLAG0 = 0,
+    BLE_CONN_STATE_USER_FLAG1,
+    BLE_CONN_STATE_USER_FLAG2,
+    BLE_CONN_STATE_USER_FLAG3,
+    BLE_CONN_STATE_USER_FLAG4,
+    BLE_CONN_STATE_USER_FLAG5,
+    BLE_CONN_STATE_USER_FLAG6,
+    BLE_CONN_STATE_USER_FLAG7,
+    BLE_CONN_STATE_USER_FLAG8,
+    BLE_CONN_STATE_USER_FLAG9,
+    BLE_CONN_STATE_USER_FLAG10,
+    BLE_CONN_STATE_USER_FLAG11,
+    BLE_CONN_STATE_USER_FLAG12,
+    BLE_CONN_STATE_USER_FLAG13,
+    BLE_CONN_STATE_USER_FLAG14,
+    BLE_CONN_STATE_USER_FLAG15,
+    BLE_CONN_STATE_USER_FLAG_INVALID,
+} ble_conn_state_user_flag_id_t;
+
+
+/**
+ * @defgroup ble_conn_state_functions BLE connection state functions
+ * @{
+ */
+
+
+/**@brief Function for initializing or resetting the module.
+ *
+ * @details This function sets all states to their default, removing all records of connection handles.
+ */
+void ble_conn_state_init(void);
+
+
+/**@brief Function for providing BLE SoftDevice events to the connection state module.
+ *
+ * @param[in]  p_ble_evt    The SoftDevice event.
+ */
+void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt);
+
+
+/**@brief Function for querying whether a connection handle represents a valid connection.
+ *
+ * @details A connection might be valid and have a BLE_CONN_STATUS_DISCONNECTED status.
+ *          Those connections are invalidated after a new connection occurs.
+ *
+ * @param[in]  conn_handle  Handle of the connection.
+ *
+ * @retval true   If conn_handle represents a valid connection, thus a connection for which
+                  we have a record.
+ * @retval false  If conn_handle is @ref BLE_GAP_ROLE_INVALID, or if it has never been recorded.
+ */
+bool ble_conn_state_valid(uint16_t conn_handle);
+
+
+/**@brief Function for querying the role of the local device in a connection.
+ *
+ * @param[in]  conn_handle  Handle of the connection to get the role for.
+ *
+ * @return  The role of the local device in the connection (see @ref BLE_GAP_ROLES).
+ *          If conn_handle is not valid, the function returns BLE_GAP_ROLE_INVALID.
+ */
+uint8_t ble_conn_state_role(uint16_t conn_handle);
+
+
+/**@brief Function for querying the status of a connection.
+ *
+ * @param[in]  conn_handle  Handle of the connection.
+ *
+ * @return  The status of the connection.
+ *          If conn_handle is not valid, the function returns BLE_CONN_STATE_INVALID.
+ */
+ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle);
+
+
+/**@brief Function for querying whether a connection is encrypted.
+ *
+ * @param[in]  conn_handle  Handle of connection to get the encryption state for.
+ *
+ * @retval true   If the connection is encrypted.
+ * @retval false  If the connection is not encrypted or conn_handle is invalid.
+ */
+bool ble_conn_state_encrypted(uint16_t conn_handle);
+
+
+/**@brief Function for querying whether a connection encryption is protected from Man in the Middle
+ *        attacks.
+ *
+ * @param[in]  conn_handle  Handle of connection to get the MITM state for.
+ *
+ * @retval true   If the connection is encrypted with MITM protection.
+ * @retval false  If the connection is not encrypted, or encryption is not MITM protected, or
+ *                conn_handle is invalid.
+ */
+bool ble_conn_state_mitm_protected(uint16_t conn_handle);
+
+
+/**@brief Function for querying the total number of connections.
+ *
+ * @return  The total number of valid connections for which the module has a record.
+ */
+uint32_t ble_conn_state_n_connections(void);
+
+
+/**@brief Function for querying the total number of connections in which the role of the local
+ *        device is @ref BLE_GAP_ROLE_CENTRAL.
+ *
+ * @return  The number of connections in which the role of the local device is
+ *          @ref BLE_GAP_ROLE_CENTRAL.
+ */
+uint32_t ble_conn_state_n_centrals(void);
+
+
+/**@brief Function for querying the total number of connections in which the role of the local
+ *        device is @ref BLE_GAP_ROLE_PERIPH.
+ *
+ * @return  The number of connections in which the role of the local device is
+ *          @ref BLE_GAP_ROLE_PERIPH.
+ */
+uint32_t ble_conn_state_n_peripherals(void);
+
+
+/**@brief Function for obtaining a list of all connection handles for which the module has a record.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return  A list of all valid connection handles for which the module has a record.
+ */
+sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void);
+
+
+/**@brief Function for obtaining a list of connection handles in which the role of the local
+ *        device is @ref BLE_GAP_ROLE_CENTRAL.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return  A list of all valid connection handles for which the module has a record and in which
+ *          the role of local device is @ref BLE_GAP_ROLE_CENTRAL.
+ */
+sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void);
+
+
+/**@brief Function for obtaining the handle for the connection in which the role of the local device
+ *        is @ref BLE_GAP_ROLE_PERIPH.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return  A list of all valid connection handles for which the module has a record and in which
+ *          the role of local device is @ref BLE_GAP_ROLE_PERIPH.
+ */
+sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void);
+
+
+/**@brief Function for obtaining exclusive access to one of the user flag collections.
+ *
+ * @details The acquired collection contains one flag for each connection. These flags can be set
+ *          and read individually for each connection.
+ *
+ *          The state of user flags will not be modified by the connection state module, except to
+ *          set it to 0 for a connection when that connection is invalidated.
+ *
+ * @return  The ID of the acquired flag, or BLE_CONN_STATE_USER_FLAG_INVALID if none are available.
+ */
+ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void);
+
+
+/**@brief Function for reading the value of a user flag.
+ *
+ * @param[in]  conn_handle  Handle of connection to get the flag state for.
+ * @param[in]  flag_id      Which flag to get the state for.
+ *
+ * @return  The state of the flag. If conn_handle is invalid, the function returns false.
+ */
+bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id);
+
+
+/**@brief Function for setting the value of a user flag.
+ *
+ * @param[in]  conn_handle  Handle of connection to set the flag state for.
+ * @param[in]  flag_id      Which flag to set the state for.
+ * @param[in]  value        Value to set the flag state to.
+ */
+void ble_conn_state_user_flag_set(uint16_t                      conn_handle,
+                                  ble_conn_state_user_flag_id_t flag_id,
+                                  bool                          value);
+
+
+/**@brief Function for getting the state of a user flag for all connection handles.
+ *
+ * @details The returned collection can be used with the @ref sdk_mapped_flags API. The returned
+ *          collection is a copy, so modifying it has no effect on the conn_state module.
+ *
+ * @param[in]  flag_id  Which flag to get states for.
+ *
+ * @return  The collection of flag states. The collection is always all zeros when the flag_id is
+ *          unregistered.
+ */
+sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id);
+
+/** @} */
+/** @} */
+
+#endif /* BLE_CONN_STATE_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_date_time.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Attention! 
+*  To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile 
+*  qualification listings, this section of source code must not be modified.
+*/
+
+/** @file
+ * @brief Contains definition of ble_date_time structure.
+ */
+
+/** @file
+ *
+ * @defgroup ble_sdk_srv_date_time BLE Date Time characteristic type
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Definition of ble_date_time_t type.
+ */
+
+#ifndef BLE_DATE_TIME_H__
+#define BLE_DATE_TIME_H__
+
+#include <stdint.h>
+
+/**@brief Date and Time structure. */
+typedef struct
+{
+    uint16_t year;
+    uint8_t  month;
+    uint8_t  day;
+    uint8_t  hours;
+    uint8_t  minutes;
+    uint8_t  seconds;
+} ble_date_time_t;
+
+static __INLINE uint8_t ble_date_time_encode(const ble_date_time_t * p_date_time,
+                                             uint8_t *               p_encoded_data)
+{
+    uint8_t len = uint16_encode(p_date_time->year, p_encoded_data);
+    
+    p_encoded_data[len++] = p_date_time->month;
+    p_encoded_data[len++] = p_date_time->day;
+    p_encoded_data[len++] = p_date_time->hours;
+    p_encoded_data[len++] = p_date_time->minutes;
+    p_encoded_data[len++] = p_date_time->seconds;
+    
+    return len;
+}
+
+static __INLINE uint8_t ble_date_time_decode(ble_date_time_t * p_date_time,
+                                             const uint8_t *   p_encoded_data)
+{
+    uint8_t len = sizeof(uint16_t);
+    
+    p_date_time->year    = uint16_decode(p_encoded_data);
+    p_date_time->month   = p_encoded_data[len++];
+    p_date_time->day     = p_encoded_data[len++]; 
+    p_date_time->hours   = p_encoded_data[len++];
+    p_date_time->minutes = p_encoded_data[len++];
+    p_date_time->seconds = p_encoded_data[len++];
+    
+    return len;
+}
+
+#endif // BLE_DATE_TIME_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_gatt_db.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef BLE_GATT_DB_H__
+#define BLE_GATT_DB_H__
+
+#include "stdint.h"
+#include "ble.h"
+#include "ble_gattc.h"
+
+#define BLE_GATT_DB_MAX_CHARS                                 4          /**< The maximum number of characteristics present in a service record. */
+
+/**@brief Structure for holding the characteristic and the handle of its CCCD present on a server.
+ */
+typedef struct
+{
+    ble_gattc_char_t characteristic;  /**< Structure containing information about the characteristic. */
+    uint16_t         cccd_handle;     /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */
+} ble_gatt_db_char_t;
+
+/**@brief Structure for holding information about the service and the characteristics present on a
+ *        server.
+ */
+typedef struct
+{
+    ble_uuid_t               srv_uuid;                                  /**< UUID of the service. */    
+    uint8_t                  char_count;                                /**< Number of characteristics present in the service. */
+    ble_gattc_handle_range_t handle_range;                              /**< Service Handle Range. */
+    ble_gatt_db_char_t       charateristics[BLE_GATT_DB_MAX_CHARS];     /**< Array of information related to the characteristics present in the service. This list can extend further than one. */
+} ble_gatt_db_srv_t;
+
+#endif /* BLE_GATT_DB_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_sensor_location.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /* Attention!
+*  To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile
+*  qualification listings, this section of source code must not be modified.
+*/
+ 
+#ifndef BLE_SENSOR_LOCATION_H__
+#define BLE_SENSOR_LOCATION_H__
+
+typedef enum {
+    BLE_SENSOR_LOCATION_OTHER        = 0 ,  /**<-- Other        */
+    BLE_SENSOR_LOCATION_TOP_OF_SHOE  = 1 ,  /**<-- Top of shoe  */
+    BLE_SENSOR_LOCATION_IN_SHOE      = 2 ,  /**<-- In shoe      */
+    BLE_SENSOR_LOCATION_HIP          = 3 ,  /**<-- Hip          */
+    BLE_SENSOR_LOCATION_FRONT_WHEEL  = 4 ,  /**<-- Front Wheel  */
+    BLE_SENSOR_LOCATION_LEFT_CRANK   = 5 ,  /**<-- Left Crank   */
+    BLE_SENSOR_LOCATION_RIGHT_CRANK  = 6 ,  /**<-- Right Crank  */
+    BLE_SENSOR_LOCATION_LEFT_PEDAL   = 7 ,  /**<-- Left Pedal   */
+    BLE_SENSOR_LOCATION_RIGHT_PEDAL  = 8 ,  /**<-- Right Pedal  */
+    BLE_SENSOR_LOCATION_FRONT_HUB    = 9 ,  /**<-- Front Hub    */
+    BLE_SENSOR_LOCATION_REAR_DROPOUT = 10,  /**<-- Rear Dropout */
+    BLE_SENSOR_LOCATION_CHAINSTAY    = 11,  /**<-- Chainstay    */
+    BLE_SENSOR_LOCATION_REAR_WHEEL   = 12,  /**<-- Rear Wheel   */
+    BLE_SENSOR_LOCATION_REAR_HUB     = 13,  /**<-- Rear Hub     */
+}ble_sensor_location_t;
+
+#define BLE_NB_MAX_SENSOR_LOCATIONS 14
+
+#endif // BLE_SENSOR_LOCATION_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_srv_common.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Attention!
+*  To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile
+*  qualification listings, this section of source code must not be modified.
+*/
+
+#include "ble_srv_common.h"
+#include <string.h>
+#include "nordic_common.h"
+#include "app_error.h"
+#include "ble.h"
+
+uint8_t ble_srv_report_ref_encode(uint8_t                    * p_encoded_buffer,
+                                  const ble_srv_report_ref_t * p_report_ref)
+{
+    uint8_t len = 0;
+
+    p_encoded_buffer[len++] = p_report_ref->report_id;
+    p_encoded_buffer[len++] = p_report_ref->report_type;
+
+    APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN);
+    return len;
+}
+
+
+void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii)
+{
+    p_utf8->length = (uint16_t)strlen(p_ascii);
+    p_utf8->p_str  = (uint8_t *)p_ascii;
+}
+
+
+/**@brief Function for setting security requirements of a characteristic.
+ *
+ * @param[in]  level   required security level.
+ * @param[out] p_perm  Characteristic security requirements.
+ *
+ * @return     encoded security level and security mode.
+ */
+static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm)
+{
+
+
+    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
+    switch (level)
+    {
+        case SEC_NO_ACCESS:
+            BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
+        break;
+        case SEC_OPEN:
+            BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm);
+        break;
+        case SEC_JUST_WORKS:
+            BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm);
+        break;
+        case SEC_MITM:
+            BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm);
+        break;
+        case SEC_SIGNED:
+            BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm);
+        break;
+        case SEC_SIGNED_MITM:
+            BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm);
+        break;
+    }
+    return;
+}
+
+
+uint32_t characteristic_add(uint16_t                   service_handle,
+                            ble_add_char_params_t *    p_char_props,
+                            ble_gatts_char_handles_t * p_char_handle)
+{
+    ble_gatts_char_md_t char_md;
+    ble_gatts_attr_t    attr_char_value;
+    ble_uuid_t          char_uuid;
+    ble_gatts_attr_md_t attr_md;
+    ble_gatts_attr_md_t user_descr_attr_md;
+    ble_gatts_attr_md_t cccd_md;
+
+    if (p_char_props->uuid_type == 0)
+    {
+        char_uuid.type = BLE_UUID_TYPE_BLE;
+    }
+    else
+    {
+        char_uuid.type = p_char_props->uuid_type;
+    }
+    char_uuid.uuid = p_char_props->uuid;
+
+    memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
+    set_security_req(p_char_props->read_access, &attr_md.read_perm);
+    set_security_req(p_char_props->write_access, & attr_md.write_perm);
+    attr_md.rd_auth    = (p_char_props->is_defered_read ? 1 : 0);
+    attr_md.wr_auth    = (p_char_props->is_defered_write ? 1 : 0);
+    attr_md.vlen       = (p_char_props->is_var_len ? 1 : 0);
+    attr_md.vloc       = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+
+
+    memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
+    if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
+    {
+
+        memset(&cccd_md, 0, sizeof(cccd_md));
+        set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
+        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+
+        cccd_md.vloc       = BLE_GATTS_VLOC_STACK;
+
+        char_md.p_cccd_md  = &cccd_md;
+    }
+    char_md.char_props = p_char_props->char_props;
+
+    memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
+    attr_char_value.p_uuid    = &char_uuid;
+    attr_char_value.p_attr_md = &attr_md;
+    attr_char_value.max_len   = p_char_props->max_len;
+    if (p_char_props->p_init_value != NULL)
+    {
+        attr_char_value.init_len  = p_char_props->init_len;
+        attr_char_value.p_value   = p_char_props->p_init_value;
+    }
+    if (p_char_props->p_user_descr != NULL)
+    {
+        memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
+        char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
+        char_md.char_user_desc_size     = p_char_props->p_user_descr->size;
+        char_md.p_char_user_desc        = p_char_props->p_user_descr->p_char_user_desc;
+
+        char_md.p_user_desc_md          = &user_descr_attr_md;
+
+        set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
+        set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);
+
+        user_descr_attr_md.rd_auth      = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
+        user_descr_attr_md.wr_auth      = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
+        user_descr_attr_md.vlen         = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
+        user_descr_attr_md.vloc         = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+    }
+    if (p_char_props->p_presentation_format != NULL)
+    {
+        char_md.p_char_pf = p_char_props->p_presentation_format;
+    }
+    return sd_ble_gatts_characteristic_add(service_handle,
+                                           &char_md,
+                                           &attr_char_value,
+                                           p_char_handle);
+}
+
+
+uint32_t descriptor_add(uint16_t                   char_handle,
+                        ble_add_descr_params_t *   p_descr_props,
+                        uint16_t *                 p_descr_handle)
+{
+    ble_gatts_attr_t    descr_params;
+    ble_uuid_t          desc_uuid;
+    ble_gatts_attr_md_t attr_md;
+
+    memset(&descr_params, 0, sizeof(descr_params));
+    if (p_descr_props->uuid_type == 0)
+    {
+        desc_uuid.type = BLE_UUID_TYPE_BLE;
+    }
+    else
+    {
+        desc_uuid.type = p_descr_props->uuid_type;
+    }
+    desc_uuid.uuid = p_descr_props->uuid;
+    descr_params.p_uuid = &desc_uuid;
+
+    set_security_req(p_descr_props->read_access, &attr_md.read_perm);
+    set_security_req(p_descr_props->write_access,&attr_md.write_perm);
+
+    attr_md.rd_auth        = (p_descr_props->is_defered_read ? 1 : 0);
+    attr_md.wr_auth        = (p_descr_props->is_defered_write ? 1 : 0);
+    attr_md.vlen           = (p_descr_props->is_var_len ? 1 : 0);
+    attr_md.vloc           = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+    descr_params.p_attr_md = &attr_md;
+
+    descr_params.init_len  = p_descr_props->init_len;
+    descr_params.init_offs = p_descr_props->init_offs;
+    descr_params.max_len   = p_descr_props->max_len;
+    descr_params.p_value   = p_descr_props->p_value;
+
+    return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/common/ble_srv_common.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_sdk_srv_common Common service definitions
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Constants, type definitions, and functions that are common to all services.
+ */
+
+#ifndef BLE_SRV_COMMON_H__
+#define BLE_SRV_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble_types.h"
+#include "app_util.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_gatt.h"
+
+/** @defgroup UUID_SERVICES Service UUID definitions
+ * @{ */
+#define BLE_UUID_ALERT_NOTIFICATION_SERVICE                      0x1811     /**< Alert Notification service UUID. */
+#define BLE_UUID_BATTERY_SERVICE                                 0x180F     /**< Battery service UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_SERVICE                          0x1810     /**< Blood Pressure service UUID. */
+#define BLE_UUID_CURRENT_TIME_SERVICE                            0x1805     /**< Current Time service UUID. */
+#define BLE_UUID_CYCLING_SPEED_AND_CADENCE                       0x1816     /**< Cycling Speed and Cadence service UUID. */
+#define BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE                 0x1819     /**< Location and Navigation service UUID. */
+#define BLE_UUID_DEVICE_INFORMATION_SERVICE                      0x180A     /**< Device Information service UUID. */
+#define BLE_UUID_GLUCOSE_SERVICE                                 0x1808     /**< Glucose service UUID. */
+#define BLE_UUID_HEALTH_THERMOMETER_SERVICE                      0x1809     /**< Health Thermometer service UUID. */
+#define BLE_UUID_HEART_RATE_SERVICE                              0x180D     /**< Heart Rate service UUID. */
+#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE                  0x1812     /**< Human Interface Device service UUID. */
+#define BLE_UUID_IMMEDIATE_ALERT_SERVICE                         0x1802     /**< Immediate Alert service UUID. */
+#define BLE_UUID_LINK_LOSS_SERVICE                               0x1803     /**< Link Loss service UUID. */
+#define BLE_UUID_NEXT_DST_CHANGE_SERVICE                         0x1807     /**< Next Dst Change service UUID. */
+#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE                      0x180E     /**< Phone Alert Status service UUID. */
+#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE                   0x1806     /**< Reference Time Update service UUID. */
+#define BLE_UUID_RUNNING_SPEED_AND_CADENCE                       0x1814     /**< Running Speed and Cadence service UUID. */
+#define BLE_UUID_SCAN_PARAMETERS_SERVICE                         0x1813     /**< Scan Parameters service UUID. */
+#define BLE_UUID_TX_POWER_SERVICE                                0x1804     /**< TX Power service UUID. */
+#define BLE_UUID_IPSP_SERVICE                                    0x1820     /**< Internet Protocol Support service UUID. */
+/** @} */
+
+/** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions
+ * @{ */
+#define BLE_UUID_BATTERY_LEVEL_STATE_CHAR                        0x2A1B     /**< Battery Level State characteristic UUID. */
+#define BLE_UUID_BATTERY_POWER_STATE_CHAR                        0x2A1A     /**< Battery Power State characteristic UUID. */
+#define BLE_UUID_REMOVABLE_CHAR                                  0x2A3A     /**< Removable characteristic UUID. */
+#define BLE_UUID_SERVICE_REQUIRED_CHAR                           0x2A3B     /**< Service Required characteristic UUID. */
+#define BLE_UUID_ALERT_CATEGORY_ID_CHAR                          0x2A43     /**< Alert Category Id characteristic UUID. */
+#define BLE_UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR                 0x2A42     /**< Alert Category Id Bit Mask characteristic UUID. */
+#define BLE_UUID_ALERT_LEVEL_CHAR                                0x2A06     /**< Alert Level characteristic UUID. */
+#define BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR           0x2A44     /**< Alert Notification Control Point characteristic UUID. */
+#define BLE_UUID_ALERT_STATUS_CHAR                               0x2A3F     /**< Alert Status characteristic UUID. */
+#define BLE_UUID_BATTERY_LEVEL_CHAR                              0x2A19     /**< Battery Level characteristic UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR                     0x2A49     /**< Blood Pressure Feature characteristic UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR                 0x2A35     /**< Blood Pressure Measurement characteristic UUID. */
+#define BLE_UUID_BODY_SENSOR_LOCATION_CHAR                       0x2A38     /**< Body Sensor Location characteristic UUID. */
+#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR                 0x2A22     /**< Boot Keyboard Input Report characteristic UUID. */
+#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR                0x2A32     /**< Boot Keyboard Output Report characteristic UUID. */
+#define BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR                    0x2A33     /**< Boot Mouse Input Report characteristic UUID. */
+#define BLE_UUID_CURRENT_TIME_CHAR                               0x2A2B     /**< Current Time characteristic UUID. */
+#define BLE_UUID_DATE_TIME_CHAR                                  0x2A08     /**< Date Time characteristic UUID. */
+#define BLE_UUID_DAY_DATE_TIME_CHAR                              0x2A0A     /**< Day Date Time characteristic UUID. */
+#define BLE_UUID_DAY_OF_WEEK_CHAR                                0x2A09     /**< Day Of Week characteristic UUID. */
+#define BLE_UUID_DST_OFFSET_CHAR                                 0x2A0D     /**< Dst Offset characteristic UUID. */
+#define BLE_UUID_EXACT_TIME_256_CHAR                             0x2A0C     /**< Exact Time 256 characteristic UUID. */
+#define BLE_UUID_FIRMWARE_REVISION_STRING_CHAR                   0x2A26     /**< Firmware Revision String characteristic UUID. */
+#define BLE_UUID_GLUCOSE_FEATURE_CHAR                            0x2A51     /**< Glucose Feature characteristic UUID. */
+#define BLE_UUID_GLUCOSE_MEASUREMENT_CHAR                        0x2A18     /**< Glucose Measurement characteristic UUID. */
+#define BLE_UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR                0x2A34     /**< Glucose Measurement Context characteristic UUID. */
+#define BLE_UUID_HARDWARE_REVISION_STRING_CHAR                   0x2A27     /**< Hardware Revision String characteristic UUID. */
+#define BLE_UUID_HEART_RATE_CONTROL_POINT_CHAR                   0x2A39     /**< Heart Rate Control Point characteristic UUID. */
+#define BLE_UUID_HEART_RATE_MEASUREMENT_CHAR                     0x2A37     /**< Heart Rate Measurement characteristic UUID. */
+#define BLE_UUID_HID_CONTROL_POINT_CHAR                          0x2A4C     /**< Hid Control Point characteristic UUID. */
+#define BLE_UUID_HID_INFORMATION_CHAR                            0x2A4A     /**< Hid Information characteristic UUID. */
+#define BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR    0x2A2A     /**< IEEE Regulatory Certification Data List characteristic UUID. */
+#define BLE_UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR                 0x2A36     /**< Intermediate Cuff Pressure characteristic UUID. */
+#define BLE_UUID_INTERMEDIATE_TEMPERATURE_CHAR                   0x2A1E     /**< Intermediate Temperature characteristic UUID. */
+#define BLE_UUID_LOCAL_TIME_INFORMATION_CHAR                     0x2A0F     /**< Local Time Information characteristic UUID. */
+#define BLE_UUID_MANUFACTURER_NAME_STRING_CHAR                   0x2A29     /**< Manufacturer Name String characteristic UUID. */
+#define BLE_UUID_MEASUREMENT_INTERVAL_CHAR                       0x2A21     /**< Measurement Interval characteristic UUID. */
+#define BLE_UUID_MODEL_NUMBER_STRING_CHAR                        0x2A24     /**< Model Number String characteristic UUID. */
+#define BLE_UUID_UNREAD_ALERT_CHAR                               0x2A45     /**< Unread Alert characteristic UUID. */
+#define BLE_UUID_NEW_ALERT_CHAR                                  0x2A46     /**< New Alert characteristic UUID. */
+#define BLE_UUID_PNP_ID_CHAR                                     0x2A50     /**< PNP Id characteristic UUID. */
+#define BLE_UUID_PROTOCOL_MODE_CHAR                              0x2A4E     /**< Protocol Mode characteristic UUID. */
+#define BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR                0x2A52     /**< Record Access Control Point characteristic UUID. */
+#define BLE_UUID_REFERENCE_TIME_INFORMATION_CHAR                 0x2A14     /**< Reference Time Information characteristic UUID. */
+#define BLE_UUID_REPORT_CHAR                                     0x2A4D     /**< Report characteristic UUID. */
+#define BLE_UUID_REPORT_MAP_CHAR                                 0x2A4B     /**< Report Map characteristic UUID. */
+#define BLE_UUID_RINGER_CONTROL_POINT_CHAR                       0x2A40     /**< Ringer Control Point characteristic UUID. */
+#define BLE_UUID_RINGER_SETTING_CHAR                             0x2A41     /**< Ringer Setting characteristic UUID. */
+#define BLE_UUID_SCAN_INTERVAL_WINDOW_CHAR                       0x2A4F     /**< Scan Interval Window characteristic UUID. */
+#define BLE_UUID_SCAN_REFRESH_CHAR                               0x2A31     /**< Scan Refresh characteristic UUID. */
+#define BLE_UUID_SERIAL_NUMBER_STRING_CHAR                       0x2A25     /**< Serial Number String characteristic UUID. */
+#define BLE_UUID_SOFTWARE_REVISION_STRING_CHAR                   0x2A28     /**< Software Revision String characteristic UUID. */
+#define BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR               0x2A47     /**< Supported New Alert Category characteristic UUID. */
+#define BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR            0x2A48     /**< Supported Unread Alert Category characteristic UUID. */
+#define BLE_UUID_SYSTEM_ID_CHAR                                  0x2A23     /**< System Id characteristic UUID. */
+#define BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR                    0x2A1C     /**< Temperature Measurement characteristic UUID. */
+#define BLE_UUID_TEMPERATURE_TYPE_CHAR                           0x2A1D     /**< Temperature Type characteristic UUID. */
+#define BLE_UUID_TIME_ACCURACY_CHAR                              0x2A12     /**< Time Accuracy characteristic UUID. */
+#define BLE_UUID_TIME_SOURCE_CHAR                                0x2A13     /**< Time Source characteristic UUID. */
+#define BLE_UUID_TIME_UPDATE_CONTROL_POINT_CHAR                  0x2A16     /**< Time Update Control Point characteristic UUID. */
+#define BLE_UUID_TIME_UPDATE_STATE_CHAR                          0x2A17     /**< Time Update State characteristic UUID. */
+#define BLE_UUID_TIME_WITH_DST_CHAR                              0x2A11     /**< Time With Dst characteristic UUID. */
+#define BLE_UUID_TIME_ZONE_CHAR                                  0x2A0E     /**< Time Zone characteristic UUID. */
+#define BLE_UUID_TX_POWER_LEVEL_CHAR                             0x2A07     /**< TX Power Level characteristic UUID. */
+#define BLE_UUID_CSC_FEATURE_CHAR                                0x2A5C     /**< Cycling Speed and Cadence Feature characteristic UUID. */
+#define BLE_UUID_CSC_MEASUREMENT_CHAR                            0x2A5B     /**< Cycling Speed and Cadence Measurement characteristic UUID. */
+#define BLE_UUID_RSC_FEATURE_CHAR                                0x2A54     /**< Running Speed and Cadence Feature characteristic UUID. */
+#define BLE_UUID_SC_CTRLPT_CHAR                                  0x2A55     /**< Speed and Cadence Control Point UUID. */
+#define BLE_UUID_RSC_MEASUREMENT_CHAR                            0x2A53     /**< Running Speed and Cadence Measurement characteristic UUID. */
+#define BLE_UUID_SENSOR_LOCATION_CHAR                            0x2A5D     /**< Sensor Location characteristic UUID. */
+#define BLE_UUID_EXTERNAL_REPORT_REF_DESCR                       0x2907     /**< External Report Reference descriptor UUID. */
+#define BLE_UUID_REPORT_REF_DESCR                                0x2908     /**< Report Reference descriptor UUID. */
+#define BLE_UUID_LN_FEATURE_CHAR                                 0x2A6A     /**< Location Navigation Service, Feature characteristic UUID. */
+#define BLE_UUID_LN_POSITION_QUALITY_CHAR                        0x2A69     /**< Location Navigation Service, Position quality UUID. */
+#define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR                      0x2A67     /**< Location Navigation Service, Location and Speed characteristic UUID. */
+#define BLE_UUID_LN_NAVIGATION_CHAR                              0x2A68     /**< Location Navigation Service, Navigation characteristic UUID. */
+#define BLE_UUID_LN_CONTROL_POINT_CHAR                           0x2A6B     /**< Location Navigation Service, Control point characteristic UUID. */
+/** @} */
+
+/** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values
+ * @{ */
+#define BLE_CHAR_ALERT_LEVEL_NO_ALERT                            0x00       /**< No Alert. */
+#define BLE_CHAR_ALERT_LEVEL_MILD_ALERT                          0x01       /**< Mild Alert. */
+#define BLE_CHAR_ALERT_LEVEL_HIGH_ALERT                          0x02       /**< High Alert. */
+/** @} */
+
+#define BLE_SRV_ENCODED_REPORT_REF_LEN                           2          /**< The length of an encoded Report Reference Descriptor. */
+#define BLE_CCCD_VALUE_LEN                                       2          /**< The length of a CCCD value. */
+
+/**@brief Type definition for error handler function that will be called in case of an error in
+ *        a service or a service library module. */
+typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error);
+
+
+
+/**@brief Value of a Report Reference descriptor. 
+ *
+ * @details This is mapping information that maps the parent characteristic to the Report ID(s) and
+ *          Report Type(s) defined within a Report Map characteristic.
+ */
+typedef struct
+{
+    uint8_t report_id;                                  /**< Non-zero value if there is more than one instance of the same Report Type */
+    uint8_t report_type;                                /**< Type of Report characteristic (see @ref BLE_HIDS_REPORT_TYPE) */
+} ble_srv_report_ref_t;
+
+/**@brief UTF-8 string data type.
+ *
+ * @note The type can only hold a pointer to the string data (i.e. not the actual data).
+ */
+typedef struct
+{
+    uint16_t  length;                                   /**< String length. */
+    uint8_t * p_str;                                    /**< String data. */
+} ble_srv_utf8_str_t;
+
+
+/**@brief Security settings structure.
+ * @details This structure contains the security options needed during initialization of the
+ *          service.
+ */
+typedef struct
+{
+    ble_gap_conn_sec_mode_t read_perm;                  /**< Read permissions. */
+    ble_gap_conn_sec_mode_t write_perm;                 /**< Write permissions. */
+} ble_srv_security_mode_t;
+
+/**@brief Security settings structure.
+ * @details This structure contains the security options needed during initialization of the
+ *          service. It can be used when the characteristics contains a CCCD.
+ */
+typedef struct
+{
+    ble_gap_conn_sec_mode_t cccd_write_perm;            /**< Write permissions for Client Characteristic Configuration Descriptor. */
+    ble_gap_conn_sec_mode_t read_perm;                  /**< Read permissions. */
+    ble_gap_conn_sec_mode_t write_perm;                 /**< Write permissions. */
+} ble_srv_cccd_security_mode_t;
+
+/**@brief Function for decoding a CCCD value, and then testing if notification is
+ *        enabled.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded CCCD is stored.
+ *
+ * @retval      TRUE If notification is enabled.
+ * @retval      FALSE Otherwise.
+ */
+static __INLINE bool ble_srv_is_notification_enabled(uint8_t * p_encoded_data)
+{
+    uint16_t cccd_value = uint16_decode(p_encoded_data);
+    return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0);
+}
+    
+/**@brief Function for decoding a CCCD value, and then testing if indication is
+ *        enabled.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded CCCD is stored.
+ *
+ * @retval      TRUE If indication is enabled.
+ * @retval      FALSE Otherwise.
+ */
+static __INLINE bool ble_srv_is_indication_enabled(uint8_t * p_encoded_data)
+{
+    uint16_t cccd_value = uint16_decode(p_encoded_data);
+    return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0);
+}
+
+/**@brief Function for encoding a Report Reference Descriptor.
+ *
+ * @param[in]   p_encoded_buffer  The buffer of the encoded data.
+ * @param[in]   p_report_ref      Report Reference value to be encoded.
+ *
+ * @return      Length of the encoded data.
+ */
+uint8_t ble_srv_report_ref_encode(uint8_t *                    p_encoded_buffer,
+                                  const ble_srv_report_ref_t * p_report_ref);
+
+/**@brief Function for making a UTF-8 structure refer to an ASCII string.
+ *
+ * @param[out]  p_utf8   UTF-8 structure to be set.
+ * @param[in]   p_ascii  ASCII string to be referred to.
+ */
+void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii);
+
+
+/**@brief Security Access enumeration.
+ * @details This enumeration gives the possible requirements for accessing a characteristic value.
+ */
+typedef enum
+{
+    SEC_NO_ACCESS    = 0,            /**< Not possible to access. */
+    SEC_OPEN         = 1,            /**< Access open. */
+    SEC_JUST_WORKS   = 2,            /**< Access possible with 'Just Works' security at least. */
+    SEC_MITM         = 3,            /**< Access possible with 'MITM' security at least. */
+    SEC_SIGNED       = 4,            /**< Access possible with 'signed' security at least. */
+    SEC_SIGNED_MITM  = 5             /**< Access possible with 'signed and MITM' security at least. */
+}security_req_t;
+
+
+/**@brief Characteristic User Descriptor parameters.
+ * @details This structure contains the parameters for User Descriptor.
+ */
+typedef struct
+{
+    uint16_t               max_size;                      /**< Maximum size of the user descriptor*/
+    uint16_t               size;                          /**< Size of the user descriptor*/
+    uint8_t                *p_char_user_desc;             /**< User descriptor content, pointer to a UTF-8 encoded string (non-NULL terminated)*/
+    bool                   is_var_len;                    /**< Indicates if the user descriptor has variable length.*/
+    ble_gatt_char_props_t  char_props;                    /**< user descriptor properties.*/
+    bool                   is_defered_read;               /**< Indicate if deferred read operations are supported.*/
+    bool                   is_defered_write;              /**< Indicate if deferred write operations are supported.*/
+    security_req_t         read_access;                   /**< Security requirement for reading the user descriptor.*/
+    security_req_t         write_access;                  /**< Security requirement for writing the user descriptor.*/
+    bool                   is_value_user;                 /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+}ble_add_char_user_desc_t;
+
+
+/**@brief Add characteristic parameters structure.
+ * @details This structure contains the parameters needed to use the @ref characteristic_add function.
+ */
+typedef struct
+{
+    uint16_t                    uuid;                     /**< Characteristic UUID (16 bits UUIDs).*/
+    uint8_t                     uuid_type;                /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
+    uint16_t                    max_len;                  /**< Maximum length of the characteristic value.*/
+    uint16_t                    init_len;                 /**< Initial length of the characteristic value.*/
+    uint8_t *                   p_init_value;             /**< Initial encoded value of the characteristic.*/
+    bool                        is_var_len;               /**< Indicates if the characteristic value has variable length.*/
+    ble_gatt_char_props_t       char_props;               /**< Characteristic properties.*/
+    bool                        is_defered_read;          /**< Indicate if deferred read operations are supported.*/
+    bool                        is_defered_write;         /**< Indicate if deferred write operations are supported.*/
+    security_req_t              read_access;              /**< Security requirement for reading the characteristic value.*/
+    security_req_t              write_access;             /**< Security requirement for writing the characteristic value.*/
+    security_req_t              cccd_write_access;        /**< Security requirement for writing the characteristic's CCCD.*/
+    bool                        is_value_user;            /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+    ble_add_char_user_desc_t    *p_user_descr;            /**< Pointer to user descriptor if needed*/
+    ble_gatts_char_pf_t         *p_presentation_format;   /**< Pointer to characteristic format if needed*/
+} ble_add_char_params_t;
+
+
+/**@brief Add descriptor parameters structure.
+ * @details This structure contains the parameters needed to use the @ref descriptor_add function.
+ */
+typedef struct
+{
+    uint16_t       uuid;                     /**< descriptor UUID (16 bits UUIDs).*/
+    uint8_t        uuid_type;                /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
+    bool           is_defered_read;          /**< Indicate if deferred read operations are supported.*/
+    bool           is_defered_write;         /**< Indicate if deferred write operations are supported.*/
+    bool           is_var_len;               /**< Indicates if the descriptor value has variable length.*/
+    security_req_t read_access;              /**< Security requirement for reading the descriptor value.*/
+    security_req_t write_access;             /**< Security requirement for writing the descriptor value.*/
+    bool           is_value_user;            /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+    uint16_t       init_len;                 /**< Initial descriptor value length in bytes. */
+    uint16_t       init_offs;                /**< Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+    uint16_t       max_len;                  /**< Maximum descriptor value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+    uint8_t*       p_value;                  /**< Pointer to the value of the descriptor*/
+} ble_add_descr_params_t;
+
+
+/**@brief Function for adding a characteristic to a given service. 
+ *
+ * If no pointer is given for the initial value,
+ * the initial length parameter will be ignored and the initial length will be 0.
+ *
+ * @param[in]  service_handle Handle of the service to which the characteristic is to be added.
+ * @param[in]  p_char_props   Information needed to add the characteristic.
+ * @param[out] p_char_handle  Handle of the added characteristic.
+ *
+ * @retval      NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
+ */
+uint32_t characteristic_add(uint16_t                   service_handle,
+                            ble_add_char_params_t *    p_char_props,
+                            ble_gatts_char_handles_t * p_char_handle);
+
+
+/**@brief Function for adding a characteristic's descriptor to a given characteristic.
+ *
+ * @param[in]  char_handle    Handle of the characteristic to which the descriptor is to be added, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in]  p_descr_props  Information needed to add the descriptor.
+ * @param[out] p_descr_handle Handle of the added descriptor.
+ *
+ * @retval      NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
+ */
+uint32_t descriptor_add(uint16_t                   char_handle,
+                        ble_add_descr_params_t *   p_descr_props,
+                        uint16_t *                 p_descr_handle);
+
+
+#endif // BLE_SRV_COMMON_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/config/device_manager_cnfg.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 device_manager_cnfg.h
+ *
+ * @cond
+ * @defgroup device_manager_cnfg Device Manager Configuration 
+ * @ingroup device_manager
+ * @{
+ *
+ * @brief Defines application specific configuration for Device Manager.
+ *
+ * @details All configurations that are specific to application have been defined
+ *          here. Application should configuration that best suits its requirements.
+ */
+ 
+#ifndef DEVICE_MANAGER_CNFG_H__
+#define DEVICE_MANAGER_CNFG_H__
+
+/**
+ * @defgroup device_manager_inst Device Manager Instances
+ * @{
+ */
+/**
+ * @brief Maximum applications that Device Manager can support.
+ *
+ * @details Maximum application that the Device Manager can support.
+ *          Currently only one application can be supported.
+ *          Minimum value : 1
+ *          Maximum value : 1
+ *          Dependencies  : None.
+ */
+#define DEVICE_MANAGER_MAX_APPLICATIONS  1
+
+/**
+ * @brief Maximum connections that Device Manager should simultaneously manage.
+ *
+ * @details Maximum connections that Device Manager should simultaneously manage.
+ *          Minimum value : 1
+ *          Maximum value : Maximum links supported by SoftDevice.
+ *          Dependencies  : None.
+ */
+#define DEVICE_MANAGER_MAX_CONNECTIONS   1
+
+
+/**
+ * @brief Maximum bonds that Device Manager should manage.
+ *
+ * @details Maximum bonds that Device Manager should manage.
+ *          Minimum value : 1
+ *          Maximum value : 254.
+ *          Dependencies  : None.
+ * @note In case of GAP Peripheral role, the Device Manager will accept bonding procedure 
+ *       requests from peers even if this limit is reached, but bonding information will not 
+ *       be stored. In such cases, application will be notified with DM_DEVICE_CONTEXT_FULL 
+ *       as event result at the completion of the security procedure.
+ */
+#define DEVICE_MANAGER_MAX_BONDS         6
+
+
+/**
+ * @brief Maximum Characteristic Client Descriptors used for GATT Server.
+ *
+ * @details Maximum Characteristic Client Descriptors used for GATT Server.
+ *          Minimum value : 1
+ *          Maximum value : 254.
+ *          Dependencies  : None.
+ */
+#define DM_GATT_CCCD_COUNT               2
+
+
+/**
+ * @brief Size of application context.
+ *
+ * @details Size of application context that Device Manager should manage for each bonded device.
+ *          Size had to be a multiple of word size.
+ *          Minimum value : 4.
+ *          Maximum value : 256. 
+ *          Dependencies  : Needed only if Application Context saving is used by the application.
+ * @note If set to zero, its an indication that application context is not required to be managed
+ *       by the module.
+ */
+#define DEVICE_MANAGER_APP_CONTEXT_SIZE    0
+
+/* @} */
+/* @} */
+/** @endcond */
+#endif // DEVICE_MANAGER_CNFG_H__
+
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/device_manager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 device_manager.h
+ *
+ * @defgroup device_manager Device Manager
+ * @ingroup ble_sdk_lib
+ * @{
+ * @brief Device Manager Application Interface Abstraction.
+ *
+ * @details The Device Manager module manages Active and Bonded Peers. Management of peer includes
+ *          book keeping of contextual information like the Security Keys, GATT
+ *          configuration and any application specific information.
+ *
+ *          Active Peers are devices which are connected, and may or may not be bonded.
+ *          Bonded Peers are devices which are bonded, and may or may not be Active (Connected).
+ *          Active Bonded Peer refers to a device which is connected and bonded.
+ *
+ *          Paired Devices refers to peer devices that are connected and have necessary context
+ *          establishment/exchange for the current connection session. On disconnect,
+ *          all contextual information is flushed. For example, SMP Information Exchanged during
+ *          pairing and GATT Configuration is not retained on disconnection.
+ *
+ *          Note that this module allows management of contextual information but 
+ *          does not provide an interface for connection management. Therefore, entering connectible
+ *          mode, connection establishment, or disconnection of a link with peer is not in scope
+ *          of this module.
+ *
+ *          For bonded peers, the contextual information is required to be retained on disconnection
+ *          and power cycling. Persistent storage of contextual information is handled by the
+ *          module. This module categorizes the contextual information into 3 categories:
+ *             - <b>Bonding Information</b>
+ *               Bond information is the information exchanged between local and peer device to
+ *               establish a bond. It also includes peer identification information,
+ *               like the peer address or the IRK or both. From here on this category of information
+ *               is referred to as Device Context.
+ *             - <b>Service/Protocol Information</b>
+ *               Service/Protocol information is the information retained for the peer to save on one-time
+ *               procedures like the GATT Service Discovery procedures and Service Configurations.
+ *               It allows devices to resume data exchange on subsequent reconnection without having
+ *               to perform initial set-up procedures each time. From here on this category is
+ *               referred to as Service Context.
+ *             - <b>Application Information</b>
+ *               Application information is the context that the application would like to associate with
+ *               each of the bonded device. For example, if the application chooses to rank its peers
+ *               in order to manage them better, the rank information could be treated as
+ *               Application Information. This storage space is provided to save the application from
+ *               maintaining a mapping table with each Device Instance and Application Information.
+ *               However, if the application have no use for this, it is possible to not
+ *               use or employ this at compile time. From here on this category of information is
+ *               referred to as Application Context.
+ */
+
+
+#ifndef DEVICE_MANAGER_H__
+#define DEVICE_MANAGER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_common.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "device_manager_cnfg.h"
+
+/**
+ * @defgroup dm_service_cntext_types Service/Protocol Types
+ *
+ * @brief Describes the possible types of Service/Protocol Contexts for a bonded/peer device.
+ *
+ * @details Possible Service/Protocol context per peer device. The Device Manager provides the
+ *          functionality of persistently storing the Service/Protocol context and can automatically
+ *          load them when needed.
+ *          For example system attributes for a GATT Server. Based on the nature of the application, 
+ *          not all service types may be needed. The application can specify
+ *          only the service/protocol context it wants to use at the time of registration.
+ * @{
+ */
+#define DM_PROTOCOL_CNTXT_NONE         0x00  /**< No Service Context, this implies the application does not want to associate any service/protocol context with the peer device */
+#define DM_PROTOCOL_CNTXT_GATT_SRVR_ID 0x01  /**< GATT Server Service Context, this implies the application does associate GATT Server with the peer device and this information will be loaded when needed for a bonded device */
+#define DM_PROTOCOL_CNTXT_GATT_CLI_ID  0x02  /**< GATT Client Service Context, this implies the application does associate GATT Client with the peer device and this information will be loaded when needed for a bonded device */
+#define DM_PROTOCOL_CNTXT_ALL                                                                     \
+        (DM_PROTOCOL_CNTXT_GATT_SRVR_ID | DM_PROTOCOL_CNTXT_GATT_CLI_ID) /**< All Service/Protocol Context, this implies that the application wants to associate all Service/Protocol Information with the bonded device. This is configurable based on system requirements. If the application has only one type of service, this define could be altered to reflect the same.  */
+/** @} */
+
+
+/**
+ * @defgroup dm_events Device Manager Events
+ *
+ * @brief This section describes the device manager events that are notified to the application.
+ *
+ * @details The Device Manager notifies the application of various asynchronous events using the
+ *          asynchronous event notification callback. All events has been categorized into:
+ *          a. General.
+ *          b. Link Status.
+ *          c. Context Management.
+ *
+ *          In the callback, these events are notified along with handle that uniquely identifies:
+ *          application instance, active instance (if applicable), device instance
+ *          bonding instance, (if applicable) and service instance.
+ *          Not all events are pertaining to an active connection, for example a context deletion event could occur even if the peer
+ *          is not connected. Also, general category of events may not be pertaining to any specific peer.
+ *          See also \ref dm_event_cb_t and \ref dm_register.
+ * @{
+ */
+/**
+ * @defgroup general_events General Events
+ *
+ * @brief General or miscellaneous events.
+ *
+ * @details This category of events are general events not pertaining to a peer or context.
+ *
+ * @{
+ */
+#define DM_EVT_RFU   0x00 /**< Reserved for future use, is never notified. */
+#define DM_EVT_ERROR 0x01 /**< Device Manager Event Error. */
+/** @} */
+
+/**
+ * @defgroup link_status_events Link Status Events
+ *
+ * @brief Link Status Events.
+ *
+ * @details This category of events notify the application of the link status. Event result associated
+ *          with the event is provided along with the event in the callback to provide more details of
+ *          whether a procedure succeeded or failed and assist the application in decision making of
+ *          how to proceed. For example if a DM_DEVICE_CONNECT_IND is indicated with NRF_SUCCESS
+ *          result, the application may want to proceed with discovering and association with
+ *          service of the peer. However, if indicated with a failure result, the application may
+ *          want to take an alternate action such as reattempting to connect or go into a
+ *          sleep mode.
+ *
+ * @{
+ */
+#define DM_EVT_CONNECTION              0x11 /**< Indicates that link with the peer is established. */
+#define DM_EVT_DISCONNECTION           0x12 /**< Indicates that link with peer is torn down. */
+#define DM_EVT_SECURITY_SETUP          0x13 /**< Security procedure for link started indication */
+#define DM_EVT_SECURITY_SETUP_COMPLETE 0x14 /**< Security procedure for link completion indication. */
+#define DM_EVT_LINK_SECURED            0x15 /**< Indicates that link with the peer is secured. For bonded devices, subsequent reconnections with bonded peer will result only in this event when the link is secured and setup procedures will not occur unless the bonding information is either lost or deleted on either or both sides.  */
+#define DM_EVT_SECURITY_SETUP_REFRESH  0x16 /**< Indicates that the security on the link was re-established. */
+/** @} */
+
+/**
+ * @defgroup context_mgmt_events Context Management Events
+ *
+ * @brief Context Management Events.
+ *
+ * @details These events notify the application of the status of context loading and storing.
+ *
+ * @{
+ */
+#define DM_EVT_DEVICE_CONTEXT_LOADED   0x21 /**< Indicates that device context for a peer is loaded. */
+#define DM_EVT_DEVICE_CONTEXT_STORED   0x22 /**< Indicates that device context is stored persistently. */
+#define DM_EVT_DEVICE_CONTEXT_DELETED  0x23 /**< Indicates that device context is deleted. */
+#define DM_EVT_SERVICE_CONTEXT_LOADED  0x31 /**< Indicates that service context for a peer is loaded. */
+#define DM_EVT_SERVICE_CONTEXT_STORED  0x32 /**< Indicates that service context is stored persistently. */
+#define DM_EVT_SERVICE_CONTEXT_DELETED 0x33 /**< Indicates that service context is deleted. */
+#define DM_EVT_APPL_CONTEXT_LOADED     0x41 /**< Indicates that application context for a peer is loaded. */
+#define DM_EVT_APPL_CONTEXT_STORED     0x42 /**< Indicates that application context is stored persistently. */
+#define DM_EVT_APPL_CONTEXT_DELETED    0x43 /**< Indicates that application context is deleted. */
+/** @} */
+/** @} */
+
+#define DM_INVALID_ID 0xFF /**< Invalid instance idenitifer. */
+
+/**
+ * @defgroup dm_data_structure Device Manager Data Types
+ *
+ * @brief This section describes all the data types exposed by the module to the application.
+ * @{
+ */
+
+/**
+ * @brief Application Instance.
+ *
+ * @details Application instance uniquely identifies an application. The identifier is allocated by
+ *          the device manager when application registers with the module. The application is
+ *          expected to identify itself with this instance identifier when initiating subsequent
+ *          requests. Application should use the utility API \ref dm_application_instance_set in
+ *          order to set its application instance in dm_handle_t needed for all subsequent APIs.
+ *          See also \ref dm_register.
+ */
+typedef uint8_t dm_application_instance_t;
+
+/**
+ * @brief Connection Instance.
+ *
+ * @details Identifies connection instance for an active device. This instance is allocated by the 
+ *          device manager when a connection is established and is notified with DM_EVT_CONNECTION
+ *          with the event result NRF_SUCCESS.
+ */
+typedef uint8_t dm_connection_instance_t;
+
+/**
+ * @brief Device Instance.
+ *
+ * @details Uniquely identifies a bonded peer device. The peer device may or may not be connected.
+ *          In case of the central: The bonded device instance to identify the peer is allocated when bonding procedure is initiated by the central using dm_security_setup_req.
+ *          In case of the peripheral: When the bonding procedure is successful, the DM_EVT_SECURITY_SETUP_COMPLETE event with success event result, is received.
+ *          In case the module cannot add more bonded devices, no instance is allocated, this is indicated by an appropriate error code for the API/event as the case may be. Application can choose to disconnect the link.
+ */
+typedef uint8_t dm_device_instance_t;
+
+/**
+ * @brief Service Instance.
+ *
+ * @details Uniquely identifies a peer device. The peer device may or may not be connected. This
+ *          instance is allocated by the device manager when a device is bonded and is notified
+ *          when security procedures have been initiated.
+ *          Security Procedures initiation is notified with DM_SECURITY_SETUP_IND with
+ *          success event result. In case the event result indicates that the module cannot add more
+ *          bonded devices, no instance is allocated. Application can chose to disconnect the link.
+ */
+typedef uint8_t dm_service_instance_t;
+
+/**
+ * @brief Service/Protocol Type Identifier.
+ *
+ * @details Uniquely identifies a service or a protocol type. Service/Protocol Type identification
+ *          is needed as each service/protocol can have its own contextual data.
+ *          This allows the peer to access more than one service at a time. \ref dm_service_cntext_types describes the
+ *          list of services/protocols supported.
+ */
+typedef uint8_t service_type_t;
+
+/**@brief Device Manager Master identification and encryption information. */
+typedef struct dm_enc_key
+{
+    ble_gap_enc_info_t  enc_info;  /**< GAP encryption information. */
+    ble_gap_master_id_t master_id; /**< Master identification. */
+} dm_enc_key_t;
+
+/** @brief Device Manager identity and address information. */
+typedef struct dm_id_key
+{
+  ble_gap_irk_t  id_info;      /**< Identity information. */
+  ble_gap_addr_t id_addr_info; /**< Identity address information. */
+} dm_id_key_t;
+
+/** @brief Device Manager signing information. */
+typedef struct dm_sign_key
+{
+    ble_gap_sign_info_t sign_key; /**< GAP signing information. */
+} dm_sign_key_t;
+
+/** @brief Security keys. */
+typedef struct dm_sec_keyset
+{
+    union 
+    {
+        dm_enc_key_t       * p_enc_key;  /**< Pointer to Device Manager encryption information structure. */
+    } enc_key;
+    dm_id_key_t   * p_id_key;            /**< Identity key, or NULL. */
+    dm_sign_key_t * p_sign_key;          /**< Signing key, or NULL. */
+} dm_sec_keys_t;
+
+/** @brief Device Manager security key set. */
+typedef struct
+{
+  dm_sec_keys_t keys_periph;  /**< Keys distributed by the device in the Peripheral role. */
+  dm_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */
+} dm_sec_keyset_t;
+
+/**
+ * @brief Device Handle used for unique identification of each peer.
+ *
+ * @details This data type is used to uniquely identify each peer device. A peer device could be
+ *          active and/or bonded. Therefore an instance for active and bonded is provided.
+ *          However, the application is expected to treat this is an opaque structure and use this for
+ *          all API interactions once stored on appropriate events.
+ *          See \ref dm_events.
+ */
+typedef struct device_handle
+{
+    dm_application_instance_t    appl_id;       /**< Identifies the application instances for the device that is being managed. */
+    dm_connection_instance_t     connection_id; /**< Identifies the active connection instance. */
+    dm_device_instance_t         device_id;     /**< Identifies peer instance in the data base. */
+    dm_service_instance_t        service_id;    /**< Service instance identifier. */
+} dm_handle_t;
+
+/**
+ * @brief Definition of Data Context.
+ *
+ * @details Defines contextual data format, it consists of context data length and pointer to data.
+ */
+typedef struct
+{
+    uint32_t  flags;  /**< Additional flags identifying data. */
+    uint32_t  len;    /**< Length of data. */
+    uint8_t * p_data; /**< Pointer to contextual data, a copy is made of the data. */
+} dm_context_t;
+
+
+/**
+ * @brief Device Context.
+ *
+ * @details Defines "device context" type for a device managed by device manager.
+ */
+typedef dm_context_t dm_device_context_t;
+
+/**
+ * @brief Service Context.
+ *
+ * @details Service context data for a service identified by the 'service_type' field.
+ */
+typedef struct
+{
+    service_type_t service_type; /**< Identifies the service/protocol to which the context data is related. */
+    dm_context_t   context_data; /**< Contains length and pointer to context data */
+} dm_service_context_t;
+
+/**
+ * @brief Application context.
+ *
+ * @details The application context can be used by the application to map any application level
+ *          information that is to be mapped with a particular peer.
+ *          For bonded peers, this information will be stored by the bond manager persistently.
+ *          Note that the device manager treats this information as an
+ *          opaque block of bytes.
+ *          Necessary APIs to get and set this context for a peer have been provided.
+ */
+typedef dm_context_t dm_application_context_t;
+
+/**
+ * @brief Event parameters.
+ *
+ * @details Defines event parameters for each of the events notified by the module.
+ */
+typedef union
+{
+    ble_gap_evt_t            * p_gap_param;       /**< All events that are triggered in device manager as a result of GAP events, like connection, disconnection and security procedures are accompanied with GAP parameters. */
+    dm_application_context_t * p_app_context;     /**< All events that are associated with application context procedures of store, load, and deletion have this as event parameter. */
+    dm_service_context_t     * p_service_context; /**< All events that are associated with service context procedures of store, load and deletion have this as event parameter. */
+    dm_device_context_t      * p_device_context;  /**< All events that are associated with device context procedures of store, load and deletion have this as event parameter. */
+} dm_event_param_t;
+
+/**
+ * @brief Asynchronous events details notified to the application by the module.
+ *
+ * @details Defines event type along with event parameters notified to the application by the
+ *          module.
+ */
+typedef struct
+{
+    uint8_t          event_id;       /**< Identifies the event. See \ref dm_events for details on event types and their significance. */
+    dm_event_param_t event_param;    /**< Event parameters. Can be NULL if the event does not have any parameters. */
+    uint16_t         event_paramlen; /**< Length of the event parameters, is zero if the event does not have any parameters. */
+} dm_event_t;
+
+/**
+ * @brief Event notification callback registered by application with the module.
+ *
+ * @details Event notification callback registered by application with the module when registering
+ *          the module using \ref dm_register API.
+ *
+ * @param[in] p_handle   Identifies the peer for which the event is being notified.
+ * @param[in] p_event    Identifies the event, any associated parameters and parameter length.
+ *                       See \ref dm_events for details on event types and their significance.
+ * @param[in,out] event_result   Provide additional information on the event. 
+ *                      In addition to SDK error codes there is also a return value
+ *                      indicating if maximum number of connections has been reached when connecting or bonding.
+ *
+ * @retval NRF_SUCCESS on success, or a failure to indicate if it could handle the event
+ *         successfully. There is no action taken in case application returns a failure.
+ */
+typedef ret_code_t (*dm_event_cb_t)(dm_handle_t const * p_handle,
+                                    dm_event_t const  * p_event,
+                                    ret_code_t        event_result);
+
+/**
+ * @brief Initialization Parameters.
+ *
+ * @details Indicates the application parameters. Currently this only encompasses clearing
+ *          all persistent data.
+ */
+typedef struct
+{
+    bool clear_persistent_data; /**< Set to true in case the module should clear all persistent data. */
+} dm_init_param_t;
+
+/**
+ * @brief Application Registration Parameters.
+ *
+ * @details Parameters needed by the module when registering with it.
+ */
+typedef struct
+{
+    dm_event_cb_t        evt_handler;  /**< Event Handler to be registered. It will receive asynchronous notification from the module, see \ref dm_events for asynchronous events. */
+    uint8_t              service_type; /**< Bit mask identifying services that the application intends to support for all peers. */
+    ble_gap_sec_params_t sec_param;    /**< Security parameters to be used for the application. */
+} dm_application_param_t;
+
+/**
+ * @brief Defines possible security status/states.
+ *
+ * @details Defines possible security status/states of a link when requested by application using
+ *          the \ref dm_security_status_req.
+ */
+typedef enum
+{
+    NOT_ENCRYPTED,          /**< The link is not secured. */
+    ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
+    ENCRYPTED               /**< The link is secure.*/
+} dm_security_status_t;
+/** @} */
+
+/**
+ * @defgroup dm_api Device Module APIs
+ *
+ * @brief This section describes APIs exposed by the module.
+ *
+ * @details This section describes APIs exposed by the module. The APIs have been categorized to provide
+ *          better and specific look up for developers. Categories are:
+ *          - Set up APIs.
+ *          - Context Management APIs.
+ *          - Utility APIs.
+ *
+ *          MSCs describe usage of these APIs.  
+ *          See @ref dm_msc.
+ * @{
+ */
+/**
+ * @defgroup dm_setup_api Device Module Set-up APIs
+ *
+ * @brief Initialization & registration APIs that are pre-requisite for all other module procedures.
+ * @details This section describes the Module Initialization and Registration APIs needed to be set up by
+ *          the application before device manager can start managing devices and device contexts
+ *          for the application.
+ *
+ * @{
+ */
+
+/**
+ * @brief Module Initialization Routine.
+ *
+ * @details Function for initializing the module. Must called before any other APIs of the module are used.
+ *
+ * @param[in] p_init_param Initialization parameters.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ *
+ * @note It is mandatory that pstorage is initialized before initializing this module.
+ */
+ret_code_t dm_init(dm_init_param_t const * p_init_param);
+
+/**
+ * @brief Function for registering the application.
+ *
+ * @details This routine is used by the application to register for asynchronous events with the
+ *          device manager. During registration the application also indicates the services that it
+ *          intends to support on this instance. It is possible to register multiple times with the
+ *          device manager. At least one instance shall be registered with the device manager after
+ *          the module has been initialized.
+ *          Maximum number of application instances device manager can support is determined
+ *          by DM_MAX_APPLICATIONS.
+ *
+ *          All applications must be registered before initiating or accepting connections from the peer.     
+ *
+ * @param[in]  p_appl_param    Application parameters.
+ * @param[out] p_appl_instance Application Instance Identifier in case registration is successful.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization.
+ * @retval NRF_ERROR_NO_MEM        If module cannot support more applications.
+ *
+ * @note Currently only one application instance is supported by the module.
+ */
+ret_code_t dm_register(dm_application_instance_t    * p_appl_instance,
+                       dm_application_param_t const * p_appl_param);
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @details BLE Event Handler for the module. This routine should be called from BLE stack event
+ *          dispatcher for the module to work as expected.
+ *
+ * @param[in] p_ble_evt BLE stack event being dispatched to the function.
+ *
+ */
+void dm_ble_evt_handler(ble_evt_t * p_ble_evt);
+
+/** @} */
+
+
+/**
+ * @defgroup dm_security_api APIs to set up or read status of security on a link.
+ *
+ * @brief This section describes APIs to set up Security. These APIs require that the peer is
+ *        connected before the procedures can be requested.
+ *
+ * @details This group allows application to request security procedures
+ *          or get the status of the security on a link.
+ * @{
+ */
+/**
+ * @brief Function for requesting setting up security on a link.
+ *
+ * @details This API initiates security procedures with a peer device.
+ *          @note For the GAP Central role, in case peer is not bonded, request to bond/pair is
+ *          initiated. If it is bonded, the link is re-encrypted using the existing bond information.
+ *          For the GAP peripheral role, a Slave security request is sent.
+ * @details If a pairing procedure is initiated successfully, application is notified of
+ *          @ref DM_EVT_SECURITY_SETUP_COMPLETE. A result indicating success or failure is notified along with the event.
+ *          In case the link is re-encrypted using existing bond information, @ref DM_EVT_LINK_SECURED is
+ *          notified to the application.
+ *
+ * @param[in] p_handle Identifies the link on which security is desired.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application
+ *                                 or if the peer is not connected when this procedure is requested.
+ */
+ret_code_t dm_security_setup_req(dm_handle_t * p_handle);
+
+/**
+ * @brief Function for reading the status of the security on a link.
+ *
+ * @details This API allows application to query status of security on a link.
+ *
+ * @param[in]  p_handle  Identifies the link on which security is desired.
+ * @param[out] p_status  Pointer where security status is provided to the application.
+ *                       See \ref dm_security_status_t for possible statuses that can be expected.
+ *
+ * @retval NRF_SUCCESS             Or appropriate error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle or p_status is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If peer is not identified by the handle provided by the application
+ *                                 or if peer is not connected when this procedure is requested.
+ */
+ret_code_t dm_security_status_req(dm_handle_t const * p_handle, dm_security_status_t * p_status);
+
+/**
+ * @brief Function for creating the whitelist.
+ *
+ * @details This API allows application to create whitelist based on bonded peer devices in module
+ *          data base.
+ *
+ * @param[in]  p_handle       Identifies the application requesting whitelist creation.
+ * @param[in,out] p_whitelist Pointer where created whitelist is provided to the application.
+ *
+ * @note 'addr_count' and 'irk_count' fields of the structure should be populated with the maximum
+ *       number of devices that the application wishes to request in the whitelist. 
+ *       If the number of bonded devices is less than requested, the fields are updated with that number of devices.
+ *       If the number of devices are more than requested, the module will populate the list
+ *       with devices in the order the bond was established with the peer devices. Also, if this routine is
+ *       called when a connection exists with one or more peer devices,
+ *       those connected devices are not added to the whitelist.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle or p_whitelist is NULL.
+ */
+ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
+                               ble_gap_whitelist_t             * p_whitelist);
+
+/** @} */
+
+
+/**
+ * @defgroup dm_cntxt_mgmt_api Context Management APIs
+ *
+ * @brief Utility APIs offered by the device manager to get information about the peer if and
+ *        when needed.
+ *
+ * @details This group of API allow the application to access information that is not required to be
+ *          maintained by the application but may be needed. Hence it is possible to get the
+ *          information from the module instead of mapping all the information with a device
+ *          context.
+ * @{
+ */
+
+ret_code_t dm_device_add(dm_handle_t               * p_handle,
+                         dm_device_context_t const * p_context);
+
+/**
+ * @brief Function for deleting a peer device context and all related information from the database.
+ *
+ * @details Delete peer device context and all related information from database. If
+ *          this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the
+ *          application. Event result notified along with the event indicates success or failure
+ *          of this procedure.
+ *
+ * @param[in] p_handle Identifies the peer device to be deleted.
+ *
+ * @retval NRF_SUCCESS             on success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE In the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If peer is not identified the handle provided by the application.
+ *
+ * @note Deleting device context results in deleting service and application context for the
+ *       bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and
+ *       DM_EVT_APPL_CONTEXT_DELETED are not notified to the application.
+ */
+ret_code_t dm_device_delete(dm_handle_t const * p_handle);
+
+/**
+ * @brief Function for deleting all peer device context and all related information from the database.
+ *
+ * @details Delete peer device context and all related information from database. If
+ *          this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the
+ *          application for each device that is deleted from the data base. Event result
+ *          notified along with the event indicates success or failure of this procedure.
+ *
+ * @param[in] p_handle Identifies application instance that is requesting
+ *                     the deletion of all bonded devices.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If peer is not identified the handle provided by the application.
+ *
+ * @note Deleting device context results in deleting both service and application context for the
+ *       bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and
+ *       DM_EVT_APPL_CONTEXT_DELETED are not notified to the application.
+ */
+ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle);
+
+/**
+ * @brief Function for setting Service Context for a peer device identified by 'p_handle' parameter.
+ *
+ * @details This API allows application to Set Service Context for a peer device identified by the
+ *          'p_handle' parameter. This API is useful when the Service Context cannot be requested
+ *          from the SoftDevice, but needs to be assembled by the application or an another module.
+ *          (or when service context is exchanged in an out of band way.)
+ *          This API could also be used to trigger a storing of service context into persistent
+ *          memory. If this is desired, a NULL pointer could be passed to the p_context.
+ *
+ * @param[in] p_handle  Identifies peer device for which the procedure is requested.
+ * @param[in] p_context Service context being set. The context information includes length of
+ *                      data and pointer to the contextual data being set. The memory pointed to by
+ *                      the pointer to data is assumed to be resident when API is being called and
+ *                      can be freed or reused once the set procedure is complete. Set procedure
+ *                      completion is indicated by the event \ref DM_EVT_SERVICE_CONTEXT_STORED.
+ *                      The Event result is notified along with the event and indicates success or failure of
+ *                      this procedure.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ */
+ret_code_t dm_service_context_set(dm_handle_t const          * p_handle,
+                                  dm_service_context_t const * p_context);
+
+/**
+ * @brief Function for getting Service Context for a peer device identified by 'p_handle' parameter.
+ *
+ * @details Get Service Context for a peer device identified by the 'p_handle' parameter. If
+ *          this API returns NRF_SUCCESS, DM_EVT_SERVICE_CONTEXT_LOADED event is notified to the
+ *          application. The event result is notified along with the event indicates success or failure
+ *          of this procedure.
+ *
+ * @param[in] p_handle  Identifies peer device for which procedure is requested.
+ * @param[in] p_context Application context being requested. The context information includes length
+ *                      of the data and a pointer to the data. Note that requesting a 'get'
+ *                      of application does not need to provide memory, the pointer to data will be
+ *                      pointing to service data and hence no data movement is involved.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE In case API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ */
+ret_code_t dm_service_context_get(dm_handle_t const    * p_handle,
+                                  dm_service_context_t * p_context);
+
+/**
+ * @brief Function for deleting a Service Context for a peer device identified by the 'p_handle' parameter.
+ *
+ * @details This API allows application to delete a Service Context identified for a peer device
+ *          identified by the 'p_handle' parameter. If this API returns NRF_SUCCESS,
+ *          DM_EVT_SERVICE_CONTEXT_DELETED event is notified to the application. 
+ *          Event result is notified along with the event and indicates success or failure of this
+ *          procedure.
+ *
+ * @param[in] p_handle Identifies peer device for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ */
+ret_code_t dm_service_context_delete(dm_handle_t const * p_handle);
+
+/**
+ * @brief Function for setting Application Context for a peer device identified by the 'p_handle' parameter.
+ *
+ * @details This application allows the setting of the application context for the peer device identified by
+ *          the 'p_handle'. Application context is stored persistently by the module and can be
+ *          requested by the application at any time using the \ref dm_application_context_get
+ *          API. Note that this procedure is permitted only for bonded devices. If the
+ *          device is not bonded, application context cannot be set. However, it is not mandatory
+ *          that the bonded device is connected when requesting this procedure.
+ *
+ * @param[in] p_handle  Identifies peer device for which procedure is requested.
+ *
+ * @param[in] p_context Application context being set. The context information includes length of the
+ *                      data and pointer to the contextual data being set. The memory pointed to by
+ *                      the data pointer is assumed to be resident when API is being called and
+ *                      can be freed or reused once the set procedure is complete. Set procedure
+ *                      completion is notified by the event \ref DM_EVT_APPL_CONTEXT_STORED.
+ *                      The event result is notified along with the event and indicates success or
+ *                      failure of this procedure.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle and/or p_context is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If peer is not identified the handle provided by the application.
+ *
+ * @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero.
+ */
+ret_code_t dm_application_context_set(dm_handle_t const              * p_handle,
+                                      dm_application_context_t const * p_context);
+
+/**
+ * @brief Function for getting Application Context for a peer device identified by the 'p_handle' parameter.
+ *
+ * @details Get Application Context for a peer device identified by the 'p_handle' parameter. If
+ *          this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_LOADED event is notified to the
+ *          application. Event result notified along with the event indicates success or failure
+ *          of this procedure.
+ *
+ * @param[in] p_handle  Identifies peer device for which procedure is requested.
+ * @param[in] p_context Application context being requested. The context information includes
+ *                      length of data and pointer to the contextual data is provided.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle and/or p_context is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ * @retval DM_NO_APP_CONTEXT       If no application context was set that can be fetched.
+ *
+ * @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to
+ *       zero.
+ */
+ret_code_t dm_application_context_get(dm_handle_t const        * p_handle,
+                                      dm_application_context_t * p_context);
+
+/**
+ * @brief Function for deleting Application Context for a peer device identified by the 'p_handle' parameter.
+ *
+ * @details Delete Application Context for a peer device identified by the 'p_handle' parameter. If
+ *          this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_DELETED event is notified to the
+ *          application. The event result notified along with the event and indicates success or failure
+ *          of this procedure.
+ *
+ * @param[in] p_handle Identifies peer device for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If the p_handle is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If peer is not identified the handle provided by the application.
+ * @retval DM_NO_APP_CONTEXT       If no application context was set that can be deleted.
+ *
+ * @note The API returns FEATURE_NOT_ENABLED if the DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero.
+ */
+ret_code_t dm_application_context_delete(dm_handle_t const * p_handle);
+
+/** @} */
+
+
+/**
+ * @defgroup utility_api Utility APIs
+ * @{
+ * @brief This section describes the utility APIs offered by the module.
+ *
+ * @details APIs defined in this section are utility or assisting/helper APIs.
+ */
+/**
+ * @brief Function for Setting/Copying Application instance to Device Manager handle.
+ *
+ * @param[in]  p_appl_instance Application instance to be set.
+ * @param[out] p_handle        Device Manager handle for which the instance is to be copied.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle and/or p_addr is NULL.
+ */
+ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
+                                       dm_handle_t                     * p_handle);
+
+/**
+ * @brief Function for getting a peer's device address.
+ *
+ * @param[in]  p_handle Identifies the peer device whose address is requested. Can not be NULL.
+ * @param[out] p_addr   Pointer where address is to be copied. Can not be NULL.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle and/or p_addr is NULL.
+ * @retval NRF_ERROR_NOT_FOUND     If the peer could not be identified.
+ */
+ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
+                            ble_gap_addr_t    * p_addr);
+
+/**
+ * @brief Function for setting/updating a peer's device address.
+ *
+ * @param[in]  p_handle Identifies the peer device whose address is requested to be set/updated.
+ * @param[out] p_addr   Address to be set/updated.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If p_handle and/or p_addr is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ * @retval NRF_ERROR_INVALID_PARAM If this procedure is requested while connected to the peer or if the address
+ *                                 type was set to BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE.
+ *
+ * @note Setting or updating a peer's device address is permitted 
+ *       only for a peer that is bonded and disconnected.
+ * @note Updated address is reflected only after DM_EVT_DEVICE_CONTEXT_STORED is notified to the
+ *       application for this bonded device instance. In order to avoid abnormal behaviour, it is
+ *       recommended to not invite/initiate connections on the updated address unless this event
+ *       has been notified.
+ */
+ret_code_t dm_peer_addr_set(dm_handle_t const    * p_handle,
+                            ble_gap_addr_t const * p_addr);
+
+/**
+ * @brief Function for initializing Device Manager handle.
+ *
+ * @param[in] p_handle Device Manager handle to be initialized.
+ *
+ * @retval NRF_SUCCESS    On success.
+ * @retval NRF_ERROR_NULL If p_handle is NULL.
+ *
+ * @note This routine is permitted before initialization of the module.
+ */
+ret_code_t dm_handle_initialize(dm_handle_t * p_handle);
+
+/**
+ * @brief Function for getting distributed keys for a device.
+ *
+ * @param[in]  p_handle   Device Manager handle identifying the peer.
+ * @param[out] p_key_dist Pointer to distributed keys.
+ *
+ * @retval NRF_SUCCESS             On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
+ *                                 application registration.
+ * @retval NRF_ERROR_NULL          If the p_handle and/or p_key_dist pointer is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR  If the peer is not identified by the handle provided by the application.
+ */
+ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
+                                   dm_sec_keyset_t   * p_key_dist);
+
+/**
+ * @brief Function for getting the corresponding dm_handle_t based on the connection handle.
+ *
+ * @param[in]     conn_handle Connection handle as provided by the SoftDevice.
+ * @param[in,out] p_handle    Pointer to the p_handle containg the application instance for the 
+ *                            registered application. If the application instance is valid then 
+ *                            the p_handle will be filled with requested data.
+ *
+ * @retval NRF_SUCCESS          On success, else an error code indicating reason for failure.
+ * @retval NRF_ERROR_NULL       If the p_handle pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND  If no p_handle is found for the provided connection handle.
+ */
+ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle);
+
+/** @} */
+/** @} */
+/** @} */
+#endif // DEVICE_MANAGER_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/device_manager/device_manager_peripheral.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,2977 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "device_manager.h"
+#include "pstorage.h"
+#include "ble_hci.h"
+#include "app_error.h"
+
+#if defined ( __CC_ARM )
+    #ifndef __ALIGN
+        #define __ALIGN(x)      __align(x)                  /**< Forced aligment keyword for ARM Compiler */
+    #endif
+#elif defined ( __ICCARM__ )
+    #ifndef __ALIGN
+        #define __ALIGN(x)                                  /**< Forced aligment keyword for IAR Compiler */
+    #endif
+#elif defined   ( __GNUC__ )
+    #ifndef __ALIGN
+        #define __ALIGN(x)      __attribute__((aligned(x))) /**< Forced aligment keyword for GNU Compiler */
+    #endif
+#endif
+
+#define INVALID_ADDR_TYPE 0xFF   /**< Identifier for an invalid address type. */
+#define EDIV_INIT_VAL     0xFFFF /**< Initial value for diversifier. */
+
+/**
+ * @defgroup device_manager_app_states Connection Manager Application States
+ * @{
+ */
+#define STATE_CONTROL_PROCEDURE_IN_PROGRESS 0x01 /**< State where a security procedure is ongoing. */
+#define STATE_QUEUED_CONTROL_REQUEST        0x02 /**< State where it is known if there is any queued security request or not. */
+/** @} */
+
+/**
+ * @defgroup device_manager_conn_inst_states Connection Manager Connection Instances States.
+ * @{
+ */
+#define STATE_IDLE             0x01 /**< State where connection instance is free. */
+#define STATE_CONNECTED        0x02 /**< State where connection is successfully established. */
+#define STATE_PAIRING          0x04 /**< State where pairing procedure is in progress. This state is used for pairing and bonding, as pairing is needed for both. */
+#define STATE_BONDED           0x08 /**< State where device is bonded. */
+#define STATE_DISCONNECTING    0x10 /**< State where disconnection is in progress, application will be notified first, but no further active procedures on the link. */
+#define STATE_PAIRING_PENDING  0x20 /**< State where pairing request is pending on the link. */
+#define STATE_BOND_INFO_UPDATE 0x40 /**< State where information has been updated, update the flash. */
+#define STATE_LINK_ENCRYPTED   0x80 /**< State where link is encrypted. */
+/** @} */
+
+/**
+ * @defgroup device_manager_peer_id_defines Peer Identification Information Defines.
+ *
+ * @brief These defines are used to know which of the peer identification is applicable for a peer.
+ *
+ * @details These defines are used for peer identification. Here, bit map is used because it is
+ *          possible that the application has both IRK and address for identification.
+ * @{
+ */
+#define UNASSIGNED            0xFF /**< Peer instance is unassigned/unused. */
+#define IRK_ENTRY             0x01 /**< Peer instance has IRK as identification information. */
+#define ADDR_ENTRY            0x02 /**< Peer instance has address as identification information. */
+#define SERVICE_CONTEXT_ENTRY 0x04 /**< Peer instance has service context set. */
+#define APP_CONTEXT_ENTRY     0x08 /**< Peer instance has an application context set. */
+/** @} */
+
+/**@brief Device store state identifiers. */
+typedef enum
+{
+    STORE_ALL_CONTEXT, /**< Store all context. */
+    FIRST_BOND_STORE,  /**< Store bond. */
+    UPDATE_PEER_ADDR   /**< Update peer address. */
+} device_store_state_t;
+
+/**
+ * @defgroup device_manager_context_offsets Context Offsets
+ * @{
+ *
+ * @brief Context offsets each of the context information in persistent memory.
+ *
+ * @details Below is a layout showing how each how the context information is stored in persistent
+ *          memory.
+ *
+ * All Device context is stored in the flash as follows:
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ * | Block / Device ID + Layout of stored information in storage block                    |
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ * | Block 0 | Device 0| Peer Id | Bond Information | Service Context| Application Context|
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ * | Block 1 | Device 1| Peer Id | Bond Information | Service Context| Application Context|
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ * |  ...              | ....                                                             |
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ * | Block N | Device N| Peer Id | Bond Information | Service Context| Application Context|
+ * +---------+---------+---------+------------------+----------------+--------------------+
+ *
+ * The following defines are used to get offset of each of the components within a block.
+ */
+
+#define PEER_ID_STORAGE_OFFSET     0                                               /**< Offset at which peer id is stored in the block. */
+#define BOND_STORAGE_OFFSET        PEER_ID_SIZE                                    /**< Offset at which bond information is stored in the block. */
+#define SERVICE_STORAGE_OFFSET     (BOND_STORAGE_OFFSET + BOND_SIZE)               /**< Offset at which service context is stored in the block. */
+#define APP_CONTEXT_STORAGE_OFFSET (SERVICE_STORAGE_OFFSET + SERVICE_CONTEXT_SIZE) /**< Offset at which application context is stored in the block. */
+/** @} */
+
+/**
+ * @defgroup device_manager_context_size Context size.
+ * @{
+ *
+ * @brief This group defines the size of each of the context information.
+ */
+#define PEER_ID_SIZE               (sizeof(peer_id_t))                                             /**< Size of peer identification information. */
+#define BOND_SIZE                  (sizeof(bond_context_t))                                        /**< Size of bond information. */
+#define DEVICE_CONTEXT_SIZE        (PEER_ID_SIZE + BOND_SIZE)                                      /**< Size of Device context, include peer identification and bond information. */
+#define GATTS_SERVICE_CONTEXT_SIZE (sizeof(dm_gatts_context_t))                                    /**< Size of GATTS service context. */
+#define GATTC_SERVICE_CONTEXT_SIZE (sizeof(dm_gatt_client_context_t))                              /**< Size of GATTC service context. */
+#define SERVICE_CONTEXT_SIZE       (GATTS_SERVICE_CONTEXT_SIZE + GATTC_SERVICE_CONTEXT_SIZE)       /**< Combined size of GATTS and GATTC service contexts. */
+#define APP_CONTEXT_MIN_SIZE       4                                                               /**< Minimum size for application context data. */
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+#define APP_CONTEXT_SIZE           (sizeof(uint32_t) + DEVICE_MANAGER_APP_CONTEXT_SIZE)            /**< Size of application context including length field. */
+#else //DEVICE_MANAGER_APP_CONTEXT_SIZE
+#define APP_CONTEXT_SIZE           0                                                               /**< Size of application context. */
+#endif // DEVICE_MANAGER_APP_CONTEXT_SIZE
+#define ALL_CONTEXT_SIZE           (DEVICE_CONTEXT_SIZE + SERVICE_CONTEXT_SIZE + APP_CONTEXT_SIZE) /**< Size of all contexts. */
+/** @} */
+
+
+/**
+ * @defgroup device_manager_log Module's Log Macros
+ *
+ * @details Macros used for creating module logs which can be useful in understanding handling
+ *          of events or actions on API requests. These are intended for debugging purposes and
+ *          can be disabled by defining the DM_DISABLE_LOGS.
+ *
+ * @note That if ENABLE_DEBUG_LOG_SUPPORT is disabled, having DM_DISABLE_LOGS has no effect.
+ * @{
+ */
+#define DM_DISABLE_LOGS        /**< Enable this macro to disable any logs from this module. */
+
+#ifndef DM_DISABLE_LOGS
+#define DM_LOG  app_trace_log  /**< Used for logging details. */
+#define DM_ERR  app_trace_log  /**< Used for logging errors in the module. */
+#define DM_TRC  app_trace_log  /**< Used for getting trace of execution in the module. */
+#define DM_DUMP app_trace_dump /**< Used for dumping octet information to get details of bond information etc. */
+#else //DM_DISABLE_LOGS
+#define DM_DUMP(...)           /**< Disables dumping of octet streams. */
+#define DM_LOG(...)            /**< Disables detailed logs. */
+#define DM_ERR(...)            /**< Disables error logs. */
+#define DM_TRC(...)            /**< Disables traces. */
+#endif //DM_DISABLE_LOGS
+/** @} */
+
+/**
+ * @defgroup device_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but
+ *          framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define DM_MUTEX_LOCK()   SDK_MUTEX_LOCK(m_dm_mutex)   /**< Lock module using mutex. */
+#define DM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dm_mutex) /**< Unlock module using mutex. */
+/** @} */
+
+
+/**
+ * @defgroup device_manager_misc_defines Miscellaneous defines used across the module.
+ * @{
+ */
+#define DM_GATT_ATTR_SIZE            6                                                   /**< Size of each GATT attribute to be stored persistently. */
+#define DM_GATT_SERVER_ATTR_MAX_SIZE ((DM_GATT_ATTR_SIZE * DM_GATT_CCCD_COUNT) + 2) /**< Maximum size of GATT attributes to be stored.*/
+#define DM_SERVICE_CONTEXT_COUNT     (DM_PROTOCOL_CNTXT_ALL + 1)                         /**< Maximum number of service contexts. */
+#define DM_EVT_DEVICE_CONTEXT_BASE   0x20                                                /**< Base for device context base. */
+#define DM_EVT_SERVICE_CONTEXT_BASE  0x30                                                /**< Base for service context base. */
+#define DM_EVT_APP_CONTEXT_BASE      0x40                                                /**< Base for application context base. */
+#define DM_LOAD_OPERATION_ID         0x01                                                /**< Load operation identifier. */
+#define DM_STORE_OPERATION_ID        0x02                                                /**< Store operation identifier. */
+#define DM_CLEAR_OPERATION_ID        0x03                                                /**< Clear operation identifier. */
+/** @} */
+
+#define DM_GATTS_INVALID_SIZE        0xFFFFFFFF                                     /**< Identifer for GATTS invalid size. */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros for verifying parameters passed to the module in the APIs. These macros
+ *          could be mapped to nothing in the final version of the code in order to save execution
+ *          time and program size.
+ * @{
+ */
+
+//#define DM_DISABLE_API_PARAM_CHECK /**< Macro to disable API parameters check. */
+
+#ifndef DM_DISABLE_API_PARAM_CHECK
+
+/**@brief Macro for verifying NULL parameters are not passed to API.
+ *
+ * @param[in] PARAM Parameter checked for NULL.
+ *
+ * @retval (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE) when @ref PARAM is NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM)                            \
+    if ((PARAM) == NULL)                                   \
+    {                                                      \
+        return (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE); \
+    }
+/**@} */
+
+
+/**@brief Macro for verifying module's initialization status.
+ *
+ * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module is not initialized.
+ */
+#define VERIFY_MODULE_INITIALIZED()                                     \
+    do                                                                  \
+    {                                                                   \
+        if (!m_module_initialized)                                      \
+        {                                                               \
+            return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
+        }                                                               \
+    } while (0)
+
+
+/**@brief Macro for verifying module's initialization status. Returns in case it is not initialized.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID() \
+    do                                   \
+    {                                    \
+        if (!m_module_initialized)       \
+        {                                \
+            return;                      \
+        }                                \
+    } while (0)
+
+
+/**@brief Macro for verifying that the application is registered.
+ *
+ * @param[in] X Application instance identifier.
+ *
+ * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module API is called without
+ *         registering an application with the module.
+ */
+#define VERIFY_APP_REGISTERED(X)                                        \
+    do                                                                  \
+    {                                                                   \
+        if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) ||                 \
+            (m_application_table[(X)].ntf_cb == NULL))                  \
+        {                                                               \
+            return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \
+        }                                                               \
+    } while (0)
+
+
+/**@brief Macro for verifying that the application is registered. Returns in case it is not
+ *        registered.
+ *
+ * @param[in] X Application instance identifier.
+ */
+#define VERIFY_APP_REGISTERED_VOID(X)                   \
+    do                                                  \
+    {                                                   \
+        if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \
+            (m_application_table[(X)].ntf_cb == NULL))  \
+        {                                               \
+            return;                                     \
+        }                                               \
+    } while (0)
+
+
+/**@brief Macro for verifying connection instance is allocated.
+ *
+ * @param[in] X Connection instance identifier.
+ *
+ * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when connection instance is not
+ *         allocated.
+ */
+#define VERIFY_CONNECTION_INSTANCE(X)                                  \
+    do                                                                 \
+    {                                                                  \
+        if (((X) >= DEVICE_MANAGER_MAX_CONNECTIONS) ||                 \
+            (m_connection_table[(X)].state == STATE_IDLE))             \
+        {                                                              \
+            return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
+        }                                                              \
+    } while (0)
+
+
+/**@brief Macro for verifying if device instance is allocated.
+ *
+ * @param[in] X Device instance identifier.
+ *
+ * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when device instance is not allocated.
+ */
+#define VERIFY_DEVICE_INSTANCE(X)                                      \
+    do                                                                 \
+    {                                                                  \
+        if (((X) >= DEVICE_MANAGER_MAX_BONDS) ||                       \
+            (m_peer_table[(X)].id_bitmap == UNASSIGNED))               \
+        {                                                              \
+            return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \
+        }                                                              \
+    } while (0)
+
+/**@brief Macro for verifying if device is bonded and thus can store data persistantly.
+ *
+ * @param[in] X Connection instance identifier.
+ *
+ * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when device is not bonded.
+ */
+#define VERIFY_DEVICE_BOND(X)                                              \
+    do                                                                     \
+    {                                                                      \
+        if ((m_connection_table[(X)].state & STATE_BONDED) != STATE_BONDED)\
+        {                                                                  \
+            return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE);    \
+        }                                                                  \
+    } while (0)
+#else
+#define NULL_PARAM_CHECK(X)
+#define VERIFY_MODULE_INITIALIZED()
+#define VERIFY_MODULE_INITIALIZED_VOID()
+#define VERIFY_APP_REGISTERED(X)
+#define VERIFY_APP_REGISTERED_VOID(X)
+#define VERIFY_CONNECTION_INSTANCE(X)
+#define VERIFY_DEVICE_INSTANCE(X)
+#endif //DM_DISABLE_API_PARAM_CHECK
+/** @} */
+
+#define INVALID_CONTEXT_LEN 0xFFFFFFFF /**< Identifier for invalid context length. */
+/**@brief Macro for checking that application context size is greater that minimal size.
+ *
+ * @param[in] X Size of application context.
+ *
+ * @retval (NRF_ERROR_INVALID_PARAM) when size is smaller than minimun required size.
+ */
+#define SIZE_CHECK_APP_CONTEXT(X)                                      \
+    if ((X) < (APP_CONTEXT_MIN_SIZE))                                  \
+    {                                                                  \
+        return NRF_ERROR_INVALID_PARAM;                                \
+    }
+
+
+/**
+ * @defgroup dm_data_types Module's internal data types.
+ *
+ * @brief This section describes a module's internal data structures.
+ * @{
+ */
+/**@brief Peer identification information.
+ */
+typedef struct
+{
+    ble_gap_id_key_t peer_id;   /**< IRK and/or address of peer. */
+    uint16_t         ediv;      /**< Peer's encrypted diversifier. */
+    uint8_t          id_bitmap; /**< Contains information if above field is valid. */
+} peer_id_t;
+
+STATIC_ASSERT(sizeof(peer_id_t) % 4 == 0); /**< Check to ensure Peer identification information is a multiple of 4. */
+
+/**@brief Portion of bonding information exchanged by a device during bond creation that needs to
+ *        be stored persistently.
+ *
+ * @note  An entry is not made in this table unless device is bonded.
+ */
+typedef struct
+{
+    ble_gap_enc_key_t peer_enc_key; /**< Local LTK info, central IRK and address */
+} bond_context_t;
+
+STATIC_ASSERT(sizeof(bond_context_t) % 4 == 0); /**< Check to ensure bond information is a multiple of 4. */
+
+/**@brief GATT Server Attributes size and data.
+ */
+typedef struct
+{
+    uint32_t flags;                                    /**< Flags identifying the stored attributes. */
+    uint32_t size;                                     /**< Size of stored attributes. */
+    uint8_t  attributes[DM_GATT_SERVER_ATTR_MAX_SIZE]; /**< Array to hold the server attributes. */
+} dm_gatts_context_t;
+
+STATIC_ASSERT(sizeof(dm_gatts_context_t) % 4 == 0); /**< Check to ensure GATT Server Attributes size and data information is a multiple of 4. */
+
+/**@brief GATT Client context information. Placeholder for now.
+ */
+typedef struct
+{
+    void * p_dummy; /**< Placeholder, currently unused. */
+} dm_gatt_client_context_t;
+
+STATIC_ASSERT(sizeof(dm_gatt_client_context_t) % 4 == 0);  /**< Check to ensure GATT Client context information is a multiple of 4. */
+STATIC_ASSERT((DEVICE_MANAGER_APP_CONTEXT_SIZE % 4) == 0); /**< Check to ensure device manager application context information is a multiple of 4. */
+
+/**@brief Connection instance definition. Maintains information with respect to an active peer.
+ */
+typedef struct
+{
+    ble_gap_addr_t peer_addr;     /**< Peer identification information. This information is retained as long as the connection session exists, once disconnected, for non-bonded devices this information is not stored persistently. */
+    uint16_t       conn_handle;   /**< Connection handle for the device. */
+    uint8_t        state;         /**< Link state. */
+    uint8_t        bonded_dev_id; /**< In case the device is bonded, this points to the corresponding bonded device. This index can be used to index service and bond context as well. */
+} connection_instance_t;
+
+/**@brief Application instance definition. Maintains information with respect to a registered
+ *        application.
+ */
+typedef struct
+{
+    dm_event_cb_t        ntf_cb;    /**< Callback registered with the application. */
+    ble_gap_sec_params_t sec_param; /**< Local security parameters registered by the application. */
+    uint8_t              state;     /**< Application state. Currently this is used only for knowing if any security procedure is in progress and/or a security procedure is pending to be requested. */
+    uint8_t              service;   /**< Service registered by the application. */
+} application_instance_t;
+
+/**@brief Function for performing necessary action of storing each of the service context as
+ *        registered by the application.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is stored.
+ *
+ * @retval Operation result code.
+ */
+typedef ret_code_t (* service_context_access_t)(pstorage_handle_t const * p_block_handle,
+                                                dm_handle_t const       * p_handle);
+
+/**@brief Function for performing necessary action of applying the context information.
+ *
+ * @param[in] p_handle Device handle identifying device that is stored.
+ *
+ * @retval Operation result code.
+ */
+typedef ret_code_t (* service_context_apply_t)(dm_handle_t * p_handle);
+
+/**@brief Function for performing necessary functions of storing or updating.
+ *
+ * @param[in] p_dest Destination address where data is stored persistently.
+ * @param[in] p_src  Source address containing data to be stored.
+ * @param[in] size   Size of data to be stored expressed in bytes. Must be word aligned.
+ * @param[in] offset Offset in bytes to be applied when writing to the block.
+ *
+ * @retval Operation result code.
+ */
+typedef uint32_t (* storage_operation)(pstorage_handle_t * p_dest,
+                                       uint8_t           * p_src,
+                                       pstorage_size_t     size,
+                                       pstorage_size_t     offset);
+/** @} */
+
+/**
+ * @defgroup dm_tables Module's internal tables.
+ *
+ * @brief This section describes the module's internal tables and the static global variables
+ *        needed for its functionality.
+ * @{
+ */
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+static uint8_t * m_app_context_table[DEVICE_MANAGER_MAX_BONDS];                     /**< Table to remember application contexts of bonded devices. */
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+__ALIGN(sizeof(uint32_t))
+static peer_id_t              m_peer_table[DEVICE_MANAGER_MAX_BONDS] ;              /**< Table to maintain bonded devices' identification information, an instance is allocated in the table when a device is bonded and freed when bond information is deleted. */
+__ALIGN(sizeof(uint32_t))
+static bond_context_t         m_bond_table[DEVICE_MANAGER_MAX_CONNECTIONS];         /**< Table to maintain bond information for active peers. */
+static dm_gatts_context_t     m_gatts_table[DEVICE_MANAGER_MAX_CONNECTIONS];        /**< Table for service information for active connection instances. */
+static connection_instance_t  m_connection_table[DEVICE_MANAGER_MAX_CONNECTIONS];   /**< Table to maintain active peer information. An instance is allocated in the table when a new connection is established and freed on disconnection. */
+static application_instance_t m_application_table[DEVICE_MANAGER_MAX_APPLICATIONS]; /**< Table to maintain application instances. */
+static pstorage_handle_t      m_storage_handle;                                     /**< Persistent storage handle for blocks requested by the module. */
+static uint32_t               m_peer_addr_update;                                   /**< 32-bit bitmap to remember peer device address update. */
+static ble_gap_id_key_t       m_local_id_info;                                      /**< ID information of central in case resolvable address is used. */
+static bool                   m_module_initialized = false;                         /**< State indicating if module is initialized or not. */
+static uint8_t                m_irk_index_table[DEVICE_MANAGER_MAX_BONDS];          /**< List maintaining IRK index list. */
+
+SDK_MUTEX_DEFINE(m_dm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+/** @} */
+
+static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
+                                                    dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
+                                                dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
+                                                   dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
+                                              dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
+                                              dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle);
+
+static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle);
+
+static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle);
+
+static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle);
+
+static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle);
+
+
+/**< Array of function pointers based on the types of service registered. */
+const service_context_access_t m_service_context_store[DM_SERVICE_CONTEXT_COUNT] =
+{
+    no_service_context_store, /**< Dummy function, when there is no service context registered. */
+    gatts_context_store,      /**< GATT Server context store function. */
+    gattc_context_store,      /**< GATT Client context store function. */
+    gattsc_context_store      /**< GATT Server & Client context store function. */
+};
+
+
+/**< Array of function pointers based on the types of service registered. */
+const service_context_access_t m_service_context_load[DM_SERVICE_CONTEXT_COUNT] =
+{
+    no_service_context_load,  /**< Dummy function, when there is no service context registered. */
+    gatts_context_load,       /**< GATT Server context load function. */
+    gattc_context_load,       /**< GATT Client context load function. */
+    gattsc_context_load       /**< GATT Server & Client context load function. */
+};
+
+
+/**< Array of function pointers based on the types of service registered. */
+const service_context_apply_t m_service_context_apply[DM_SERVICE_CONTEXT_COUNT] =
+{
+    no_service_context_apply, /**< Dummy function, when there is no service context registered. */
+    gatts_context_apply,      /**< GATT Server context apply function. */
+    gattc_context_apply,      /**< GATT Client context apply function. */
+    gattsc_context_apply      /**< GATT Server & Client context apply function. */
+};
+
+
+const uint32_t m_context_init_len = 0xFFFFFFFF; /**< Constant used to update the initial value for context in the flash. */
+
+/**@brief Function for setting update status for the device identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ */
+static __INLINE void update_status_bit_set(uint32_t index)
+{
+    m_peer_addr_update |= (BIT_0 << index);
+}
+
+
+/**@brief Function for resetting update status for device identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ */
+static __INLINE void update_status_bit_reset(uint32_t index)
+{
+    m_peer_addr_update &= (~((uint32_t)BIT_0 << index));
+}
+
+
+/**@brief Function for providing update status for the device identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ *
+ * @retval true if the bit is set, false otherwise.
+ */
+static __INLINE bool update_status_bit_is_set(uint32_t index)
+{
+    return ((m_peer_addr_update & (BIT_0 << index)) ? true : false);
+}
+
+
+/**@brief Function for initialiasing the application instance identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ */
+static __INLINE void application_instance_init(uint32_t index)
+{
+    DM_TRC("[DM]: Initializing Application Instance 0x%08X.\r\n", index);
+
+    m_application_table[index].ntf_cb  = NULL;
+    m_application_table[index].state   = 0x00;
+    m_application_table[index].service = 0x00;
+}
+
+
+/**@brief Function for initialiasing the connection instance identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ */
+static __INLINE void connection_instance_init(uint32_t index)
+{
+    DM_TRC("[DM]: Initializing Connection Instance 0x%08X.\r\n", index);
+
+    m_connection_table[index].state         = STATE_IDLE;
+    m_connection_table[index].conn_handle   = BLE_CONN_HANDLE_INVALID;
+    m_connection_table[index].bonded_dev_id = DM_INVALID_ID;
+
+    memset(&m_connection_table[index].peer_addr, 0, sizeof (ble_gap_addr_t));
+}
+
+
+/**@brief Function for initialiasing the peer device instance identified by 'index'.
+ *
+ * @param[in] index Device identifier.
+ */
+static __INLINE void peer_instance_init(uint32_t index)
+{
+    DM_TRC("[DM]: Initializing Peer Instance 0x%08X.\r\n", index);
+
+    memset(m_peer_table[index].peer_id.id_addr_info.addr, 0, BLE_GAP_ADDR_LEN);
+    memset(m_peer_table[index].peer_id.id_info.irk, 0, BLE_GAP_SEC_KEY_LEN);
+
+    //Initialize the address type to invalid.
+    m_peer_table[index].peer_id.id_addr_info.addr_type = INVALID_ADDR_TYPE;
+
+    //Initialize the identification bit map to unassigned.
+    m_peer_table[index].id_bitmap = UNASSIGNED;
+
+    // Initialize diversifier.
+    m_peer_table[index].ediv      = EDIV_INIT_VAL;
+
+
+    //Reset the status bit.
+    update_status_bit_reset(index);
+
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+    //Initialize the application context for bond device.
+    m_app_context_table[index] = NULL;
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+}
+
+
+/**@brief Function for searching connection instance matching the connection handle and the state
+ *        requested.
+ *
+ * @details Connection handle and state information is used to get a connection instance, it
+ *          is possible to ignore the connection handle by using BLE_CONN_HANDLE_INVALID.
+ *
+ * @param[in]  conn_handle Connection handle.
+ * @param[in]  state       Connection instance state.
+ * @param[out] p_instance  Connection instance.
+ *
+ * @retval NRF_SUCCESS             Operation success.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Invalid state
+ * @retval NRF_ERROR_NOT_FOUND     Operation failure. Not found
+ */
+static ret_code_t connection_instance_find(uint16_t   conn_handle,
+                                           uint8_t    state,
+                                           uint32_t * p_instance)
+{
+    ret_code_t err_code;
+    uint32_t   index;
+
+    err_code = NRF_ERROR_INVALID_STATE;
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
+    {
+        //Search only based on the state.
+        if (state & m_connection_table[index].state)
+        {
+            //Ignore the connection handle.
+            if ((conn_handle == BLE_CONN_HANDLE_INVALID) ||
+                (conn_handle == m_connection_table[index].conn_handle))
+            {
+                //Search for matching connection handle.
+                (*p_instance) = index;
+                err_code      = NRF_SUCCESS;
+
+                break;
+            }
+            else
+            {
+                err_code = NRF_ERROR_NOT_FOUND;
+            }
+        }
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for allocating device instance for a bonded device.
+ *
+ * @param[out] p_device_index Device index.
+ * @param[in]  p_addr         Peer identification information.
+ *
+ * @retval NRF_SUCCESS            Operation success.
+ * @retval DM_DEVICE_CONTEXT_FULL Operation failure.
+ */
+static __INLINE ret_code_t device_instance_allocate(uint8_t *              p_device_index,
+                                                    ble_gap_addr_t const * p_addr)
+{
+    ret_code_t err_code;
+    uint32_t   index;
+
+    err_code = DM_DEVICE_CONTEXT_FULL;
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
+               index, m_peer_table[index].peer_id.id_addr_info.addr_type);
+        DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
+               m_peer_table[index].peer_id.id_addr_info.addr[0],
+               m_peer_table[index].peer_id.id_addr_info.addr[1],
+               m_peer_table[index].peer_id.id_addr_info.addr[2],
+               m_peer_table[index].peer_id.id_addr_info.addr[3],
+               m_peer_table[index].peer_id.id_addr_info.addr[4],
+               m_peer_table[index].peer_id.id_addr_info.addr[5]);
+
+        if (m_peer_table[index].id_bitmap == UNASSIGNED)
+        {
+            if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+            {
+                m_peer_table[index].id_bitmap            &= (~ADDR_ENTRY);
+                m_peer_table[index].peer_id.id_addr_info  = (*p_addr);
+            }
+            else
+            {
+                m_peer_table[index].id_bitmap &= (~IRK_ENTRY);
+            }
+
+            (*p_device_index) = index;
+            err_code          = NRF_SUCCESS;
+
+            DM_LOG("[DM]: Allocated device instance 0x%02X\r\n", index);
+
+            break;
+        }
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for freeing a device instance allocated for bonded device.
+ *
+ * @param[in] device_index Device index.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ */
+static __INLINE ret_code_t device_instance_free(uint32_t device_index)
+{
+    ret_code_t        err_code;
+    pstorage_handle_t block_handle;
+
+    //Get the block handle.
+    err_code = pstorage_block_identifier_get(&m_storage_handle, device_index, &block_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        DM_TRC("[DM]:[DI 0x%02X]: Freeing Instance.\r\n", device_index);
+
+        //Request clearing of the block.
+        err_code = pstorage_clear(&block_handle, ALL_CONTEXT_SIZE);
+
+        if (err_code == NRF_SUCCESS)
+        {
+            peer_instance_init(device_index);
+        }
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for searching for the device in the bonded device list.
+ *
+ * @param[in]  p_addr         Peer identification information.
+ * @param[out] p_device_index Device index.
+ *
+ * @retval NRF_SUCCESS         Operation success.
+ * @retval NRF_ERROR_NOT_FOUND Operation failure.
+ */
+static ret_code_t device_instance_find(ble_gap_addr_t const * p_addr, uint32_t * p_device_index, uint16_t ediv)
+{
+    ret_code_t err_code;
+    uint32_t   index;
+
+    err_code = NRF_ERROR_NOT_FOUND;
+
+    if (NULL != p_addr)
+    {
+        DM_LOG("[DM]: Searching for device 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
+               p_addr->addr[0],
+               p_addr->addr[1],
+               p_addr->addr[2],
+               p_addr->addr[3],
+               p_addr->addr[4],
+               p_addr->addr[5]);
+    }
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
+               index, m_peer_table[index].peer_id.id_addr_info.addr_type);
+        DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
+               m_peer_table[index].peer_id.id_addr_info.addr[0],
+               m_peer_table[index].peer_id.id_addr_info.addr[1],
+               m_peer_table[index].peer_id.id_addr_info.addr[2],
+               m_peer_table[index].peer_id.id_addr_info.addr[3],
+               m_peer_table[index].peer_id.id_addr_info.addr[4],
+               m_peer_table[index].peer_id.id_addr_info.addr[5]);
+
+        if (((NULL == p_addr) && (ediv == m_peer_table[index].ediv)) ||
+            ((NULL != p_addr) && (memcmp(&m_peer_table[index].peer_id.id_addr_info, p_addr, sizeof(ble_gap_addr_t)) == 0)))
+        {
+            DM_LOG("[DM]: Found device at instance 0x%02X\r\n", index);
+
+            (*p_device_index) = index;
+            err_code          = NRF_SUCCESS;
+
+            break;
+        }
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for notifying connection manager event to the application.
+ *
+ * @param[in] p_handle     Device handle identifying device.
+ * @param[in] p_event      Connection manager event details.
+ * @param[in] event_result Event result code.
+ */
+static __INLINE void app_evt_notify(dm_handle_t const * const p_handle,
+                                    dm_event_t const * const  p_event,
+                                    uint32_t                  event_result)
+{
+    dm_event_cb_t app_cb = m_application_table[0].ntf_cb;
+
+    DM_MUTEX_UNLOCK();
+
+    DM_TRC("[DM]: Notifying application of event 0x%02X\r\n", p_event->event_id);
+
+    //No need to do any kind of return value processing thus can be supressed.
+    UNUSED_VARIABLE(app_cb(p_handle, p_event, event_result));
+
+    DM_MUTEX_LOCK();
+}
+
+
+/**@brief Function for allocating instance.
+ *
+ * @details The instance identifier is provided in the 'p_instance' parameter if the routine
+ *          succeeds.
+ *
+ * @param[out] p_instance Connection instance.
+ *
+ * @retval NRF_SUCCESS      Operation success.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No memory.
+ */
+static __INLINE uint32_t connection_instance_allocate(uint32_t * p_instance)
+{
+    uint32_t err_code;
+
+    DM_LOG("[DM]: Request to allocation connection instance\r\n");
+
+    err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, STATE_IDLE, p_instance);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        DM_LOG("[DM]:[%02X]: Connection Instance Allocated.\r\n", (*p_instance));
+        m_connection_table[*p_instance].state = STATE_CONNECTED;
+    }
+    else
+    {
+        DM_LOG("[DM]: No free connection instances available\r\n");
+        err_code = NRF_ERROR_NO_MEM;
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for freeing instance. Instance identifier is provided in the parameter
+ *        'p_instance' in case the routine succeeds.
+ *
+ * @param[in] p_instance Connection instance.
+ */
+static __INLINE void connection_instance_free(uint32_t const * p_instance)
+{
+    DM_LOG("[DM]:[CI 0x%02X]: Freeing connection instance\r\n", (*p_instance));
+
+    if (m_connection_table[*p_instance].state != STATE_IDLE)
+    {
+        DM_LOG("[DM]:[%02X]: Freed connection instance.\r\n", (*p_instance));
+        connection_instance_init(*p_instance);
+    }
+}
+
+
+/**@brief Function for storage operation dummy handler.
+ *
+ * @param[in] p_dest Destination address where data is to be stored persistently.
+ * @param[in] p_src  Source address containing data to be stored. API assumes this to be resident
+ *                   memory and no intermediate copy of data is made by the API.
+ * @param[in] size   Size of data to be stored expressed in bytes. Should be word aligned.
+ * @param[in] offset Offset in bytes to be applied when writing to the block.
+ *                   For example, if within a block of 100 bytes, application wishes to
+ *                   write 20 bytes at offset of 12, then this field should be set to 12.
+ *                   Should be word aligned.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+static uint32_t storage_operation_dummy_handler(pstorage_handle_t * p_dest,
+                                                uint8_t           * p_src,
+                                                pstorage_size_t     size,
+                                                pstorage_size_t     offset)
+{
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for saving the device context persistently.
+ *
+ * @param[in] p_handle Device handle identifying device.
+ * @param[in] state    Device store state.
+ */
+static __INLINE void device_context_store(dm_handle_t const * p_handle, device_store_state_t state)
+{
+    pstorage_handle_t block_handle;
+    storage_operation store_fn;
+    ret_code_t        err_code;
+
+    DM_LOG("[DM]: --> device_context_store\r\n");
+
+    err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                             p_handle->device_id,
+                                             &block_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        if ((STATE_BOND_INFO_UPDATE ==
+             (m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)) ||
+            (state == UPDATE_PEER_ADDR))
+        {
+            DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Updating bonding information.\r\n",
+                   p_handle->device_id, p_handle->connection_id);
+
+            store_fn = pstorage_update;
+        }
+        else if (state == FIRST_BOND_STORE)
+        {
+            DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Storing bonding information.\r\n",
+                   p_handle->device_id, p_handle->connection_id);
+
+            store_fn = pstorage_store;
+        }
+        else
+        {
+            DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> No update in bonding information.\r\n",
+                   p_handle->device_id, p_handle->connection_id);
+
+            //No operation needed.
+            store_fn = storage_operation_dummy_handler;
+        }
+
+        //Store the peer id.
+        err_code = store_fn(&block_handle,
+                            (uint8_t *)&m_peer_table[p_handle->device_id],
+                            PEER_ID_SIZE,
+                            PEER_ID_STORAGE_OFFSET);
+
+        if ((err_code == NRF_SUCCESS) && (state != UPDATE_PEER_ADDR))
+        {
+            m_connection_table[p_handle->connection_id].state &= (~STATE_BOND_INFO_UPDATE);
+
+            //Store the bond information.
+            err_code = store_fn(&block_handle,
+                                (uint8_t *)&m_bond_table[p_handle->connection_id],
+                                BOND_SIZE,
+                                BOND_STORAGE_OFFSET);
+
+            if (err_code != NRF_SUCCESS)
+            {
+                DM_ERR("[DM]:[0x%02X]:Failed to store bond information, reason 0x%08X\r\n",
+                       p_handle->device_id, err_code);
+            }
+        }
+
+        if (state != UPDATE_PEER_ADDR)
+        {
+            //Store the service information
+            err_code = m_service_context_store[m_application_table[p_handle->appl_id].service]
+                    (
+                        &block_handle,
+                        p_handle
+                    );
+
+            if (err_code != NRF_SUCCESS)
+            {
+                //Notify application of an error event.
+                DM_ERR("[DM]: Failed to store service context, reason %08X\r\n", err_code);
+            }
+        }
+    }
+
+    if (err_code != NRF_SUCCESS)
+    {
+        //Notify application of an error event.
+        DM_ERR("[DM]: Failed to store device context, reason %08X\r\n", err_code);
+    }
+}
+
+
+/**@brief Function for storing when there is no service registered.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is loaded.
+ *
+ * @retval NRF_SUCCESS
+ */
+static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle,
+                                                    dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> no_service_context_store\r\n");
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for storing GATT Server context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is stored.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle)
+{
+    storage_operation store_fn;
+    uint32_t          attr_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS;
+    uint16_t          attr_len   = DM_GATT_SERVER_ATTR_MAX_SIZE;
+    uint8_t           sys_data[DM_GATT_SERVER_ATTR_MAX_SIZE];
+
+    DM_LOG("[DM]: --> gatts_context_store\r\n");
+
+    uint32_t err_code = sd_ble_gatts_sys_attr_get(
+        m_connection_table[p_handle->connection_id].conn_handle,
+        sys_data,
+        &attr_len,
+        attr_flags);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        if (memcmp(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len) == 0)
+        {
+            //No store operation is needed.
+            DM_LOG("[DM]:[0x%02X]: No change in GATTS Context information.\r\n",
+                   p_handle->device_id);
+
+            if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) !=
+                STATE_CONNECTED)
+            {
+                DM_LOG("[DM]:[0x%02X]: Resetting GATTS for active instance.\r\n",
+                       p_handle->connection_id);
+
+                //Reset GATTS information for the current context.
+                memset(&m_gatts_table[p_handle->connection_id], 0, sizeof(dm_gatts_context_t));
+            }
+        }
+        else
+        {
+            if (m_gatts_table[p_handle->connection_id].size != 0)
+            {
+                //There is data already stored in persistent memory, therefore an update is needed.
+                DM_LOG("[DM]:[0x%02X]: Updating stored service context\r\n", p_handle->device_id);
+
+                store_fn = pstorage_update;
+            }
+            else
+            {
+                //Fresh write, a store is needed.
+                DM_LOG("[DM]:[0x%02X]: Storing service context\r\n", p_handle->device_id);
+
+                store_fn = pstorage_store;
+            }
+
+            m_gatts_table[p_handle->connection_id].flags = attr_flags;
+            m_gatts_table[p_handle->connection_id].size  = attr_len;
+            memcpy(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len);
+
+            DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
+
+            DM_LOG("[DM]:[0x%02X]: GATTS Data size 0x%08X\r\n",
+                   p_handle->device_id,
+                   m_gatts_table[p_handle->connection_id].size);
+
+            //Store GATTS information.
+            err_code = store_fn((pstorage_handle_t *)p_block_handle,
+                                (uint8_t *)&m_gatts_table[p_handle->connection_id],
+                                GATTS_SERVICE_CONTEXT_SIZE,
+                                SERVICE_STORAGE_OFFSET);
+
+            if (err_code != NRF_SUCCESS)
+            {
+                DM_ERR("[DM]:[0x%02X]:Failed to store service context, reason 0x%08X\r\n",
+                       p_handle->device_id,
+                       err_code);
+            }
+            else
+            {
+                DM_LOG("[DM]: Service context successfully stored.\r\n");
+            }
+        }
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for storing GATT Client context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is stored.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> gattc_context_store\r\n");
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for storing GATT Server & Client context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is stored.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ */
+static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle,
+                                                dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> gattsc_context_store\r\n");
+
+    ret_code_t err_code = gatts_context_store(p_block_handle, p_handle);
+
+    if (NRF_SUCCESS == err_code)
+    {
+        err_code = gattc_context_store(p_block_handle, p_handle);
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for loading when there is no service registered.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is loaded.
+ *
+ * @retval NRF_SUCCESS
+ */
+static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle,
+                                                   dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> no_service_context_load\r\n");
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for loading GATT Server context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is loaded.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ */
+static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle,
+                                              dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: --> gatts_context_load\r\n",
+           p_handle->connection_id,
+           p_handle->device_id);
+
+    ret_code_t err_code = pstorage_load((uint8_t *)&m_gatts_table[p_handle->connection_id],
+                                        (pstorage_handle_t *)p_block_handle,
+                                        GATTS_SERVICE_CONTEXT_SIZE,
+                                        SERVICE_STORAGE_OFFSET);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]: Service context loaded, size 0x%08X\r\n",
+               p_handle->connection_id,
+               p_block_handle->block_id,
+               m_gatts_table[p_handle->connection_id].size);
+        DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t));
+
+        if (m_gatts_table[p_handle->connection_id].size == DM_GATTS_INVALID_SIZE)
+        {
+            m_gatts_table[p_handle->connection_id].size = 0;
+        }
+    }
+    else
+    {
+        DM_ERR("[DM]:[%02X]: Failed to load Service context, reason %08X\r\n",
+               p_handle->connection_id,
+               err_code);
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for loading GATT Client context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is loaded.
+ *
+ * @retval NRF_SUCCESS
+ */
+static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle,
+                                              dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> gattc_context_load\r\n");
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for loading GATT Server & Client context.
+ *
+ * @param[in] p_block_handle Storage block identifier.
+ * @param[in] p_handle       Device handle identifying device that is loaded.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ */
+static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle,
+                                               dm_handle_t const       * p_handle)
+{
+    DM_LOG("[DM]: --> gattsc_context_load\r\n");
+
+    ret_code_t err_code = gatts_context_load(p_block_handle, p_handle);
+
+    if (NRF_SUCCESS == err_code)
+    {
+        err_code = gattc_context_load(p_block_handle, p_handle);
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for applying when there is no service registered.
+ *
+ * @param[in] p_handle Device handle identifying device that is applied.
+ *
+ * @retval NRF_SUCCESS
+ */
+static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle)
+{
+    DM_LOG("[DM]: --> no_service_context_apply\r\n");
+    DM_LOG("[DM]:[CI 0x%02X]: No Service context\r\n", p_handle->connection_id);
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for applying GATT Server context.
+ *
+ * @param[in] p_handle Device handle identifying device that is applied.
+ *
+ * @retval NRF_SUCCESS                    On success.
+ * @retval DM_SERVICE_CONTEXT_NOT_APPLIED On failure.
+ */
+static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle)
+{
+    uint32_t err_code;
+
+    uint8_t * p_gatts_context = NULL;
+    uint16_t  context_len     = 0;
+    uint32_t  context_flags   = 0;
+
+    DM_LOG("[DM]: --> gatts_context_apply\r\n");
+    DM_LOG("[DM]:[CI 0x%02X]: State 0x%02X, Size 0x%08X\r\n",
+           p_handle->connection_id,
+           m_connection_table[p_handle->connection_id].state,
+           m_gatts_table[p_handle->connection_id].size);
+
+    if ((m_gatts_table[p_handle->connection_id].size != 0) &&
+        (
+            ((m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) &&
+            ((m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)
+             != STATE_BOND_INFO_UPDATE)
+        )
+       )
+    {
+        DM_LOG("[DM]: Setting stored context.\r\n");
+
+        p_gatts_context = &m_gatts_table[p_handle->connection_id].attributes[0];
+        context_len     = m_gatts_table[p_handle->connection_id].size;
+        context_flags   = m_gatts_table[p_handle->connection_id].flags;
+    }
+
+    err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
+                                         p_gatts_context,
+                                         context_len,
+                                         context_flags);
+
+    if (err_code == NRF_ERROR_INVALID_DATA)
+    {
+        // Indication that the ATT table has changed. Restore the system attributes to system
+        // services only and send a service changed indication if possible.
+        context_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS;
+        err_code      = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle,
+                                                  p_gatts_context,
+                                                  context_len,
+                                                  context_flags);
+    }
+
+    if (err_code != NRF_SUCCESS)
+    {
+        DM_LOG("[DM]: Failed to set system attributes, reason 0x%08X.\r\n", err_code);
+
+        err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
+    }
+
+    if (context_flags == BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS)
+    {
+        err_code = sd_ble_gatts_service_changed(m_connection_table[p_handle->connection_id].conn_handle,
+                                                0x000C,
+                                                0xFFFF);
+        if (err_code != NRF_SUCCESS)
+        {
+            DM_LOG("[DM]: Failed to send Service Changed indication, reason 0x%08X.\r\n", err_code);
+            if ((err_code != BLE_ERROR_INVALID_CONN_HANDLE) &&
+                (err_code != NRF_ERROR_INVALID_STATE) &&
+                (err_code != BLE_ERROR_NO_TX_BUFFERS) &&
+                (err_code != NRF_ERROR_BUSY))
+            {
+                // Those errors can be expected when sending trying to send Service Changed
+                // Indication if the CCCD is not set to indicate. Thus set the returning error
+                //  code to success.
+                err_code = NRF_SUCCESS;
+            }
+            else
+            {
+                err_code = DM_SERVICE_CONTEXT_NOT_APPLIED;
+            }
+        }
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for applying GATT Client context.
+ *
+ * @param[in] p_handle Device handle identifying device that is applied.
+ *
+ * @retval NRF_SUCCESS On success.
+ */
+static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle)
+{
+    DM_LOG("[DM]: --> gattc_context_apply\r\n");
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for applying GATT Server & Client context.
+ *
+ * @param[in] p_handle Device handle identifying device that is applied.
+ *
+ * @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
+ */
+static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle)
+{
+    uint32_t err_code;
+
+    DM_LOG("[DM]: --> gattsc_context_apply\r\n");
+
+    err_code = gatts_context_apply(p_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = gattc_context_apply(p_handle);
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for pstorage module callback.
+ *
+ * @param[in] p_handle Identifies module and block for which callback is received.
+ * @param[in] op_code  Identifies the operation for which the event is notified.
+ * @param[in] result   Identifies the result of flash access operation.
+ *                     NRF_SUCCESS implies, operation succeeded.
+ * @param[in] p_data   Identifies the application data pointer. In case of store operation, this
+ *                     points to the resident source of application memory that application can now
+ *                     free or reuse. In case of clear, this is NULL as no application pointer is
+ *                     needed for this operation.
+ * @param[in] data_len Length of data provided by the application for the operation.
+ */
+static void dm_pstorage_cb_handler(pstorage_handle_t * p_handle,
+                                   uint8_t             op_code,
+                                   uint32_t            result,
+                                   uint8_t           * p_data,
+                                   uint32_t            data_len)
+{
+    VERIFY_APP_REGISTERED_VOID(0);
+
+    if (data_len > ALL_CONTEXT_SIZE)
+    {
+        //Clearing of all bonds at initialization, no event is generated.
+        return;
+    }
+
+    DM_MUTEX_LOCK();
+
+    dm_event_t        dm_event;
+    dm_handle_t       dm_handle;
+    dm_context_t      context_data;
+    pstorage_handle_t block_handle;
+    uint32_t          index_count;
+    uint32_t          err_code;
+
+    bool app_notify = true;
+
+    err_code = dm_handle_initialize(&dm_handle);
+    APP_ERROR_CHECK(err_code);
+
+    dm_handle.appl_id = 0;
+    dm_event.event_id = 0x00;
+
+    //Construct the event which it is related to.
+
+    //Initialize context data information and length.
+    context_data.p_data = p_data;
+    context_data.len    = data_len;
+
+    for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
+        if ((err_code == NRF_SUCCESS) &&
+            (
+                (memcmp(p_handle, &block_handle, sizeof(pstorage_handle_t)) == 0)
+            )
+           )
+        {
+            dm_handle.device_id = index;
+            break;
+        }
+    }
+
+    if (dm_handle.device_id != DM_INVALID_ID)
+    {
+        if (op_code == PSTORAGE_CLEAR_OP_CODE)
+        {
+            if (data_len == ALL_CONTEXT_SIZE)
+            {
+                dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
+            }
+            else
+            {
+                dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
+            }
+        }
+        else
+        {
+            //Update or store operation.
+            //Context is identified based on the pointer value. Device context, application context
+            //and service context all have their own value range.
+            index_count = ((uint32_t)(p_data - (uint8_t *)m_peer_table)) / PEER_ID_SIZE;
+
+            if (index_count < DEVICE_MANAGER_MAX_BONDS)
+            {
+                dm_event.event_param.p_device_context = &context_data;
+
+                //Only the peer identification is stored, not bond information. Hence do not notify
+                //the application yet, unless the store operation resulted in a failure.
+                if ((result == NRF_SUCCESS) &&
+                    (
+                        (update_status_bit_is_set(dm_handle.device_id) == false)
+                    )
+                   )
+                {
+                    app_notify = false;
+                }
+                else
+                {
+                    //Reset update status since update is complete.
+                    update_status_bit_reset(dm_handle.device_id);
+
+                    //Notify application of error in storing the context.
+                    dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE;
+                }
+            }
+            else
+            {
+                index_count = ((uint32_t)(p_data - (uint8_t *)m_bond_table)) / BOND_SIZE;
+
+                if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
+                {
+                    DM_LOG("[DM]:[0x%02X]:[0x%02X]: Bond context Event\r\n",
+                           dm_handle.device_id,
+                           dm_handle.connection_id);
+
+                    dm_event.event_param.p_device_context = &context_data;
+                    dm_event.event_id                     = DM_EVT_DEVICE_CONTEXT_BASE;
+                    dm_handle.connection_id               = index_count;
+
+                    ble_gap_sec_keyset_t keys_exchanged;
+                    keys_exchanged.keys_central.p_enc_key = NULL;
+                    keys_exchanged.keys_central.p_id_key  = &m_local_id_info;
+                    keys_exchanged.keys_periph.p_enc_key  = &m_bond_table[index_count].peer_enc_key;
+                    keys_exchanged.keys_periph.p_id_key   =
+                        &m_peer_table[dm_handle.device_id].peer_id;
+
+                    //Context information updated to provide the keys.
+                    context_data.p_data = (uint8_t *)&keys_exchanged;
+                    context_data.len    = sizeof(ble_gap_sec_keyset_t);
+                }
+                else
+                {
+                    index_count = ((uint32_t)(p_data - (uint8_t *)m_gatts_table)) /
+                                  GATTS_SERVICE_CONTEXT_SIZE;
+
+                    if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS)
+                    {
+                        DM_LOG("[DM]:[0x%02X]:[0x%02X]: Service context Event\r\n",
+                               dm_handle.device_id,
+                               dm_handle.connection_id);
+
+                        //Notify application.
+                        dm_event.event_id       = DM_EVT_SERVICE_CONTEXT_BASE;
+                        dm_handle.connection_id = index_count;
+                        dm_handle.service_id    = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;
+
+                        //Reset the service context now that it was successfully written to the
+                        //application and the link is disconnected.
+                        if ((m_connection_table[index_count].state & STATE_CONNECTED) !=
+                            STATE_CONNECTED)
+                        {
+                            DM_LOG("[DM]:[0x%02X]:[0x%02X]: Resetting bond information for "
+                                   "active instance.\r\n",
+                                   dm_handle.device_id,
+                                   dm_handle.connection_id);
+
+                            memset(&m_gatts_table[dm_handle.connection_id],
+                                   0,
+                                   sizeof(dm_gatts_context_t));
+                        }
+                    }
+                    else
+                    {
+                        DM_LOG("[DM]:[0x%02X]:[0x%02X]: App context Event\r\n",
+                               dm_handle.device_id,
+                               dm_handle.connection_id);
+
+                        app_notify        = false;
+                        dm_event.event_id = DM_EVT_APP_CONTEXT_BASE;
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+
+                        if (p_data == (uint8_t *)(&m_context_init_len))
+                        {
+                            //Context data is deleted.
+                            //This is a workaround to get the right event as on delete operation
+                            //update operation is used instead of clear.
+                            op_code    = PSTORAGE_CLEAR_OP_CODE;
+                            app_notify = true;
+                        }
+                        else if (m_app_context_table[dm_handle.device_id] == p_data)
+                        {
+                            app_notify                         = true;
+                            dm_event.event_param.p_app_context = &context_data;
+
+                            //Verify if the device is connected, if yes set connection instance.
+                            for (uint32_t index = 0;
+                                 index < DEVICE_MANAGER_MAX_CONNECTIONS;
+                                 index++)
+                            {
+                                if (dm_handle.device_id == m_connection_table[index].bonded_dev_id)
+                                {
+                                    dm_handle.connection_id = index;
+                                    break;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            //No implementation needed.
+                        }
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+                    }
+                }
+            }
+        }
+
+        if (app_notify == true)
+        {
+            if (op_code == PSTORAGE_CLEAR_OP_CODE)
+            {
+                dm_event.event_id |= DM_CLEAR_OPERATION_ID;
+            }
+            else if (op_code == PSTORAGE_LOAD_OP_CODE)
+            {
+                dm_event.event_id |= DM_LOAD_OPERATION_ID;
+            }
+            else
+            {
+                dm_event.event_id |= DM_STORE_OPERATION_ID;
+            }
+
+            dm_event.event_param.p_app_context = &context_data;
+            app_evt_notify(&dm_handle, &dm_event, result);
+        }
+    }
+
+    DM_MUTEX_UNLOCK();
+}
+
+
+ret_code_t dm_init(dm_init_param_t const * const p_init_param)
+{
+    pstorage_module_param_t param;
+    pstorage_handle_t       block_handle;
+    ret_code_t              err_code;
+    uint32_t                index;
+
+    DM_LOG("[DM]: >> dm_init.\r\n");
+
+    NULL_PARAM_CHECK(p_init_param);
+
+    SDK_MUTEX_INIT(m_dm_mutex);
+
+    DM_MUTEX_LOCK();
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++)
+    {
+        application_instance_init(index);
+    }
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
+    {
+        connection_instance_init(index);
+    }
+
+    memset(m_gatts_table, 0, sizeof(m_gatts_table));
+
+    //Initialization of all device instances.
+    for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        peer_instance_init(index);
+        m_irk_index_table[index] = DM_INVALID_ID;
+    }
+
+    //All context with respect to a particular device is stored contiguously.
+    param.block_size  = ALL_CONTEXT_SIZE;
+    param.block_count = DEVICE_MANAGER_MAX_BONDS;
+    param.cb          = dm_pstorage_cb_handler;
+
+    err_code = pstorage_register(&param, &m_storage_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        m_module_initialized = true;
+
+        if (p_init_param->clear_persistent_data == false)
+        {
+            DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id);
+
+            //Copy bonded peer device address and IRK to RAM table.
+
+            //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining
+            //range is for active connections that may or may not be bonded.
+            for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+            {
+                err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle);
+
+                //Issue read request if you successfully get the block identifier.
+                if (err_code == NRF_SUCCESS)
+                {
+                    DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id);
+
+                    err_code = pstorage_load((uint8_t *)&m_peer_table[index],
+                                             &block_handle,
+                                             sizeof(peer_id_t),
+                                             0);
+
+                    if (err_code != NRF_SUCCESS)
+                    {
+                        // In case a peer device could not be loaded successfully, rest of the
+                        // initialization procedure are skipped and an error is sent to the
+                        // application.
+                        DM_LOG(
+                            "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n",
+                            index,
+                            err_code);
+
+
+
+                        m_module_initialized = false;
+                        break;
+                    }
+                    else
+                    {
+                        DM_LOG("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n",
+                               index,
+                               m_peer_table[index].peer_id.id_addr_info.addr_type);
+                        DM_LOG("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n",
+                               m_peer_table[index].peer_id.id_addr_info.addr[0],
+                               m_peer_table[index].peer_id.id_addr_info.addr[1],
+                               m_peer_table[index].peer_id.id_addr_info.addr[2],
+                               m_peer_table[index].peer_id.id_addr_info.addr[3],
+                               m_peer_table[index].peer_id.id_addr_info.addr[4],
+                               m_peer_table[index].peer_id.id_addr_info.addr[5]);
+                    }
+                }
+                else
+                {
+                    //In case a peer device could not be loaded successfully, rest of the
+                    //initialization procedure are skipped and an error is sent to the application.
+                    DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n",
+                           index,
+                           err_code);
+
+                    m_module_initialized = false;
+                    break;
+                }
+            }
+        }
+        else
+        {
+            err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count));
+            DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n");
+        }
+    }
+    else
+    {
+        DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code);
+    }
+
+    DM_MUTEX_UNLOCK();
+
+    DM_TRC("[DM]: << dm_init.\r\n");
+
+    return err_code;
+}
+
+
+ret_code_t dm_register(dm_application_instance_t    * p_appl_instance,
+                       dm_application_param_t const * p_appl_param)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_appl_instance);
+    NULL_PARAM_CHECK(p_appl_param);
+    NULL_PARAM_CHECK(p_appl_param->evt_handler);
+
+    DM_MUTEX_LOCK();
+
+    DM_LOG("[DM]: >> dm_register.\r\n");
+
+    uint32_t err_code;
+
+    //Verify if an application instance is available. Currently only one instance is supported.
+    if (m_application_table[0].ntf_cb == NULL)
+    {
+        DM_LOG("[DM]: Application Instance allocated.\r\n");
+
+        //Mark instance as allocated.
+        m_application_table[0].ntf_cb    = p_appl_param->evt_handler;
+        m_application_table[0].sec_param = p_appl_param->sec_param;
+        m_application_table[0].service   = p_appl_param->service_type;
+
+        m_application_table[0].sec_param.kdist_central.enc  = 0;
+        m_application_table[0].sec_param.kdist_central.id   = 1;
+        m_application_table[0].sec_param.kdist_central.sign = 0;
+        m_application_table[0].sec_param.kdist_periph.enc   = 1;
+        m_application_table[0].sec_param.kdist_periph.id    = 1;
+        m_application_table[0].sec_param.kdist_periph.sign  = 0;
+        //Populate application's instance variable with the assigned allocation instance.
+        *p_appl_instance = 0;
+        err_code         = NRF_SUCCESS;
+    }
+    else
+    {
+        err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE);
+    }
+
+    DM_MUTEX_UNLOCK();
+
+    DM_TRC("[DM]: << dm_register.\r\n");
+
+    return err_code;
+}
+
+
+ret_code_t dm_security_setup_req(dm_handle_t * p_handle)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_LOG("[DM]: >> dm_security_setup_req\r\n");
+
+    uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE);
+
+    if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED)
+    {
+        err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle,
+                                           &m_application_table[0].sec_param);
+    }
+
+    DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code);
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_security_status_req(dm_handle_t const    * p_handle,
+                                  dm_security_status_t * p_status)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_status);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_LOG("[DM]: >> dm_security_status_req\r\n");
+
+    if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) ||
+        (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING))
+    {
+        (*p_status) = ENCRYPTION_IN_PROGRESS;
+    }
+    else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED)
+    {
+        (*p_status) = ENCRYPTED;
+    }
+    else
+    {
+        (*p_status) = NOT_ENCRYPTED;
+    }
+
+    DM_TRC("[DM]: << dm_security_status_req\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
+                               ble_gap_whitelist_t             * p_whitelist)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_whitelist);
+    NULL_PARAM_CHECK(p_whitelist->pp_addrs);
+    NULL_PARAM_CHECK(p_whitelist->pp_irks);
+    VERIFY_APP_REGISTERED(*p_handle);
+
+    DM_MUTEX_LOCK();
+
+    DM_LOG("[DM]: >> dm_whitelist_create\r\n");
+
+    uint32_t addr_count = 0;
+    uint32_t irk_count  = 0;
+    bool     connected  = false;
+
+    for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        connected = false;
+
+        for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++)
+        {
+            if ((index == m_connection_table[c_index].bonded_dev_id) &&
+                ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED))
+            {
+                connected = true;
+                break;
+            }
+        }
+
+        if (connected == false)
+        {
+            DM_LOG("irkentry %d addrentry %d", (m_peer_table[index].id_bitmap & IRK_ENTRY), (m_peer_table[index].id_bitmap & ADDR_ENTRY));
+            if ((irk_count < p_whitelist->irk_count) &&
+                ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0) && (m_peer_table[index].id_bitmap & ADDR_ENTRY) != 0)
+            {
+                p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info;
+                m_irk_index_table[irk_count]    = index;
+                irk_count++;
+            }
+
+            if ((addr_count < p_whitelist->addr_count) &&
+                (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0)
+            {
+                p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info;
+                addr_count++;
+            }
+        }
+    }
+
+    p_whitelist->addr_count = addr_count;
+    p_whitelist->irk_count  = irk_count;
+
+    DM_LOG("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n",
+           irk_count,
+           addr_count);
+
+    DM_TRC("[DM]: << dm_whitelist_create\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t dm_device_add(dm_handle_t               * p_handle,
+                         dm_device_context_t const * p_context)
+{
+    return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
+}
+
+
+ret_code_t dm_device_delete(dm_handle_t const * p_handle)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_device_delete\r\n");
+
+    uint32_t err_code = device_instance_free(p_handle->device_id);
+
+    DM_TRC("[DM]: << dm_device_delete\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED((*p_handle));
+
+    DM_MUTEX_LOCK();
+
+    uint32_t err_code = NRF_SUCCESS;
+
+    DM_TRC("[DM]: >> dm_device_delete_all\r\n");
+
+    for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++)
+    {
+        if (m_peer_table[index].id_bitmap != UNASSIGNED)
+        {
+            err_code = device_instance_free(index);
+        }
+    }
+
+    DM_TRC("[DM]: << dm_device_delete_all\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_service_context_set(dm_handle_t const          * p_handle,
+                                  dm_service_context_t const * p_context)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_context);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_CONNECTION_INSTANCE(p_handle->connection_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_service_context_set\r\n");
+
+    if ((p_context->context_data.p_data != NULL) &&
+        (
+            (p_context->context_data.len != 0) &&
+            (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)
+        )
+       )
+    {
+        if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
+        {
+            memcpy(m_gatts_table[p_handle->connection_id].attributes,
+                   p_context->context_data.p_data,
+                   p_context->context_data.len);
+        }
+    }
+
+    pstorage_handle_t block_handle;
+    uint32_t          err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                                               p_handle->device_id,
+                                                               &block_handle);
+
+    err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle);
+
+    DM_TRC("[DM]: << dm_service_context_set\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_service_context_get(dm_handle_t const    * p_handle,
+                                  dm_service_context_t * p_context)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_context);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED)
+    {
+        DM_TRC("[DM]: Device must be connected to get context. \r\n");
+
+        return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
+    }
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_service_context_get\r\n");
+
+    if ((p_context->context_data.p_data == NULL) &&
+        (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE))
+    {
+        if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID)
+        {
+            p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes;
+            p_context->context_data.len    = m_gatts_table[p_handle->connection_id].size;
+        }
+    }
+
+    pstorage_handle_t block_handle;
+    uint32_t          err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                                               p_handle->device_id,
+                                                               &block_handle);
+
+    err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle);
+
+    DM_TRC("[DM]: << dm_service_context_get\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_service_context_delete(dm_handle_t const * p_handle)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_LOG("[DM]: Context delete is not supported yet.\r\n");
+
+    return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE);
+}
+
+
+ret_code_t dm_application_context_set(dm_handle_t const              * p_handle,
+                                      dm_application_context_t const * p_context)
+{
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_context);
+    NULL_PARAM_CHECK(p_context->p_data);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+    VERIFY_DEVICE_BOND(p_handle->connection_id);
+    SIZE_CHECK_APP_CONTEXT(p_context->len);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_application_context_set\r\n");
+
+    uint32_t          err_code;
+    uint32_t          context_len;
+    pstorage_handle_t block_handle;
+
+    storage_operation store_fn = pstorage_store;
+
+    err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                             p_handle->device_id,
+                                             &block_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = pstorage_load((uint8_t *)&context_len,
+                                 &block_handle,
+                                 sizeof(uint32_t),
+                                 APP_CONTEXT_STORAGE_OFFSET);
+
+        if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
+        {
+            //Data already exists. Need an update.
+            store_fn = pstorage_update;
+
+            DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, "
+                   "new length 0x%08X.\r\n",
+                   p_handle->device_id,
+                   context_len,
+                   p_context->len);
+        }
+        else
+        {
+            DM_LOG("[DM]: Storing application context.\r\n");
+        }
+
+        //Store/update context length.
+        err_code = store_fn(&block_handle,
+                            (uint8_t *)(&p_context->len),
+                            sizeof(uint32_t),
+                            APP_CONTEXT_STORAGE_OFFSET);
+
+        if (err_code == NRF_SUCCESS)
+        {
+            //Update context data is used for application context as flash is never
+            //cleared if a delete of application context is called.
+            err_code = pstorage_update(&block_handle,
+                                       p_context->p_data,
+                                       DEVICE_MANAGER_APP_CONTEXT_SIZE,
+                                       (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
+            if (err_code == NRF_SUCCESS)
+            {
+                m_app_context_table[p_handle->device_id] = p_context->p_data;
+            }
+        }
+    }
+
+    DM_TRC("[DM]: << dm_application_context_set\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+
+#else //DEVICE_MANAGER_APP_CONTEXT_SIZE
+    return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+}
+
+
+ret_code_t dm_application_context_get(dm_handle_t const        * p_handle,
+                                      dm_application_context_t * p_context)
+{
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_context);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_application_context_get\r\n");
+
+    uint32_t          context_len;
+    uint32_t          err_code;
+    pstorage_handle_t block_handle;
+
+    //Check if the context exists.
+    if (NULL == p_context->p_data)
+    {
+        p_context->p_data = m_app_context_table[p_handle->device_id];
+    }
+    else
+    {
+        m_app_context_table[p_handle->device_id] = p_context->p_data;
+    }
+
+    err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                             p_handle->device_id,
+                                             &block_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = pstorage_load((uint8_t *)&context_len,
+                                 &block_handle,
+                                 sizeof(uint32_t),
+                                 APP_CONTEXT_STORAGE_OFFSET);
+
+        if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN))
+        {
+            err_code = pstorage_load(p_context->p_data,
+                                     &block_handle,
+                                     DEVICE_MANAGER_APP_CONTEXT_SIZE,
+                                     (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t)));
+            if (err_code == NRF_SUCCESS)
+            {
+                p_context->len = context_len;
+            }
+        }
+        else
+        {
+            err_code = DM_NO_APP_CONTEXT;
+        }
+    }
+
+    DM_TRC("[DM]: << dm_application_context_get\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+
+#else //DEVICE_MANAGER_APP_CONTEXT_SIZE
+    return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+}
+
+
+ret_code_t dm_application_context_delete(const dm_handle_t * p_handle)
+{
+#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0)
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_application_context_delete\r\n");
+
+    uint32_t          err_code;
+    uint32_t          context_len;
+    pstorage_handle_t block_handle;
+
+    err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                             p_handle->device_id,
+                                             &block_handle);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = pstorage_load((uint8_t *)&context_len,
+                                 &block_handle,
+                                 sizeof(uint32_t),
+                                 APP_CONTEXT_STORAGE_OFFSET);
+
+        if (context_len != m_context_init_len)
+        {
+            err_code = pstorage_update(&block_handle,
+                                       (uint8_t *)&m_context_init_len,
+                                       sizeof(uint32_t),
+                                       APP_CONTEXT_STORAGE_OFFSET);
+
+            if (err_code != NRF_SUCCESS)
+            {
+                DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code);
+            }
+            else
+            {
+                m_app_context_table[p_handle->device_id] = NULL;
+            }
+        }
+    }
+
+    DM_TRC("[DM]: << dm_application_context_delete\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+#else //DEVICE_MANAGER_APP_CONTEXT_SIZE
+    return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE);
+#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE
+}
+
+
+ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
+                                       dm_handle_t                     * p_handle)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_appl_instance);
+    VERIFY_APP_REGISTERED((*p_appl_instance));
+
+    p_handle->appl_id = (*p_appl_instance);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t dm_handle_initialize(dm_handle_t * p_handle)
+{
+    NULL_PARAM_CHECK(p_handle);
+
+    p_handle->appl_id       = DM_INVALID_ID;
+    p_handle->connection_id = DM_INVALID_ID;
+    p_handle->device_id     = DM_INVALID_ID;
+    p_handle->service_id    = DM_INVALID_ID;
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t dm_peer_addr_set(dm_handle_t const    * p_handle,
+                            ble_gap_addr_t const * p_addr)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_addr);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_peer_addr_set\r\n");
+
+    ret_code_t err_code;
+
+    if ((p_handle->connection_id == DM_INVALID_ID) &&
+        (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE))
+    {
+        m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr);
+        update_status_bit_set(p_handle->device_id);
+        device_context_store(p_handle, UPDATE_PEER_ADDR);
+        err_code = NRF_SUCCESS;
+    }
+    else
+    {
+        err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE);
+    }
+
+    DM_TRC("[DM]: << dm_peer_addr_set\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
+                            ble_gap_addr_t    * p_addr)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_addr);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_peer_addr_get\r\n");
+
+    ret_code_t err_code;
+
+    err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE);
+
+    if (p_handle->device_id == DM_INVALID_ID)
+    {
+        if ((p_handle->connection_id != DM_INVALID_ID) &&
+            ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) ==
+             STATE_CONNECTED))
+        {
+            DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n",
+                   p_handle->connection_id);
+
+            (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr;
+            err_code  = NRF_SUCCESS;
+        }
+    }
+    else
+    {
+        if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0)
+        {
+            DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n",
+                   p_handle->device_id);
+
+            (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info;
+            err_code  = NRF_SUCCESS;
+        }
+    }
+
+    DM_TRC("[DM]: << dm_peer_addr_get\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
+                                   dm_sec_keyset_t   * p_key_dist)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_handle);
+    NULL_PARAM_CHECK(p_key_dist);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+    VERIFY_DEVICE_INSTANCE(p_handle->device_id);
+
+    DM_MUTEX_LOCK();
+
+    DM_TRC("[DM]: >> dm_distributed_keys_get\r\n");
+
+    ret_code_t        err_code;
+    ble_gap_enc_key_t peer_enc_key;
+    pstorage_handle_t block_handle;
+
+    err_code                                   = NRF_ERROR_NOT_FOUND;
+    p_key_dist->keys_central.enc_key.p_enc_key = NULL;
+    p_key_dist->keys_central.p_id_key          = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
+    p_key_dist->keys_central.p_sign_key        = NULL;
+    p_key_dist->keys_periph.p_id_key           = (dm_id_key_t *)&m_local_id_info;
+    p_key_dist->keys_periph.p_sign_key         = NULL;
+    p_key_dist->keys_periph.enc_key.p_enc_key  = (dm_enc_key_t *)&peer_enc_key;
+
+    if ((m_peer_table[p_handle->device_id].id_bitmap & IRK_ENTRY) == 0)
+    {
+//        p_key_dist->keys_periph.p_id_key->id_addr_info.addr_type = INVALID_ADDR_TYPE;
+    }
+
+    err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle);
+    if (err_code == NRF_SUCCESS)
+    {
+
+        err_code = pstorage_load((uint8_t *)&peer_enc_key,
+                                 &block_handle,
+                                 BOND_SIZE,
+                                 BOND_STORAGE_OFFSET);
+
+        if (err_code == NRF_SUCCESS)
+        {
+            p_key_dist->keys_central.enc_key.p_enc_key = NULL;
+            p_key_dist->keys_central.p_id_key          = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id;
+            p_key_dist->keys_central.p_sign_key        = NULL;
+            p_key_dist->keys_periph.p_id_key           = (dm_id_key_t *)&m_local_id_info;
+            p_key_dist->keys_periph.p_sign_key         = NULL;
+            p_key_dist->keys_periph.enc_key.p_enc_key  = (dm_enc_key_t *)&peer_enc_key;
+        }
+    }
+
+    DM_TRC("[DM]: << dm_distributed_keys_get\r\n");
+
+    DM_MUTEX_UNLOCK();
+
+    return err_code;
+}
+
+
+/**@brief Function for loading bond information for a connection instance.
+ */
+void bond_data_load(dm_handle_t * p_handle)
+{
+    pstorage_handle_t block_handle;
+
+    uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle,
+                                                       p_handle->device_id,
+                                                       &block_handle);
+    if (err_code == NRF_SUCCESS)
+    {
+        DM_LOG(
+            "[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n",
+            p_handle->connection_id,
+            block_handle.block_id,
+            &m_bond_table[p_handle->connection_id],
+            BOND_SIZE,
+            BOND_STORAGE_OFFSET);
+
+        err_code = pstorage_load((uint8_t *)&m_bond_table[p_handle->connection_id],
+                                 &block_handle,
+                                 BOND_SIZE,
+                                 BOND_STORAGE_OFFSET);
+
+        if (err_code != NRF_SUCCESS)
+        {
+            DM_LOG("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n",
+                   p_handle->connection_id,
+                   err_code);
+        }
+
+        DM_LOG(
+            "[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n",
+            p_handle->connection_id,
+            &m_gatts_table[p_handle->connection_id],
+            sizeof(dm_gatts_context_t),
+            SERVICE_STORAGE_OFFSET);
+
+        err_code = m_service_context_load[m_application_table[0].service](
+            &block_handle,
+            p_handle);
+
+        if (err_code != NRF_SUCCESS)
+        {
+            DM_LOG(
+                "[DM]:[%02X]: Failed to load service information, reason %08X\r\n",
+                p_handle->connection_id,
+                err_code);
+        }
+    }
+    else
+    {
+        DM_LOG("[DM]:[%02X]: Failed to get block identifier for "
+               "device %08X, reason %08X.\r\n", p_handle->connection_id, p_handle->device_id, err_code);
+    }
+}
+
+int address_to_device_id(ble_gap_addr_t const * p_addr)
+{
+    for(int peer_iterator = 0; peer_iterator < DEVICE_MANAGER_MAX_BONDS; peer_iterator++)
+    {
+        if(im_address_resolve(p_addr, &m_peer_table[peer_iterator].peer_id.id_info))
+            return peer_iterator;
+    }
+
+    return DM_INVALID_ID;
+}
+
+void dm_ble_evt_handler(ble_evt_t * p_ble_evt)
+{
+    uint32_t    err_code;
+    uint32_t    index;
+    uint32_t    device_index        = DM_INVALID_ID;
+    bool        notify_app          = false;
+    dm_handle_t handle;
+    dm_event_t  event;
+    uint32_t    event_result;
+    ble_gap_enc_info_t * p_enc_info = NULL;
+
+    VERIFY_MODULE_INITIALIZED_VOID();
+    VERIFY_APP_REGISTERED_VOID(0);
+    DM_MUTEX_LOCK();
+
+    err_code = dm_handle_initialize(&handle);
+    APP_ERROR_CHECK(err_code);
+
+    event_result                    = NRF_SUCCESS;
+    err_code                        = NRF_SUCCESS;
+    event.event_param.p_gap_param   = &p_ble_evt->evt.gap_evt;
+    event.event_paramlen            = sizeof(ble_gap_evt_t);
+    handle.device_id                = DM_INVALID_ID;
+    handle.appl_id                  = 0;
+    index                           = 0x00;
+
+    if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
+    {
+        err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle,
+                                            STATE_CONNECTED,
+                                            &index);
+
+        if (err_code == NRF_SUCCESS)
+        {
+            handle.device_id     = m_connection_table[index].bonded_dev_id;
+            handle.connection_id = index;
+        }
+    }
+
+    switch (p_ble_evt->header.evt_id)
+    {
+        case BLE_GAP_EVT_CONNECTED:
+            //Allocate connection instance for a new connection.
+            err_code = connection_instance_allocate(&index);
+
+            //Connection instance is successfully allocated.
+            if (err_code == NRF_SUCCESS)
+            {
+                //Application notification related information.
+                notify_app           = true;
+                event.event_id       = DM_EVT_CONNECTION;
+                handle.connection_id = index;
+
+                m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+                m_connection_table[index].state       = STATE_CONNECTED;
+                m_connection_table[index].peer_addr   =
+                    p_ble_evt->evt.gap_evt.params.connected.peer_addr;
+
+                if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
+                {
+                    err_code = NRF_SUCCESS;
+
+                    DM_LOG("CONNECT: matched, addr_to_did %d\r\n", device_index);
+                }
+                else
+                {
+                    //Use the device address to check if the device exists in the bonded device list.
+                    err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr,
+                                                    &device_index, EDIV_INIT_VAL);
+                    DM_LOG("CONNECT: not matched, status: %d found manually: %d\r\n", err_code, device_index);
+                }
+
+                if (err_code == NRF_SUCCESS)
+                {
+                    DM_LOG("CONNECT: SUCCESS!\r\n");
+                    m_connection_table[index].bonded_dev_id = device_index;
+                    m_connection_table[index].state        |= STATE_BONDED;
+                    handle.device_id                        = device_index;
+
+                    bond_data_load(&handle);
+                }
+            }
+
+            DM_LOG("CONNECT: did %d bdid %d\r\n", handle.device_id, m_connection_table[index].bonded_dev_id);
+
+            break;
+
+        case BLE_GAP_EVT_DISCONNECTED:
+            //Disconnection could be peer or self initiated hence disconnecting and connecting
+            //both states are permitted, however, connection handle must be known.
+            DM_LOG("[DM]: Disconnect Reason 0x%04X\r\n",
+                   p_ble_evt->evt.gap_evt.params.disconnected.reason);
+
+            m_connection_table[index].state &= (~STATE_CONNECTED);
+
+            if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)
+            {
+                if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED)
+                {
+                    //Write bond information persistently.
+                    device_context_store(&handle, STORE_ALL_CONTEXT);
+                }
+            }
+            else
+            {
+                //Free any allocated instances for devices that is not bonded.
+                if (handle.device_id != DM_INVALID_ID)
+                {
+                    peer_instance_init(handle.device_id);
+                    handle.device_id = DM_INVALID_ID;
+                }
+            }
+
+            m_connection_table[index].state = STATE_DISCONNECTING;
+            notify_app                      = true;
+            event.event_id                  = DM_EVT_DISCONNECTION;
+
+            break;
+
+        case BLE_GAP_EVT_SEC_INFO_REQUEST:
+            DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_INFO_REQUEST\r\n");
+
+            //If the device is already bonded, respond with existing info, else NULL.
+            if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
+            {
+                DM_LOG("INVALID ID \r\n");
+
+                //Find device based on div.
+                err_code = device_instance_find(NULL,&device_index, p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv);
+                if (err_code == NRF_SUCCESS)
+                {
+                    //Load needed bonding information.
+                    m_connection_table[index].bonded_dev_id = device_index;
+                    m_connection_table[index].state        |= STATE_BONDED;
+                    handle.device_id                        = device_index;
+                    bond_data_load(&handle);
+                }
+            }
+
+            if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
+            {
+                DM_LOG("VALID ID index %d bdid %d\r\n",index, m_connection_table[index].bonded_dev_id);
+                p_enc_info = &m_bond_table[index].peer_enc_key.enc_info;
+                DM_DUMP((uint8_t *)p_enc_info, sizeof(ble_gap_enc_info_t));
+            }
+
+            err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle,
+                                                 p_enc_info,
+                                                 &m_peer_table[index].peer_id.id_info,
+                                                 NULL);
+
+            if (err_code != NRF_SUCCESS)
+            {
+                DM_LOG("[DM]:[CI %02X]:[DI %02X]: Security information response failed, reason "
+                       "0x%08X\r\n", index, m_connection_table[index].bonded_dev_id, err_code);
+            }
+            break;
+
+        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+            DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n");
+
+            DM_LOG("SEC_PARAM irkm: %d idx: %d \r\n",p_ble_evt->evt.gap_evt.params.connected.irk_match, p_ble_evt->evt.gap_evt.params.connected.irk_match_idx);
+
+            event.event_id = DM_EVT_SECURITY_SETUP;
+
+            m_connection_table[index].state |= STATE_PAIRING;
+            notify_app                       = true;
+
+            if ((device_index = address_to_device_id(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)) != DM_INVALID_ID)
+            {
+                handle.device_id                        = device_index;
+                m_connection_table[index].bonded_dev_id = device_index;
+                err_code = NRF_SUCCESS;
+
+                DM_LOG("REBONDING bdid %d, did %d, conn %d\r\n",m_connection_table[index].bonded_dev_id, handle.device_id, index);
+            }
+
+            if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID)
+            {
+                DM_LOG("allocating new \r\n");
+
+                //Assign a peer index as a new bond or update existing bonds.
+                err_code = device_instance_allocate((uint8_t *)&device_index,
+                                                    &m_connection_table[index].peer_addr);
+
+                //Allocation successful.
+                if (err_code == NRF_SUCCESS)
+                {
+
+                    DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
+
+                    handle.device_id                        = device_index;
+                    m_connection_table[index].bonded_dev_id = device_index;
+                }
+                else
+                {
+                    DM_LOG("[DM]: Security parameter request failed, reason 0x%08X.\r\n", err_code);
+                    event_result = err_code;
+                    notify_app   = true;
+                }
+            }
+            else
+            {
+                DM_LOG("refresh\r\n");
+                //Bond/key refresh.
+                event.event_id = DM_EVT_SECURITY_SETUP_REFRESH;
+                memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
+
+                //Set the update flag for bond data.
+                m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
+            }
+
+            DM_LOG("FINAL [DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index);
+
+            ble_gap_sec_keyset_t keys_exchanged;
+
+            DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n",
+                   p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc,
+                   p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_central.id,
+                   p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign,
+                   p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond);
+
+            keys_exchanged.keys_central.p_enc_key  = NULL;
+            keys_exchanged.keys_central.p_id_key   = &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id;
+            keys_exchanged.keys_central.p_sign_key = NULL;
+            keys_exchanged.keys_periph.p_enc_key   = &m_bond_table[index].peer_enc_key;
+            keys_exchanged.keys_periph.p_id_key    = NULL;
+            keys_exchanged.keys_periph.p_sign_key  = NULL;
+
+            err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
+                                                   BLE_GAP_SEC_STATUS_SUCCESS,
+                                                   &m_application_table[0].sec_param,
+                                                   &keys_exchanged);
+
+            if (err_code != NRF_SUCCESS)
+            {
+                DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code);
+                event_result = err_code;
+                notify_app   = false;
+            }
+            break;
+
+        case BLE_GAP_EVT_AUTH_STATUS:
+        {
+            DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n",
+                   p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
+
+            m_application_table[0].state    &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS);
+            m_connection_table[index].state &= (~STATE_PAIRING);
+            event.event_id                   = DM_EVT_SECURITY_SETUP_COMPLETE;
+            notify_app                       = true;
+
+            if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
+            {
+                DM_LOG("bond failed\r\n");
+                // Free the allocation as bonding failed.
+                ret_code_t result = device_instance_free(m_connection_table[index].bonded_dev_id);
+                (void) result;
+                event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status;
+            }
+            else
+            {
+                DM_LOG("bonding\r\n");
+                DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status,
+                        sizeof(ble_gap_evt_auth_status_t));
+                DM_DUMP((uint8_t *)&m_bond_table[index], sizeof(bond_context_t));
+
+                if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1)
+                {
+                    if (handle.device_id != DM_INVALID_ID)
+                    {
+                        m_connection_table[index].state |= STATE_BONDED;
+
+                        //IRK and/or public address is shared, update it.
+                        if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_central.id == 1)
+                        {
+                            DM_LOG("shared\r\n");
+                            m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
+                        }
+
+                        if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID)
+                        {
+                            DM_LOG("bonded index %d bdid %d\r\n", index,m_connection_table[index].bonded_dev_id);
+                            DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",
+                                   index,
+                                   handle.device_id);
+
+                            if (m_connection_table[index].peer_addr.addr_type !=
+                                BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+                            {
+                                DM_LOG("not RPR\r\n");
+
+                               m_peer_table[handle.device_id].peer_id.id_addr_info =
+                                    m_connection_table[index].peer_addr;
+                               m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY);
+
+                               DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info,
+                                       sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info));
+                            }
+                            else
+                            {
+                                DM_LOG("PR\r\n");
+                                // Here we must fetch the keys from the keyset distributed.
+                                m_peer_table[handle.device_id].ediv       = m_bond_table[index].peer_enc_key.master_id.ediv;
+                                m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY);
+                            }
+
+                            device_context_store(&handle, FIRST_BOND_STORE);
+                        }
+                    }
+                }
+                else
+                {
+                    //Pairing request, no need to touch the bonding info.
+                }
+            }
+            break;
+        }
+
+        case BLE_GAP_EVT_CONN_SEC_UPDATE:
+            DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n",
+                   p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm,
+                   p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv);
+
+            if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) &&
+                (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) &&
+                ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED))
+            {
+                //Lost bond case, generate a security refresh event!
+                memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE);
+
+                event.event_id                   = DM_EVT_SECURITY_SETUP_REFRESH;
+                m_connection_table[index].state |= STATE_PAIRING_PENDING;
+                m_connection_table[index].state |= STATE_BOND_INFO_UPDATE;
+                m_application_table[0].state    |= STATE_QUEUED_CONTROL_REQUEST;
+            }
+            else
+            {
+                m_connection_table[index].state |= STATE_LINK_ENCRYPTED;
+                event.event_id                   = DM_EVT_LINK_SECURED;
+
+                //Apply service context.
+                err_code = m_service_context_apply[m_application_table[0].service](&handle);
+
+                if (err_code != NRF_SUCCESS)
+                {
+                    DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n",
+                            handle.connection_id,
+                            handle.device_id);
+
+                    event_result = DM_SERVICE_CONTEXT_NOT_APPLIED;
+                }
+            }
+            event_result = NRF_SUCCESS;
+            notify_app   = true;
+
+            break;
+
+        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+            DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n");
+
+            //Apply service context.
+            event_result = m_service_context_apply[m_application_table[0].service](&handle);
+            break;
+
+        case BLE_GAP_EVT_SEC_REQUEST:
+            DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n");
+
+            //Verify if the device is already bonded, and if it is bonded, initiate encryption.
+            //If the device is not bonded, an instance needs to be allocated in order to initiate
+            //bonding. The application have to initiate the procedure, the module will not do this
+            //automatically.
+            event.event_id = DM_EVT_SECURITY_SETUP;
+            notify_app     = true;
+
+            break;
+
+        default:
+            break;
+    }
+
+    if (notify_app)
+    {
+        app_evt_notify(&handle, &event, event_result);
+
+        //Freeing the instance after the event is notified so the application can get the context.
+        if (event.event_id == DM_EVT_DISCONNECTION)
+        {
+            //Free the instance.
+            connection_instance_free(&index);
+        }
+    }
+
+    UNUSED_VARIABLE(err_code);
+
+    DM_MUTEX_UNLOCK();
+}
+
+
+ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle)
+{
+    ret_code_t err_code;
+    uint32_t   index;
+
+    NULL_PARAM_CHECK(p_handle);
+    VERIFY_APP_REGISTERED(p_handle->appl_id);
+
+    p_handle->device_id  = DM_INVALID_ID;
+
+    err_code = NRF_ERROR_NOT_FOUND;
+
+    for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++)
+    {
+        //Search for matching connection handle.
+        if (conn_handle == m_connection_table[index].conn_handle)
+        {
+            p_handle->connection_id = index;
+            p_handle->device_id     = m_connection_table[index].bonded_dev_id;
+
+            err_code = NRF_SUCCESS;
+            break;
+        }
+    }
+    return err_code;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/id_manager.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "id_manager.h"
+
+#include <string.h>
+#include "nrf_soc.h"
+#include "ble_gap.h"
+#include "ble_conn_state.h"
+#include "peer_manager_types.h"
+#include "peer_database.h"
+#include "nordic_common.h"
+
+#define IM_MAX_CONN_HANDLES         8
+#define IM_NO_INVALID_CONN_HANDLES  0xFF
+#define MAX_REGISTRANTS             3
+#define WHITELIST_MAX_COUNT         MAX(BLE_GAP_WHITELIST_ADDR_MAX_COUNT, \
+                                        BLE_GAP_WHITELIST_IRK_MAX_COUNT)
+#define IM_ADDR_CLEARTEXT_LENGTH    3
+#define IM_ADDR_CIPHERTEXT_LENGTH   3
+
+#define MODULE_INITIALIZED (m_im.n_registrants > 0)
+
+#define VERIFY_MODULE_INITIALIZED()     \
+do                                      \
+{                                       \
+    if (!MODULE_INITIALIZED)            \
+    {                                   \
+        return NRF_ERROR_INVALID_STATE; \
+    }                                   \
+} while(0)
+
+#define VERIFY_PARAM_NOT_NULL(param)    \
+do                                      \
+{                                       \
+    if (param == NULL)                  \
+    {                                   \
+        return NRF_ERROR_NULL;          \
+    }                                   \
+} while(0)
+
+
+typedef struct
+{
+    pm_peer_id_t   peer_id;
+    uint16_t       conn_handle;
+    ble_gap_addr_t peer_address;
+} im_connection_t;
+
+typedef struct
+{
+    im_evt_handler_t              evt_handlers[MAX_REGISTRANTS];
+    uint8_t                       n_registrants;
+    im_connection_t               connections[8];
+    pm_peer_id_t                  whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
+    ble_gap_irk_t                 whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
+    ble_gap_addr_t                whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+    uint8_t                       n_whitelist_peer_ids;
+    ble_conn_state_user_flag_id_t conn_state_user_flag_id;
+} im_t;
+
+static im_t m_im = {.n_registrants = 0};
+
+static void internal_state_reset()
+{
+    memset(&m_im, 0, sizeof(im_t));
+    m_im.n_registrants = 0;
+    m_im.n_whitelist_peer_ids = 0;
+    m_im.conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID;
+    for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+    {
+        m_im.connections[i].conn_handle = BLE_CONN_HANDLE_INVALID;
+    }
+}
+
+
+/**@brief Function for sending an event to all registered event handlers.
+ *
+ * @param[in] p_event The event to distribute.
+ */
+static void evt_send(im_evt_t * p_event)
+{
+    for (uint32_t i = 0; i < m_im.n_registrants; i++)
+    {
+        m_im.evt_handlers[i](p_event);
+    }
+}
+
+/**@brief Function finding a free position in m_im.connections.
+ *
+ * @detail All connection handles in the m_im.connections array are checked against the connection
+ *         state module. The index of the first one that is not a connection handle for a current
+ *         connection is returned. This position in the array can safely be used for a new connection.
+ *
+ * @return Either the index of a free position in the array or IM_NO_INVALID_CONN_HANDLES if no free
+           position exists.
+ */
+uint8_t get_free_connection()
+{
+    for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+    {
+        // Query the connection state module to check if the connection handle does not belong to a
+        // valid connection.
+        if (!ble_conn_state_user_flag_get(m_im.connections[i].conn_handle, m_im.conn_state_user_flag_id))
+        {
+            return i;
+        }
+    }
+    // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
+    return IM_NO_INVALID_CONN_HANDLES;
+}
+
+
+/**@brief Function finding a particular connection handle m_im.connections.
+ *
+ * @param[in]  conn_handle  The handle to find.
+ *
+ * @return Either the index of the conn_handle in the array or IM_NO_INVALID_CONN_HANDLES if the
+ *         handle was not found.
+ */
+uint8_t get_connection_by_conn_handle(uint16_t conn_handle)
+{
+    if (ble_conn_state_user_flag_get(conn_handle, m_im.conn_state_user_flag_id))
+    {
+        for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+        {
+            if (m_im.connections[i].conn_handle == conn_handle)
+            {
+                return i;
+            }
+        }
+    }
+    // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
+    return IM_NO_INVALID_CONN_HANDLES;
+}
+
+
+/**@brief Function for registering a new connection instance.
+ *
+ * @param[in]  conn_handle  The handle of the new connection.
+ * @param[in]  p_ble_addr   The address used to connect.
+ *
+ * @return Either the index of the new connection in the array or IM_NO_INVALID_CONN_HANDLES if no
+ *         free position exists.
+ */
+uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
+{
+    uint8_t conn_index = IM_NO_INVALID_CONN_HANDLES;
+
+    if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID))
+    {
+        ble_conn_state_user_flag_set(conn_handle, m_im.conn_state_user_flag_id, true);
+
+        conn_index = get_connection_by_conn_handle(conn_handle);
+        if (conn_index == IM_NO_INVALID_CONN_HANDLES)
+        {
+            conn_index = get_free_connection();
+        }
+
+        if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+        {
+            m_im.connections[conn_index].conn_handle  = conn_handle;
+            m_im.connections[conn_index].peer_id      = PM_PEER_ID_INVALID;
+            m_im.connections[conn_index].peer_address = *p_ble_addr;
+        }
+    }
+    return conn_index;
+}
+
+
+/**@brief Function checking the validity of an IRK
+ *
+ * @detail An all-zero IRK is not valid. This function will check if a given IRK is valid.
+ *
+ * @param[in] irk The IRK for which the validity is going to be checked.
+ *
+ * @retval true  The IRK is valid.
+ * @retval false The IRK is invalid.
+ */
+bool is_valid_irk(ble_gap_irk_t const * irk)
+{
+    for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++)
+    {
+        if (irk->irk[i] != 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+/**@brief Function for comparing two addresses to determine if they are identical
+ *
+ * @note The address type need to be identical, as well as every bit in the address itself.
+ *
+ * @param[in] p_addr1 The first address to be compared.
+ * @param[in] p_addr2 The second address to be compared.
+ *
+ * @retval true  The addresses are identical.
+ * @retval false The addresses are not identical.
+ */
+bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2)
+{
+    if ((p_addr1 == NULL) || (p_addr2 == NULL))
+    {
+        return false;
+    }
+
+    // Check that the addr type is identical, return false if it is not
+    if (p_addr1->addr_type != p_addr2->addr_type)
+    {
+        return false;
+    }
+    // Check if the addr bytes are is identical
+    return (memcmp(p_addr1->addr, p_addr2->addr, BLE_GAP_ADDR_LEN) == 0);
+}
+
+
+void im_ble_evt_handler(ble_evt_t * ble_evt)
+{
+    ret_code_t err_code;
+    switch (ble_evt->header.evt_id)
+    {
+        case BLE_GAP_EVT_CONNECTED:
+        {
+            pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID;
+
+            if (ble_evt->evt.gap_evt.params.connected.irk_match == 1)
+            {
+                // The peer was matched using a whitelist.
+                bonded_matching_peer_id
+                        = m_im.whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx];
+            }
+            else if (   ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type
+                     != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
+            {
+                /* Search the database for bonding data matching the one that triggered the event.
+                 * Public and static addresses can be matched on address alone, while resolvable
+                 * random addresses can be resolved agains known IRKs. Non-resolvable random addresses
+                 * are never matching because they are not longterm form of identification.
+                 */
+                pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+                while (   (compared_peer_id        != PM_PEER_ID_INVALID)
+                       && (bonded_matching_peer_id == PM_PEER_ID_INVALID))
+                {
+                    pm_peer_data_flash_t compared_data;
+                    switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type)
+                    {
+                        case BLE_GAP_ADDR_TYPE_PUBLIC:
+                            /* fall-through */
+                        case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
+                            err_code = pdb_read_buf_get(compared_peer_id,
+                                                        PM_PEER_DATA_ID_BONDING,
+                                                        &compared_data,
+                                                        NULL);
+                            if ((err_code == NRF_SUCCESS) &&
+                                addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr,
+                                             &compared_data.data.p_bonding_data->peer_id.id_addr_info)
+                            )
+                            {
+                                bonded_matching_peer_id = compared_peer_id;
+                            }
+                            break;
+
+                        case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE:
+                            err_code = pdb_read_buf_get(compared_peer_id,
+                                                        PM_PEER_DATA_ID_BONDING,
+                                                        &compared_data,
+                                                        NULL);
+                            if (err_code == NRF_SUCCESS &&
+                                im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr,
+                                                   &compared_data.data.p_bonding_data->peer_id.id_info)
+                            )
+                            {
+                                bonded_matching_peer_id = compared_peer_id;
+                            }
+                            break;
+
+                        case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE:
+                            // Should not happen.
+                            break;
+
+                        default:
+                            break;
+                    }
+                    compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
+                }
+            }
+            new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr);
+
+            if (bonded_matching_peer_id != PM_PEER_ID_INVALID)
+            {
+                im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id);
+
+                // Send a bonded peer event
+                im_evt_t im_evt;
+                im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle;
+                im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED;
+                evt_send(&im_evt);
+            }
+        }
+    }
+}
+
+
+/**@brief Function to compare two sets of bonding data to check if they belong to the same device.
+ * @note  Invalid irks will never match even though they are identical.
+ *
+ * @param[in]  p_bonding_data1 First bonding data for comparison
+ * @param[in]  p_bonding_data2 Second bonding data for comparison
+ *
+ * @return     True if the input matches, false if it does not.
+ */
+bool is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1,
+                               pm_peer_data_bonding_t const * p_bonding_data2)
+{
+    bool valid_irk = is_valid_irk(&p_bonding_data1->peer_id.id_info);
+    bool duplicate_irk = valid_irk &&
+        (memcmp(p_bonding_data1->peer_id.id_info.irk,
+        p_bonding_data2->peer_id.id_info.irk,
+        BLE_GAP_SEC_KEY_LEN) == 0
+    );
+    bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info,
+                                       &p_bonding_data2->peer_id.id_addr_info
+    );
+    return duplicate_irk || duplicate_addr;
+}
+
+
+/**@brief Event handler for events from the peer_database module.
+ *
+ * @param[in]  p_event The event that has happend with peer id and flags.
+ */
+static void pdb_evt_handler(pdb_evt_t const * p_event)
+{
+    ret_code_t err_code;
+    if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED))
+    {
+        // If new data about peer id has been stored it is compared to other peers peer ids in
+        // search of duplicates.
+        if (p_event->data_id == PM_PEER_DATA_ID_BONDING)
+        {
+            pm_peer_data_flash_t written_data;
+            err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL);
+            if (err_code == NRF_SUCCESS)
+            {
+                pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+                while (compared_peer_id != PM_PEER_ID_INVALID)
+                {
+                    pm_peer_data_flash_t compared_data;
+                    err_code = pdb_read_buf_get(compared_peer_id,
+                                                PM_PEER_DATA_ID_BONDING,
+                                                &compared_data,
+                                                NULL);
+                    if ( err_code == NRF_SUCCESS &&
+                        p_event->peer_id != compared_peer_id &&
+                        is_duplicate_bonding_data(written_data.data.p_bonding_data,
+                                                  compared_data.data.p_bonding_data)
+                    )
+                    {
+                        im_evt_t im_evt;
+                        im_evt.conn_handle = im_conn_handle_get(p_event->peer_id);
+                        im_evt.evt_id = IM_EVT_DUPLICATE_ID;
+                        im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id;
+                        im_evt.params.duplicate_id.peer_id_2 = compared_peer_id;
+                        evt_send(&im_evt);
+                    }
+                    compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
+                }
+            }
+        }
+    }
+}
+
+
+ret_code_t im_register(im_evt_handler_t evt_handler)
+{
+    VERIFY_PARAM_NOT_NULL(evt_handler);
+    ret_code_t err_code = NRF_SUCCESS;
+
+    if (!MODULE_INITIALIZED)
+    {
+        internal_state_reset();
+        m_im.conn_state_user_flag_id = ble_conn_state_user_flag_acquire();
+        if (m_im.conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
+        {
+            err_code = NRF_ERROR_NO_MEM;
+        }
+        else
+        {
+            err_code = pdb_register(pdb_evt_handler);
+        }
+    }
+    if (err_code == NRF_SUCCESS)
+    {
+        if ((m_im.n_registrants < MAX_REGISTRANTS))
+        {
+            m_im.evt_handlers[m_im.n_registrants++] = evt_handler;
+        }
+        else
+        {
+            err_code = NRF_ERROR_NO_MEM;
+        }
+    }
+    return err_code;
+}
+
+
+pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle)
+{
+    uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
+
+    if (MODULE_INITIALIZED && (conn_index != IM_NO_INVALID_CONN_HANDLES))
+    {
+        return m_im.connections[conn_index].peer_id;
+    }
+
+    return PM_PEER_ID_INVALID;
+}
+
+
+ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
+{
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_NULL(p_ble_addr);
+
+    uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
+    if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+    {
+        *p_ble_addr = m_im.connections[conn_index].peer_address;
+        return NRF_SUCCESS;
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+/**@brief Function for comparing two master ids
+ * @note  Two invalid master IDs will not match.
+ *
+ * @param[in]  p_master_id1 First master id for comparison
+ * @param[in]  p_master_id2 Second master id for comparison
+ *
+ * @return     True if the input matches, false if it does not.
+ */
+bool master_id_compare(ble_gap_master_id_t const * p_master_id1,
+                       ble_gap_master_id_t const * p_master_id2)
+{
+    if(!im_master_id_is_valid(p_master_id1))
+    {
+        return false;
+    }
+    if (p_master_id1->ediv != p_master_id2->ediv)
+    {
+        return false;
+    }
+    return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0);
+}
+
+
+pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id)
+{
+    ret_code_t err_code;
+    // For each stored peer, check if the master_id match p_master_id
+    pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+    while (compared_peer_id != PM_PEER_ID_INVALID)
+    {
+        pm_peer_data_flash_t        compared_data;
+        ble_gap_master_id_t const * p_compared_master_id;
+
+        err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL);
+        if (err_code == NRF_SUCCESS)
+        {
+            p_compared_master_id = &compared_data.data.p_bonding_data->own_ltk.master_id;
+            if (compared_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_CENTRAL)
+            {
+                p_compared_master_id = &compared_data.data.p_bonding_data->peer_ltk.master_id;
+            }
+            if (master_id_compare(p_master_id, p_compared_master_id))
+            {
+                // If a matching master_id is found return the peer_id
+                return compared_peer_id;
+            }
+        }
+        compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
+    }
+    // If no matching master_id is found return the PM_PEER_ID_INVALID
+    return PM_PEER_ID_INVALID;
+}
+
+
+pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx)
+{
+    // Verify that the requested idx is within the list
+    if (irk_match_idx < m_im.n_whitelist_peer_ids)
+    {
+        // Return the peer_id from the white list
+        return m_im.whitelist_peer_ids[irk_match_idx];
+    }
+    else
+    {
+        // Return PM_PEER_ID_INVALID to indicate that there was no peer with the requested idx
+        return PM_PEER_ID_INVALID;
+    }
+}
+
+
+uint16_t im_conn_handle_get(pm_peer_id_t peer_id)
+{
+    for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+    {
+        if (peer_id == m_im.connections[i].peer_id)
+        {
+            return m_im.connections[i].conn_handle;
+        }
+    }
+    return BLE_CONN_HANDLE_INVALID;
+}
+
+
+bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id)
+{
+
+    if (p_master_id->ediv != 0)
+    {
+        return true;
+    }
+    for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++)
+    {
+        if (p_master_id->rand[i] != 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id)
+{
+    uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
+    if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+    {
+        m_im.connections[conn_index].peer_id = peer_id;
+    }
+}
+
+
+ret_code_t im_wlist_create(pm_peer_id_t *        p_peer_ids,
+                           uint8_t               n_peer_ids,
+                           ble_gap_whitelist_t * p_whitelist)
+{
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_NULL(p_whitelist);
+    ret_code_t err_code;
+    p_whitelist->addr_count = 0;
+    p_whitelist->irk_count = 0;
+    m_im.n_whitelist_peer_ids = 0;
+    for (uint32_t peer_index = 0; peer_index < n_peer_ids; peer_index++)
+    {
+        bool peer_connected = false;
+        for (uint32_t conn_index = 0; conn_index < IM_MAX_CONN_HANDLES; conn_index++)
+        {
+            if (p_peer_ids[peer_index] == m_im.connections[conn_index].peer_id &&
+                ble_conn_state_user_flag_get(m_im.connections[conn_index].conn_handle, m_im.conn_state_user_flag_id)
+            )
+            {
+                peer_connected = true;
+                break;
+            }
+        }
+        if (!peer_connected)
+        {
+            pm_peer_data_flash_t peer_data;
+            err_code = pdb_read_buf_get(p_peer_ids[peer_index], PM_PEER_DATA_ID_BONDING, &peer_data, NULL);
+            if (err_code == NRF_ERROR_INVALID_PARAM || err_code == NRF_ERROR_NOT_FOUND)
+            {
+                return NRF_ERROR_INVALID_PARAM;
+            }
+            if (p_whitelist->pp_addrs != NULL &&
+                peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type
+                        != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE &&
+                peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type
+                        != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
+            )
+            {
+                memcpy(m_im.whitelist_addrs[peer_index].addr,
+                    peer_data.data.p_bonding_data->peer_id.id_addr_info.addr,
+                    BLE_GAP_ADDR_LEN
+                );
+                m_im.whitelist_addrs[peer_index].addr_type =
+                    peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type;
+                p_whitelist->pp_addrs[peer_index] = &m_im.whitelist_addrs[peer_index];
+                p_whitelist->addr_count++;
+            }
+            if (p_whitelist->pp_irks != NULL &&
+                is_valid_irk(&(peer_data.data.p_bonding_data->peer_id.id_info))
+            )
+            {
+                memcpy(m_im.whitelist_irks[peer_index].irk,
+                    peer_data.data.p_bonding_data->peer_id.id_info.irk,
+                    BLE_GAP_SEC_KEY_LEN
+                );
+                p_whitelist->pp_irks[peer_index] = &m_im.whitelist_irks[peer_index];
+                p_whitelist->irk_count++;
+                m_im.whitelist_peer_ids[peer_index] = p_peer_ids[peer_index];
+                m_im.n_whitelist_peer_ids++;
+            }
+        }
+    }
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist)
+{
+    pm_peer_id_t new_whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
+    uint32_t n_new_whitelist_peer_ids = 0;
+    VERIFY_PARAM_NOT_NULL(p_whitelist);
+    for (uint32_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++)
+    {
+        new_whitelist_peer_ids[i] = PM_PEER_ID_INVALID;
+    }
+    pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+    while (compared_peer_id != PM_PEER_ID_INVALID)
+    {
+        pm_peer_data_flash_t compared_data;
+        pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL);
+        for (uint32_t i = 0; i < p_whitelist->irk_count; i++)
+        {
+            bool valid_irk = is_valid_irk(&compared_data.data.p_bonding_data->peer_id.id_info);
+            bool duplicate_irk = valid_irk &&
+                (memcmp(p_whitelist->pp_irks[i]->irk,
+                compared_data.data.p_bonding_data->peer_id.id_info.irk,
+                BLE_GAP_SEC_KEY_LEN) == 0
+            );
+            if (duplicate_irk)
+            {
+                new_whitelist_peer_ids[i] = compared_peer_id;
+                n_new_whitelist_peer_ids++;
+            }
+        }
+        compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
+    }
+    if (n_new_whitelist_peer_ids != p_whitelist->irk_count)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+    else
+    {
+        for (uint32_t i = 0; i < n_new_whitelist_peer_ids; i++)
+        {
+            m_im.whitelist_peer_ids[i] = new_whitelist_peer_ids[i];
+        }
+        m_im.n_whitelist_peer_ids = n_new_whitelist_peer_ids;
+        return NRF_SUCCESS;
+    }
+}
+
+
+/**@brief Function for calculating the ah() hash function described in Bluetooth core specification
+ *        4.2 section 3.H.2.2.2.
+ *
+ * @detail  BLE uses a hash function to calculate the first half of a resolvable address
+ *          from the second half of the address and an irk. This function will use the ECB
+ *          periferal to hash these data acording to the Bluetooth core specification.
+ *
+ * @note The ECB expect little endian input and output.
+ *       This function expect big endian and will reverse the data as necessary.
+ *
+ * @param[in]  p_k          The key used in the hash function.
+ *                          For address resolution this is should be the irk.
+ *                          The array must have a length of 16.
+ * @param[in]  p_r          The rand used in the hash function. For generating a new address
+ *                          this would be a random number. For resolving a resolvable address
+ *                          this would be the last half of the address being resolved.
+ *                          The array must have a length of 3.
+ * @param[out] p_local_hash The result of the hash operation. For address resolution this
+ *                          will match the first half of the address being resolved if and only
+ *                          if the irk used in the hash function is the same one used to generate
+ *                          the address.
+ *                          The array must have a length of 16.
+ */
+void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash)
+{
+    nrf_ecb_hal_data_t ecb_hal_data;
+    for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++)
+    {
+        ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i];
+    }
+    memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH);
+
+    for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++)
+    {
+        ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i];
+    }
+
+    sd_ecb_block_encrypt(&ecb_hal_data);
+
+    for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++)
+    {
+        p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i];
+    }
+}
+
+
+bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
+{
+    if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+    {
+        return false;
+    }
+    uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH];
+    uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH];
+    uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH];
+    memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH);
+    memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH);
+    ah(p_irk->irk, prand, local_hash);
+
+    return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/id_manager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_ID_MANAGER_H__
+#define PEER_ID_MANAGER_H__
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+
+/**
+ * @defgroup id_manager ID Manager
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for keeping track of peer identities
+ *       (IRK and peer address).
+ */
+
+
+/**@brief Events that can come from the ID Manager module.
+ */
+typedef enum
+{
+    IM_EVT_DUPLICATE_ID,          /**< The ID Manager module has detected that two stored peers represent the same peer. */
+    IM_EVT_BONDED_PEER_CONNECTED, /**< A connected peer has been identified as one of the bonded peers. This can happen immediately on connection, or at a later time. */
+} im_evt_id_t;
+
+
+typedef struct
+{
+    im_evt_id_t evt_id;
+    uint16_t    conn_handle;
+    union
+    {
+        struct
+        {
+            pm_peer_id_t peer_id_1;
+            pm_peer_id_t peer_id_2;
+        } duplicate_id;
+    } params;
+} im_evt_t;
+
+
+/**@brief Event handler for events from the ID Manager module.
+ *
+ * @param[in]  p_event   The event that has happened.
+ */
+typedef void (*im_evt_handler_t)(im_evt_t const * p_event);
+
+/**@brief Function for registering for events from the ID Manager module.
+ *
+ * @note This will also initialize the module if needed.
+ *
+ * @param[in]  evt_handler  Callback for events from the ID Manager module.
+ *
+ * @retval NRF_SUCCESS       Registration was successful.
+ * @retval NRF_ERROR_NO_MEM  No more registrations possible.
+ * @retval NRF_ERROR_NULL    evt_handler was NULL.
+ */
+ret_code_t im_register(im_evt_handler_t evt_handler);
+
+
+/**@brief Function for dispatching SoftDevice events to the ID Manager module.
+ *
+ * @param[in]  p_ble_evt  The SoftDevice event.
+ */
+void im_ble_evt_handler(ble_evt_t * p_ble_evt);
+
+
+/**@brief Function for getting the corresponding peer ID from a connection handle.
+ *
+ * @param[in]  conn_handle  The connection handle.
+ *
+ * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
+ */
+pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle);
+
+
+/**@brief Function for getting the corresponding peer ID from a master ID (EDIV and rand).
+ *
+ * @param[in]  p_master_id  The master ID.
+ *
+ * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
+ */
+pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id);
+
+
+/**@brief Function for getting the corresponding peer ID from an IRK match index, see @ref
+ *        ble_gap_evt_connected_t.
+ *
+ * @param[in]  irk_match_idx  The IRK match index.
+ *
+ * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
+ */
+pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx);
+
+
+/**@brief Function for getting the corresponding connection handle from a peer ID.
+ *
+ * @param[in] peer_id  The peer ID.
+ *
+ * @return The corresponding connection handle, or @ref BLE_CONN_HANDLE_INVALID if none could be
+ *         resolved.
+ */
+uint16_t im_conn_handle_get(pm_peer_id_t peer_id);
+
+
+/**@brief Function for getting the BLE address used by the peer when connecting.
+ *
+ * @param[in]  conn_handle  The connection handle.
+ * @param[out] p_ble_addr   The BLE address used by the peer when the connection specified by
+ *                          conn_handle was established.
+ *
+ * @retval NRF_SUCCESS                   The address was found and copied.
+ * @retval NRF_ERROR_INVALID_STATE       Module not initialized.
+ * @retval BLE_ERROR_CONN_HANDLE_INVALID conn_handle does not refer to an active connection.
+ * @retval NRF_ERROR_NULL                p_ble_addr was NULL.
+ */
+ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr);
+
+
+/**@brief Function for checking whether a master ID is valid or invalid
+ *
+ * @param[in]  p_master_id  The master ID.
+ *
+ * @retval true   The master id is valid.
+ * @retval true   The master id is invalid (i.e. all zeros).
+ */
+bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id);
+
+
+/**@brief Function for reporting that a new peer ID has been allocated for a specified connection.
+ *
+ * @param[in]  conn_handle  The connection.
+ * @param[in]  peer_id      The new peer ID.
+ */
+void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id);
+
+
+/**
+ * @brief Function for informing this module of what whitelist will be used.
+ *
+ * @details This function is meant to be used when the app wants to use a custom whitelist.
+ *          When using peer manager, this function must be used if a custom whitelist is used.
+ *
+ * @note When using a whitelist, always use the whitelist created/set by the most recent
+ *       call to @ref im_wlist_create or to this function, whichever happened most recently.
+ * @note Do not call this function while scanning with another whitelist.
+ * @note Do not add any irks to the whitelist that are not present in the bonding data of a peer in
+ *       the peer database.
+ *
+ * @param[in] p_whitelist  The whitelist.
+ *
+ * @retval NRF_SUCCESS         Whitelist successfully set.
+ * @retval NRF_ERROR_NULL      p_whitelist was NULL.
+ * @retval NRF_ERROR_NOT_FOUND One or more of the whitelists irks was not found in the peer_database.
+ */
+ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist);
+
+
+/**
+ * @brief Function for constructing a whitelist for use when advertising.
+ *
+ * @note When advertising with whitelist, always use the whitelist created/set by the most recent
+ *       call to this function or to @ref im_wlist_set, whichever happened most recently.
+ * @note Do not call this function while advertising with another whitelist.
+ *
+ * @param[in]     p_peer_ids   The ids of the peers to be added to the whitelist.
+ * @param[in]     n_peer_ids   The number of peer ids in p_peer_ids.
+ * @param[in,out] p_whitelist  The constructed whitelist. Note that p_adv_whitelist->pp_addrs
+ *                             must be NULL or point to an array with size @ref
+ *                             BLE_GAP_WHITELIST_ADDR_MAX_COUNT and p_adv_whitelist->pp_irks
+ *                             must be NULL or point to an array with size @ref
+ *                             BLE_GAP_WHITELIST_IRK_MAX_COUNT.
+ *
+ * @retval NRF_SUCCESS     Whitelist successfully created.
+ * @retval NRF_ERROR_NULL  p_whitelist was NULL.
+ */
+ret_code_t im_wlist_create(pm_peer_id_t        * p_peer_ids,
+                           uint8_t               n_peer_ids,
+                           ble_gap_whitelist_t * p_whitelist);
+
+/**
+ * @brief Function for resolving a resolvable address with an identity resolution key (IRK).
+ *
+ * @details This function will use the ECB peripheral to resolve a resolvable address.
+ *          This can be used to resolve the identity of a device distributing a random
+ *          resolvable address based on any IRKs you have received earlier. If an address is
+ *          resolved by an IRK, the device disributing the address must also know the IRK.
+ *
+ * @param[in] p_addr  A random resolvable address.
+ * @param[in] p_irk   An identity resolution key (IRK).
+ *
+ * @retval true   The irk used matched the one used to create the address.
+ * @retval false  The irk used did not match the one used to create the address, or an argument was
+ *                NULL.
+ */
+bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
+
+/**@brief Function for calculating the ah() hash function described in Bluetooth core specification
+ *        4.2 section 3.H.2.2.2.
+ *
+ * @detail  BLE uses a hash function to calculate the first half of a resolvable address
+ *          from the second half of the address and an irk. This function will use the ECB
+ *          periferal to hash these data acording to the Bluetooth core specification.
+ *
+ * @note The ECB expect little endian input and output.
+ *       This function expect big endian and will reverse the data as necessary.
+ *
+ * @param[in]  p_k          The key used in the hash function.
+ *                          For address resolution this is should be the irk.
+ *                          The array must have a length of 16.
+ * @param[in]  p_r          The rand used in the hash function. For generating a new address
+ *                          this would be a random number. For resolving a resolvable address
+ *                          this would be the last half of the address being resolved.
+ *                          The array must have a length of 3.
+ * @param[out] p_local_hash The result of the hash operation. For address resolution this
+ *                          will match the first half of the address being resolved if and only
+ *                          if the irk used in the hash function is the same one used to generate
+ *                          the address.
+ *                          The array must have a length of 16.
+ *
+ * @note    ====IMPORTANT====
+ *          This is a special modification to the original nRF51 SDK required by the mbed BLE API
+ *          to be able to generate BLE private resolvable addresses. This function is used by
+ *          the BLE API implementation for nRF5xSecurityManager::getAddressFromBondTable() in the
+ *          ble-nrf51822 yotta module.
+ *          =================
+ */
+void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash);
+
+/** @} */
+
+#endif /* PEER_ID_MANAGER_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "peer_data.h"
+
+#include <stdint.h>
+#include <string.h>
+#include "peer_manager_types.h"
+#include "fds.h"
+
+
+
+void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_chunk_t * p_chunks, uint16_t * p_n_chunks)
+{
+    if (p_n_chunks == NULL)
+    {
+    }
+    else if ((p_peer_data == NULL) || (p_chunks == NULL))
+    {
+        *p_n_chunks = 0;
+    }
+    else
+    {
+        switch (p_peer_data->data_type)
+        {
+            case PM_PEER_DATA_ID_BONDING:
+                p_chunks[0].p_data       = p_peer_data->data.p_bonding_data;
+                p_chunks[0].length_words = p_peer_data->length_words;
+                *p_n_chunks = 1;
+                break;
+            case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+                p_chunks[0].p_data       = p_peer_data->data.p_service_changed_pending;
+                p_chunks[0].length_words = p_peer_data->length_words;
+                *p_n_chunks = 1;
+                break;
+            case PM_PEER_DATA_ID_GATT_LOCAL:
+                p_chunks[0].p_data       = p_peer_data->data.p_local_gatt_db;
+                p_chunks[0].length_words = PM_N_WORDS(PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
+                p_chunks[1].p_data       = p_peer_data->data.p_local_gatt_db->p_data;
+                p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words;
+                *p_n_chunks = 2;
+                break;
+            case PM_PEER_DATA_ID_GATT_REMOTE:
+                p_chunks[0].p_data       = p_peer_data->data.p_remote_gatt_db;
+                p_chunks[0].length_words = PM_N_WORDS(PM_REMOTE_DB_LEN_OVERHEAD_BYTES);
+                p_chunks[1].p_data       = p_peer_data->data.p_remote_gatt_db->p_data;
+                p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words;
+                *p_n_chunks = 2;
+                break;
+            case PM_PEER_DATA_ID_APPLICATION:
+                p_chunks[0].p_data       = p_peer_data->data.p_application_data;
+                p_chunks[0].length_words = p_peer_data->length_words;
+                *p_n_chunks = 1;
+                break;
+            default:
+                *p_n_chunks = 0;
+                break;
+        }
+    }
+}
+
+
+ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data)
+{
+    if ((p_in_data == NULL) || (p_out_data == NULL))
+    {
+        return NRF_ERROR_NULL;
+    }
+    else
+    {
+        if (p_out_data->length_words < p_in_data->length_words)
+        {
+            p_out_data->length_words = p_in_data->length_words;
+            return NRF_ERROR_NO_MEM;
+        }
+        p_out_data->length_words = p_in_data->length_words;
+        p_out_data->data_type    = p_in_data->data_type;
+
+        switch (p_in_data->data_type)
+        {
+            case PM_PEER_DATA_ID_BONDING:
+                *p_out_data->data.p_bonding_data = *p_in_data->data.p_bonding_data;
+                break;
+            case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+                *p_out_data->data.p_service_changed_pending = *p_in_data->data.p_service_changed_pending;
+                break;
+            case PM_PEER_DATA_ID_GATT_LOCAL:
+                if (p_out_data->data.p_local_gatt_db->p_data == NULL)
+                {
+                    return NRF_ERROR_NULL;
+                }
+                if (p_out_data->data.p_local_gatt_db->len < p_in_data->data.p_local_gatt_db->len)
+                {
+                    p_out_data->data.p_local_gatt_db->len = p_in_data->data.p_local_gatt_db->len;
+                    return NRF_ERROR_NO_MEM;
+                }
+                else
+                {
+                    p_out_data->data.p_local_gatt_db->flags = p_in_data->data.p_local_gatt_db->flags;
+                    p_out_data->data.p_local_gatt_db->len   = p_in_data->data.p_local_gatt_db->len;
+                    memcpy(p_out_data->data.p_local_gatt_db->p_data,
+                           p_in_data->data.p_local_gatt_db->p_data,
+                           p_in_data->data.p_local_gatt_db->len);
+                }
+                break;
+            case PM_PEER_DATA_ID_GATT_REMOTE:
+                if (p_out_data->data.p_remote_gatt_db->p_data == NULL)
+                {
+                    return NRF_ERROR_NULL;
+                }
+                if (p_out_data->data.p_remote_gatt_db->service_count < p_in_data->data.p_remote_gatt_db->service_count)
+                {
+                    p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count;
+                    return NRF_ERROR_NO_MEM;
+                }
+                else
+                {
+                    p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count;
+                    memcpy(p_out_data->data.p_remote_gatt_db->p_data,
+                           p_in_data->data.p_remote_gatt_db->p_data,
+                           p_in_data->data.p_remote_gatt_db->service_count * sizeof(ble_gatt_db_srv_t));
+                }
+                break;
+            case PM_PEER_DATA_ID_APPLICATION:
+                memcpy(p_out_data->data.p_application_data,
+                       p_in_data->data.p_application_data,
+                       p_in_data->length_words * 4);
+                break;
+            default:
+                break;
+        }
+    }
+    return NRF_SUCCESS;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_DATA_H__
+#define PEER_DATA_H__
+
+#include <stdint.h>
+#include "peer_manager_types.h"
+#include "fds.h"
+
+
+/**
+ * @defgroup peer_data Peer Data
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module defines the structure of the data
+ *        that is managed by the @ref peer_manager. It also provides functions for parsing the data.
+ */
+
+
+/**@brief Function for enumerating the separate (non-contiguous) parts of the peer data.
+ *
+ * @param[in]  p_peer_data  The peer data to enumerate.
+ * @param[out] p_chunks      The resulting chunks. This must be an array of at least 2 elements.
+ * @param[out] p_n_chunks    The number of chunks. If this is 0, something went wrong.
+ */
+void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_chunk_t * p_chunks, uint16_t * p_n_chunks);
+
+
+/**@brief Function for converting @ref pm_peer_data_flash_t into @ref pm_peer_data_t.
+ *
+ * @param[in]  p_in_data   The source data.
+ * @param[out] p_out_data  The target data structure.
+ *
+ * @retval NRF_SUCCESS       Successful conversion.
+ * @retval NRF_ERROR_NULL    A parameter was NULL.
+ * @retval NRF_ERROR_NO_MEM  A buffer was not large enough.
+ */
+ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data);
+
+/** @} */
+
+#endif /* PEER_DATA_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data_storage.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,688 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "peer_data_storage.h"
+
+#include <stdint.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "peer_manager_types.h"
+#include "peer_id.h"
+#include "peer_data.h"
+#include "fds.h"
+
+#define MAX_REGISTRANTS    6                         /**< The number of user that can register with the module. */
+
+#define MODULE_INITIALIZED (m_pds.n_registrants > 0) /**< Expression which is true when the module is initialized. */
+
+/**@brief Macro for verifying that the module is initialized. It will cause the function to return
+ *        @ref NRF_ERROR_INVALID_STATE if not.
+ */
+#define VERIFY_MODULE_INITIALIZED()         \
+do                                          \
+{                                           \
+    if (!MODULE_INITIALIZED)                \
+    {                                       \
+        return NRF_ERROR_INVALID_STATE;     \
+    }                                       \
+} while(0)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the function to return
+ *        if not.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID()    \
+do                                          \
+{                                           \
+    if (!MODULE_INITIALIZED)                \
+    {                                       \
+        return;                             \
+    }                                       \
+} while(0)
+
+
+/**@brief Macro for verifying that the param is not NULL. It will cause the function to return
+ *        if not.
+ *
+ * @param[in] param  The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL(param)        \
+do                                          \
+{                                           \
+    if (param == NULL)                      \
+    {                                       \
+        return NRF_ERROR_NULL;              \
+    }                                       \
+} while(0)
+
+
+/**@brief Macro for verifying that param is not zero. It will cause the function to return
+ *        if not.
+ *
+ * @param[in] param  The variable to check if is zero.
+ */
+#define VERIFY_PARAM_NOT_ZERO(param)        \
+do                                          \
+{                                           \
+    if (param == 0)                         \
+    {                                       \
+        return NRF_ERROR_NULL;              \
+    }                                       \
+} while(0)
+
+
+/**@brief Macro for verifying that the peer id is within a valid range
+ *
+ * @param[in]   id      The peer data id to check.
+ */
+#define VERIFY_PEER_ID_IN_RANGE(id)         \
+do                                          \
+{                                           \
+    if ((id >= PM_PEER_ID_N_AVAILABLE_IDS)) \
+    {                                       \
+        return NRF_ERROR_INVALID_PARAM;     \
+    }                                       \
+} while (0)
+
+
+/**@brief Macro for verifying that the peer data id is withing a valid range
+ *
+ * @param[in]   id      The peer data id to check.
+ */
+#define VERIFY_PEER_DATA_ID_IN_RANGE(id)    \
+do                                          \
+{                                           \
+    if (!PM_PEER_DATA_ID_IS_VALID(id))      \
+    {                                       \
+        return NRF_ERROR_INVALID_PARAM;     \
+    }                                       \
+} while (0)
+
+
+#define PEER_IDS_INITIALIZE()               \
+do                                          \
+{                                           \
+    if (!m_pds.peer_ids_initialized)        \
+    {                                       \
+        peer_ids_init();                    \
+    }                                       \
+} while (0)
+
+
+typedef struct
+{
+    bool                peer_ids_initialized;
+    pds_evt_handler_t   evt_handlers[MAX_REGISTRANTS];
+    uint8_t             n_registrants;
+} pds_t;
+
+static pds_t m_pds = {.n_registrants = 0};
+
+static void internal_state_reset(pds_t * p_pds)
+{
+    memset(p_pds, 0, sizeof(pds_t));
+}
+
+/**@brief Function for dispatching outbound events to all registered event handlers.
+ *
+ * @param[in]  p_event  The event to dispatch.
+ */
+static void pds_evt_send(pds_evt_t * p_event)
+{
+    for (int i = 0; i < m_pds.n_registrants; i++)
+    {
+        m_pds.evt_handlers[i](p_event);
+    }
+}
+
+/**@brief Function to convert peer id to instance id
+ *
+ * @param[in] peer_id   Peer id to convert to instance id
+ *
+ * @return  Value as instance id
+ */
+static fds_instance_id_t convert_peer_id_to_instance_id(pm_peer_id_t peer_id)
+{
+    return (fds_instance_id_t)(peer_id + peer_id_to_instance_id);
+}
+
+/**@brief Function to convert peer data id to type id
+ *
+ * @param[in]   peer_data_id    Peer data id to convert to type_id
+ *
+ * @return Value as type id
+ */
+static fds_type_id_t convert_peer_data_id_to_type_id(pm_peer_data_id_t peer_data_id)
+{
+    return (fds_type_id_t)peer_data_id + (fds_type_id_t)peer_data_id_to_type_id;
+}
+
+
+/**@brief Function to convert peer data id to type id
+ *
+ * @param[in]   peer_data_id    Peer data id to convert to type_id
+ *
+ * @return Value as type id
+ */
+static pm_peer_id_t convert_instance_id_to_peer_id(fds_instance_id_t instance_id)
+{
+    return (pm_peer_id_t)(instance_id + instance_id_to_peer_id);
+}
+
+
+/**@brief Function to type id to peer data id
+ *
+ * @param[in]   type_id    Type id to convert to peer data id
+ *
+ * @return Value as peer data id
+ */
+static pm_peer_data_id_t convert_type_id_to_peer_data_id(fds_type_id_t type_id)
+{
+    return (pm_peer_data_id_t)(type_id + instance_id_to_peer_id);
+}
+
+
+static ret_code_t find_fds_item(pm_peer_id_t              peer_id,
+                                pm_peer_data_id_t         data_id,
+                                fds_record_desc_t * const p_desc)
+{
+    fds_find_token_t find_tok;
+
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+    // pp_record verified outside
+
+    fds_type_id_t       type_id     = convert_peer_data_id_to_type_id(data_id);
+    fds_instance_id_t   instance_id = convert_peer_id_to_instance_id(peer_id);
+
+    return fds_find(type_id, instance_id, p_desc, &find_tok);
+}
+
+
+static void peer_ids_init()
+{
+    fds_record_t            record;
+    fds_record_desc_t       record_desc;
+    fds_find_token_t        find_tok;
+    fds_type_id_t     const type_id = convert_peer_data_id_to_type_id(PM_PEER_DATA_ID_BONDING);
+    pm_peer_id_t            peer_id;
+
+    if (!m_pds.peer_ids_initialized)
+    {
+        while(fds_find_by_type(type_id, &record_desc, &find_tok) == NRF_SUCCESS)
+        {
+            fds_open(&record_desc, &record);
+            fds_close(&record_desc);
+            peer_id = convert_instance_id_to_peer_id(record.header.ic.instance);
+            peer_id_allocate(peer_id);
+        }
+
+        m_pds.peer_ids_initialized = true;
+    }
+}
+
+//uint32_t size_pad_to_mult_of_four(uint32_t unpadded_size)
+//{
+//    return (unpadded_size + 3) & 3;
+//}
+
+static void fds_evt_handler(ret_code_t          result,
+                            fds_cmd_id_t        cmd,
+                            fds_record_id_t     record_id,
+                            fds_record_key_t    record_key
+                            /*fds_record_t  const * const p_record*/)
+{
+    pds_evt_t evt;
+    switch(cmd)
+    {
+        case FDS_CMD_INIT:
+
+            break;
+
+        case FDS_CMD_UPDATE:
+        case FDS_CMD_WRITE:
+            evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
+            evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_STORED : PDS_EVT_ERROR_STORE;
+            evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
+            evt.store_token = record_id;
+            pds_evt_send(&evt);
+            break;
+
+        case FDS_CMD_CLEAR:
+            evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
+            evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_CLEARED : PDS_EVT_ERROR_CLEAR;
+            evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
+            evt.store_token = record_id;
+            pds_evt_send(&evt);
+            break;
+
+        case FDS_CMD_CLEAR_INST:
+            {
+                if ((record_key.type     == FDS_TYPE_ID_INVALID) &&
+                    (record_key.instance != FDS_TYPE_ID_INVALID))
+                {
+                    pm_peer_id_t peer_id = convert_instance_id_to_peer_id(record_key.instance);
+
+                    evt.peer_id = peer_id;
+                    evt.data_id = PM_PEER_DATA_ID_INVALID;
+                    if (result == NRF_SUCCESS)
+                    {
+                        evt.evt_id = PDS_EVT_PEER_ID_CLEAR;
+                        peer_id_free(peer_id);
+                    }
+                    else
+                    {
+                        evt.evt_id = PDS_EVT_ERROR_PEER_ID_CLEAR;
+                    }
+                }
+                else
+                {
+                    // TODO: Not supported yet (clear many without clearing peer_id)
+                }
+
+                pds_evt_send(&evt);
+            }
+            break;
+
+        case FDS_CMD_GC:
+            evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
+            evt.evt_id = PDS_EVT_COMPRESSED;
+            evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
+            evt.store_token = record_id;
+            pds_evt_send(&evt);
+            break;
+
+        default:
+
+            break;
+    }
+}
+
+
+ret_code_t pds_register(pds_evt_handler_t evt_handler)
+{
+    if (m_pds.n_registrants >= MAX_REGISTRANTS)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    VERIFY_PARAM_NOT_NULL(evt_handler);
+
+    if (!MODULE_INITIALIZED)
+    {
+        ret_code_t retval;
+        internal_state_reset(&m_pds);
+        peer_id_init();
+
+        fds_cb_t cb = fds_evt_handler;
+        retval = fds_register(cb);
+        if(retval != NRF_SUCCESS)
+        {
+            return retval;
+        }
+
+        retval = fds_init();
+        if(retval != NRF_SUCCESS)
+        {
+            return retval;
+        }
+    }
+
+    m_pds.evt_handlers[m_pds.n_registrants] = evt_handler;
+    m_pds.n_registrants += 1;
+
+    return NRF_SUCCESS;
+
+}
+
+
+ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t            peer_id,
+                                      pm_peer_data_id_t       data_id,
+                                      pm_peer_data_flash_t  * p_data,
+                                      pm_store_token_t      * p_token)
+{
+    ret_code_t retval;
+
+    fds_record_t      record;
+    fds_record_desc_t record_desc;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+
+    retval = find_fds_item(peer_id, data_id, &record_desc);
+    if (retval != NRF_SUCCESS)
+    {
+        return retval;
+    }
+
+    // Shouldn't fail, unless record is cleared.
+    fds_open(&record_desc, &record);
+    // No need to keep it open, since we are not reading.
+    fds_close(&record_desc);
+
+    //NRF_LOG_PRINTF("Found item with peer_id: %d, data_id: %d, Address: %p\r\n", record.p_data);
+
+    if (p_data != NULL)
+    {
+        p_data->data_type    = data_id;
+        p_data->length_words = record.header.tl.length_words;
+
+        p_data->data.p_application_data = (uint8_t const*)record.p_data;
+    }
+
+    if (p_token != NULL)
+    {
+        *p_token = (uint32_t)record.header.id;
+    }
+
+    return retval;
+}
+
+
+ret_code_t pds_peer_data_lock(pm_store_token_t store_token)
+{
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_ZERO(store_token);
+
+    // TODO: Not implemented yet in fds
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t pds_peer_data_verify(pm_store_token_t store_token)
+{
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_ZERO(store_token);
+
+    // TODO: Not implemented yet in fds
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t pds_peer_data_read(pm_peer_id_t          peer_id,
+                              pm_peer_data_id_t     data_id,
+                              pm_peer_data_t      * p_data,
+                              fds_length_t        * p_len_words)
+{
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+    VERIFY_PARAM_NOT_NULL(p_len_words);
+    VERIFY_PARAM_NOT_NULL(p_data);
+
+    ret_code_t err_code;
+    pm_peer_data_flash_t peer_data_flash;
+
+    err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &peer_data_flash, NULL);
+
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    if ((*p_len_words) == 0)
+    {
+        (*p_len_words) = peer_data_flash.length_words;
+        return NRF_SUCCESS;
+    }
+    else if ((*p_len_words) < peer_data_flash.length_words)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    VERIFY_PARAM_NOT_NULL(p_data->data.p_application_data);
+
+    err_code = peer_data_deserialize(&peer_data_flash, p_data);
+
+    return err_code;
+}
+
+
+ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data,
+                                       pm_prepare_token_t         * p_prepare_token)
+{
+    ret_code_t retval;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_NULL(p_peer_data);
+    VERIFY_PARAM_NOT_NULL(p_prepare_token);
+    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
+
+    retval = fds_reserve((fds_write_token_t*)p_prepare_token, p_peer_data->length_words);
+    return retval;
+}
+
+
+ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token)
+{
+    ret_code_t retval;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_ZERO(prepare_token);
+
+    retval = fds_reserve_cancel((fds_write_token_t*)&prepare_token);
+    return retval;
+}
+
+
+ret_code_t pds_peer_data_write_prepared(pm_peer_id_t                    peer_id,
+                                        pm_peer_data_const_t    const * p_peer_data,
+                                        pm_prepare_token_t              prepare_token,
+                                        pm_store_token_t              * p_store_token)
+{
+    ret_code_t         retval;
+    fds_record_desc_t  record_desc;
+    fds_record_key_t   record_key;
+    fds_record_chunk_t chunks[2];
+    uint16_t           n_chunks;
+
+    VERIFY_MODULE_INITIALIZED();
+    //VERIFY_PARAM_NOT_ZERO(prepare_token);
+    VERIFY_PARAM_NOT_NULL(p_peer_data);
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
+
+    // Fill in the keys.
+    record_key.type     = convert_peer_data_id_to_type_id(p_peer_data->data_type);
+    record_key.instance = convert_peer_id_to_instance_id(peer_id);
+
+    // Create chunks.
+    peer_data_parts_get(p_peer_data, chunks, &n_chunks);
+
+    retval = fds_write_reserved((fds_write_token_t*)&prepare_token, &record_desc,
+                                record_key, n_chunks, chunks);
+
+    if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
+    {
+        fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
+    }
+
+    return retval;
+}
+
+
+ret_code_t pds_peer_data_write(pm_peer_id_t                 peer_id,
+                               pm_peer_data_const_t const * p_peer_data,
+                               pm_store_token_t           * p_store_token)
+{
+    ret_code_t          retval;
+    fds_record_desc_t   record_desc;
+    fds_record_key_t    record_key;
+    fds_record_chunk_t  chunks[2];
+    uint16_t            n_chunks;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
+
+    // Fill in the keys.
+    record_key.type     = convert_peer_data_id_to_type_id(p_peer_data->data_type);
+    record_key.instance = convert_peer_id_to_instance_id(peer_id);
+
+    // Create chunks
+    peer_data_parts_get(p_peer_data, chunks, &n_chunks);
+
+    // Request write
+    retval = fds_write(&record_desc, record_key, n_chunks, chunks);
+
+    if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
+    {
+        fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
+    }
+
+    return retval;
+}
+
+
+ret_code_t pds_peer_data_update(pm_peer_id_t                 peer_id,
+                                pm_peer_data_const_t const * p_peer_data,
+                                pm_store_token_t             old_token,
+                                pm_store_token_t           * p_store_token)
+{
+    ret_code_t         retval;
+    fds_record_desc_t  record_desc;
+    fds_record_key_t   record_key;
+    fds_record_chunk_t chunks[2];
+    uint16_t           n_chunks;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
+    VERIFY_PARAM_NOT_NULL(p_peer_data);
+
+    record_key.type     = convert_peer_data_id_to_type_id(p_peer_data->data_type);
+    record_key.instance = convert_peer_id_to_instance_id(peer_id);
+
+    // Create chunks
+    peer_data_parts_get(p_peer_data, chunks, &n_chunks);
+
+    fds_descriptor_from_rec_id(&record_desc, (fds_record_id_t)old_token);
+
+    retval = fds_update(&record_desc, record_key, n_chunks, chunks);
+
+    if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
+    {
+        fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
+    }
+
+    return retval;
+}
+
+ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+    ret_code_t        retval;
+    fds_type_id_t     type_id;
+    fds_instance_id_t instance_id;
+    fds_record_desc_t record_desc;
+    fds_find_token_t  find_tok;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+
+    type_id     = convert_peer_data_id_to_type_id(data_id);
+    instance_id = convert_peer_id_to_instance_id(peer_id);
+
+    retval = fds_find(type_id, instance_id, &record_desc, &find_tok);
+    if(retval != NRF_SUCCESS)
+    {
+        return retval;
+    }
+
+    retval = fds_clear(&record_desc);
+    return retval;
+}
+
+
+pm_peer_id_t pds_peer_id_allocate(void)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return PM_PEER_ID_INVALID;
+    }
+    PEER_IDS_INITIALIZE();
+    return peer_id_allocate(PM_PEER_ID_INVALID);
+}
+
+
+ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
+{
+    ret_code_t retval;
+    fds_instance_id_t instance_id;
+
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PEER_ID_IN_RANGE(peer_id);
+    PEER_IDS_INITIALIZE();
+
+    instance_id = convert_peer_id_to_instance_id(peer_id);
+
+    retval = fds_clear_by_instance(instance_id);
+    return retval;
+}
+
+
+bool pds_peer_id_is_allocated(pm_peer_id_t peer_id)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return false;
+    }
+    PEER_IDS_INITIALIZE();
+
+    return peer_id_is_allocated(peer_id);
+}
+
+
+pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return PM_PEER_ID_INVALID;
+    }
+    PEER_IDS_INITIALIZE();
+
+    return peer_id_next_id_get(prev_peer_id);
+}
+
+
+uint32_t pds_n_peers(void)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return 0;
+    }
+    PEER_IDS_INITIALIZE();
+    return peer_id_n_ids();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_data_storage.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_DATA_STORAGE_H__
+#define PEER_DATA_STORAGE_H__
+
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+#include "fds.h"
+
+
+/**
+ * @defgroup peer_data_storage Peer Data Storage
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides a Peer Manager-specific API
+ *        to the persistent storage.
+ */
+
+#define PDS_PREPARE_TOKEN_INVALID 0
+#define PDS_STORE_TOKEN_INVALID   0
+
+
+typedef enum
+{
+    peer_id_to_instance_id  = 16384,
+    instance_id_to_peer_id  = -peer_id_to_instance_id,
+    peer_data_id_to_type_id = 32768,
+    type_id_to_peer_data_id = -peer_data_id_to_type_id,
+} pds_convert_t;
+
+
+/**@brief The types of events that can come from the peer_data_storage module.
+ */
+typedef enum
+{
+    PDS_EVT_STORED,                 /**< The specified data has been successfully stored. */
+    PDS_EVT_CLEARED,                /**< The specified data has been successfully cleared. */
+    PDS_EVT_PEER_ID_CLEAR,          /**< The peer id has been successfully cleared. */
+    PDS_EVT_ERROR_STORE,            /**< The specified data could not be stored. */
+    PDS_EVT_ERROR_CLEAR,            /**< The specified data could not be cleared. */
+    PDS_EVT_ERROR_PEER_ID_CLEAR,    /**< The peer id has been successfully cleared. */
+    PDS_EVT_COMPRESSED,             /**< A compress procedure has finished successfully. */
+} pds_evt_id_t;
+
+
+/**@brief Events that can come from the peer_data_storage module.
+ */
+typedef struct
+{
+    pds_evt_id_t      evt_id;       /**< The type of event. */
+    pm_peer_id_t      peer_id;      /**< The peer the event pertains to. */
+    pm_peer_data_id_t data_id;      /**< The data the event pertains to. */
+    pm_store_token_t  store_token;
+} pds_evt_t;
+
+
+/**@brief Event handler for events from the peer_data_storage module.
+ *
+ * @param[in]  event    The event that has happened.
+ * @param[in]  peer_id  The id of the peer the event pertains to.
+ * @param[in]  flags    The data the event pertains to.
+ */
+typedef void (*pds_evt_handler_t)(pds_evt_t const * p_event);
+
+
+/**@brief Function for registering for events from the peer database.
+ *
+ * @note This function will initialize the module if it is not already initialized.
+ *
+ * @param[in]  evt_handler  Event handler to register.
+ *
+ * @retval NRF_SUCCESS              Registration successful.
+ * @retval NRF_ERROR_NO_MEM         No more event handlers can be registered.
+ * @retval NRF_ERROR_NULL           evt_handler was NULL.
+ * @retval NRF_ERROR_INVALID_PARAM  Unexpected return code from @ref pm_buffer_init.
+ * @retval NRF_ERROR_INVALID_STATE  FDS has not been initalized.
+ */
+ret_code_t pds_register(pds_evt_handler_t evt_handler);
+
+
+#if 0
+/**@brief Function for initializing Peer Data storage and registering a
+ * callback for its events.
+ *
+ * @param[in] evt_handler  Event handler to register.
+ *
+ * @retval NRF_SUCCESS              Registration successful.
+ * @retval NRF_ERROR_NO_MEM         No more event handlers can be registered.
+ * @retval NRF_ERROR_NULL           evt_handler was NULL.
+ * @retval NRF_ERROR_INVALID_STATE  FDS has not completed initialization.
+ */
+ret_code_t pds_init(pds_evt_handler_t evt_handler);
+#endif
+
+/**@brief Function for retrieving a direct pointer to peer data in persistent storage.
+ *
+ * @param[in]  peer_id      The id of the peer whose data to read.
+ * @param[in]  data_id      Which data to get.
+ * @param[out] p_data       The peer data pointer.
+ * @param[out] p_token      Token that can be used to lock data in flash and check data validity.
+ *
+ * @retval NRF_SUCCESS              The pointer was successfully retrieved.
+ * @retval NRF_ERROR_INVALID_PARAM  Invalid data_id.
+ * @retval NRF_ERROR_NULL           p_data was NULL.
+ * @retval NRF_ERROR_NOT_FOUND      The requested data was not found in persistent storage.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t            peer_id,
+                                      pm_peer_data_id_t       data_id,
+                                      pm_peer_data_flash_t  * p_data,
+                                      pm_store_token_t      * p_token);
+
+/**@brief Function to lock the flash data (to defer compression from invalidating data)
+ *
+ * @param[in]   store_token     The token representing the item to lock
+ *
+ */
+ret_code_t pds_peer_data_lock(pm_store_token_t store_token);
+
+
+/**@brief Function to verify flash data integrity
+ *
+ * @param[in]   store_token     The token representing the item to lock
+ *
+ * @retval NRF_SUCCESS              The data integrity is valid.
+ * @retval NRF_ERROR_NULL           The token is invalid.
+ * @retval NRF_ERROR_INVALID_DATA   The data integrity is not valid.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t  pds_peer_data_verify(pm_store_token_t store_token);
+
+
+/**@brief Function for retrieving peer data from persistent storage by making a copy
+ *
+ * @param[in]       peer_id     The id of the peer whose data to read.
+ * @param[in]       data_id     Which piece of data to read.
+ * @param[out]      p_data      Pointer to the peer data.
+ * @param[in,out]   p_len_words Length available to copy to (in words).
+ *                              If set to NULL, then no copy will be made and the
+ *                              length will be reflected in p_len_words after the call returns.
+ *
+ * @retval NRF_SUCCESS              The read was successful.
+ * @retval NRF_ERROR_INVALID_PARAM  Invalid data_id.
+ * @retval NRF_ERROR_NULL           data contained a NULL pointer.
+ * @retval NRF_ERROR_NOT_FOUND      The requested data was not found in persistent storage.
+ * @retval NRF_ERROR_NO_MEM         The length of stored data too large to copy out
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pds_peer_data_read(pm_peer_id_t          peer_id,
+                              pm_peer_data_id_t     data_id,
+                              pm_peer_data_t      * p_data,
+                              fds_length_t        * p_len_words);
+
+
+/**@brief Function for preparing persistent storage for a write.
+ *
+ * @details If this call succeeds, space is reserved in persistent storage, so the write will fit.
+ *
+ * @note If space has already been prepared for this peer_id/data_id pair, no new space will be
+ *       reserved, unless the previous reservation had too small size.
+ *
+ * @param[in]  p_peer_data      Data to prepare for. The data needs not be ready, but length and type
+ *                              values must.
+ * @param[out] p_prepare_token  A token identifying the prepared memory area.
+ *
+ * @retval NRF_SUCCESS               The call was successful.
+ * @retval NRF_ERROR_INVALID_PARAM   Invalid data ID.
+ * @retval NRF_ERROR_INVALID_LENGTH  Data length above the maximum allowed.
+ * @retval NRF_ERROR_NO_MEM          No space available in persistent storage.
+ * @retval NRF_ERROR_INVALID_STATE   Module is not initialized.
+ */
+ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data,
+                                       pm_prepare_token_t         * p_prepare_token);
+
+
+/**@brief Function for undoing a previous call to @ref pds_peer_data_write_prepare.
+ *
+ * @param[in]  prepare_token  A token identifying the prepared memory area to cancel.
+ *
+ * @retval NRF_SUCCESS               The call was successful.
+ * @retval NRF_ERROR_NOT_FOUND       Invalid peer ID and/or prepare token.
+ * @retval NRF_ERROR_INVALID_STATE   Module is not initialized.
+ */
+ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token);
+
+
+/**@brief Function for writing prepared (reserved) peer data to persistent storage.
+ *
+ * @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE
+ *          event.
+ *
+ * @param[in]  peer_id        The id of the peer the data pertains to.
+ * @param[in]  p_peer_data    The peer data.
+ * @param[in]  prepare_token  A token identifying the prepared memory area to write into. If
+ *                            the prepare token is invalid, e.g. PDS_PREPARE_TOKEN_INVALID, the
+ *                            prepare/write sequence will happen atomically.
+ * @param[out] p_store_token  A token identifying this particular store operation. The token can be
+ *                            used to identify events pertaining to this operation.
+ *
+ * @retval NRF_SUCCESS               The write was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM   Invalid data ID or store_flags.
+ * @retval NRF_ERROR_INVALID_LENGTH  Length of data longer than in prepare call.
+ * @retval NRF_ERROR_NULL            data contained a NULL pointer.
+ * @retval NRF_ERROR_NO_MEM          No space available in persistent storage. This can only happen
+ *                                   if p_prepare_token is NULL.
+ * @retval NRF_ERROR_BUSY            FDS or underlying modules are busy and can't take any
+ *                                   more requests
+ * @retval NRF_ERROR_INVALID_STATE   Module is not initialized.
+ */
+ret_code_t pds_peer_data_write_prepared(pm_peer_id_t                    peer_id,
+                                        pm_peer_data_const_t    const * p_peer_data,
+                                        pm_prepare_token_t              prepare_token,
+                                        pm_store_token_t              * p_store_token);
+
+
+/**@brief Function for writing peer data to persistent storage.
+ *
+ * @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE
+ *          event.
+ *
+ * @param[in]  peer_id        The id of the peer the data pertains to.
+ * @param[in]  p_peer_data    The peer data.
+ * @param[out] p_store_token  A token identifying this particular store operation. The token can be
+ *                            used to identify events pertaining to this operation.
+ *
+ * @retval NRF_SUCCESS               The write was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM   Invalid data ID or store_flags.
+ * @retval NRF_ERROR_NULL            Data contained a NULL pointer.
+ * @retval NRF_ERROR_NO_MEM          No space available in persistent storage. This can only happen
+ *                                   if p_prepare_token is NULL.
+ * @retval NRF_ERROR_BUSY            FDS or underlying modules are busy and can't take any
+ *                                   more requests
+ * @retval NRF_ERROR_INVALID_STATE   Module is not initialized.
+ */
+ret_code_t pds_peer_data_write(pm_peer_id_t                 peer_id,
+                               pm_peer_data_const_t const * p_peer_data,
+                               pm_store_token_t           * p_store_token);
+
+
+/**@brief Function for updating currently stored peer data to a new version
+ *
+ * @details Updating happens asynchronously.
+ *          Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token
+ *          and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token
+ *
+ * @param[in]   peer_id             The peer which the data is associated to.
+ * @param[in]   peer_data           New data.
+ * @param[in]   old_token           Store token for the old data.
+ * @param[out]  p_store_token       Store token for the new data.
+ *
+ * @retval NRF_SUCESS               The update was initiated successfully
+ * @retval NRF_ERROR_NOT_FOUND      The old store token was invalid.
+ * @retval NRF_ERROR_NULL           Data contained a NULL pointer.
+ * @retval NRF_ERROR_NO_MEM         No space available in persistent storage.
+ * @retval NRF_ERROR_BUSY           FDS or underlying modules are busy and can't take any
+ *                                  more requests
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pds_peer_data_update(pm_peer_id_t                 peer_id,
+                                pm_peer_data_const_t const * peer_data,
+                                pm_store_token_t             old_token,
+                                pm_store_token_t           * p_store_token);
+
+
+/**@brief Function for clearing peer data from persistent storage.
+ *
+ * @details Clearing happens asynchronously. Expect a @ref PDS_EVT_CLEARED or @ref PDS_EVT_ERROR_CLEAR
+ *          event.
+ *
+ * @param[in]  peer_id  The id of the peer the data pertains to.
+ * @param[in]  data_id  Which data to clear.
+ *
+ * @retval NRF_SUCCESS              The clear was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID or was invalid.
+ * @retval NRF_ERROR_NOT_FOUND      Nothing to clear for this peer ID.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for claiming an unused peer ID.
+ *
+ * @return  The first unused peer ID.
+ * @retval  PM_PEER_ID_INVALID  If no peer ID is available or module is not initialized.
+ */
+pm_peer_id_t pds_peer_id_allocate(void);
+
+
+/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent
+ *        storage.
+ *
+ * @param[in]  peer_id  Peer ID to free.
+ *
+ * @retval NRF_SUCCESS          The clear was initiated successfully
+ * @retval NRF_ERROR_BUSY       Another peer_id clear was already requested or fds queue full
+ */
+ret_code_t pds_peer_id_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for finding out whether a peer ID is in use.
+ *
+ * @param[in]  peer_id  The peer ID to inquire about.
+ *
+ * @retval  true   peer_id is in use.
+ * @retval  false  peer_id is free, or the module is not initialized.
+ */
+bool pds_peer_id_is_allocated(pm_peer_id_t peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ *        used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ *       peer ID.
+ *
+ * @param[in]  prev_peer_id  The previous peer ID.
+ *
+ * @return  The next peer ID.
+ * @return  The first ordinary peer ID  if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval  PM_PEER_ID_INVALID          if prev_peer_id was the last ordinary peer ID or the module
+ *                                      is not initialized.
+ */
+pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ *        in persistent storage.
+ *
+ * @return  The number of valid peer IDs, or 0 if module is not initialized.
+ */
+uint32_t pds_n_peers(void);
+
+
+/** @} */
+
+#endif /* PEER_DATA_STORAGE_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_database.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "peer_database.h"
+
+#include <string.h>
+#include "peer_manager_types.h"
+#include "peer_data_storage.h"
+#include "pm_buffer.h"
+
+
+#define MAX_REGISTRANTS    6                         /**< The number of user that can register with the module. */
+
+#define MODULE_INITIALIZED (m_pdb.n_registrants > 0) /**< Expression which is true when the module is initialized. */
+
+#define N_WRITE_BUFFERS        8                     /**< The number of write buffers available. */
+#define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS)     /**< The number of write buffer records. */
+
+/**@brief Macro for verifying that the module is initialized. It will cause the function to return
+ *        @ref NRF_ERROR_INVALID_STATE if not.
+ */
+#define VERIFY_MODULE_INITIALIZED()     \
+do                                      \
+{                                       \
+    if (!MODULE_INITIALIZED)            \
+    {                                   \
+        return NRF_ERROR_INVALID_STATE; \
+    }                                   \
+} while(0)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the function to return
+ *        if not.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID()\
+do                                      \
+{                                       \
+    if (!MODULE_INITIALIZED)            \
+    {                                   \
+        return;                         \
+    }                                   \
+} while(0)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the function to return
+ *        if not.
+ *
+ * @param[in] param  The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL(param)    \
+do                                      \
+{                                       \
+    if (param == NULL)                  \
+    {                                   \
+        return NRF_ERROR_NULL;          \
+    }                                   \
+} while(0)
+
+
+typedef struct
+{
+    pm_peer_id_t        peer_id;
+    pm_peer_data_id_t   data_id;
+    uint8_t             buffer_block_id;
+    uint8_t             store_busy       : 1;
+    uint8_t             store_flash_full : 1;
+    uint8_t             store_requested  : 1;
+    uint32_t            n_bufs;
+    pm_prepare_token_t  prepare_token;
+    pm_store_token_t    store_token;
+} pdb_buffer_record_t;
+
+typedef struct
+{
+    pdb_evt_handler_t   evt_handlers[MAX_REGISTRANTS];
+    uint8_t             n_registrants;
+    pm_buffer_t         write_buffer;
+    pdb_buffer_record_t write_buffer_records[N_WRITE_BUFFER_RECORDS];
+    uint32_t            n_writes;
+} pdb_t;
+
+static pdb_t m_pdb = {.n_registrants = 0};
+
+
+/**@brief Function for invalidating a record of a write buffer allocation.
+ *
+ * @param[in]  p_record  The record to invalidate.
+ */
+static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record)
+{
+    p_record->peer_id          = PM_PEER_ID_INVALID;
+    p_record->data_id          = PM_PEER_DATA_ID_INVALID;
+    p_record->buffer_block_id  = BUFFER_INVALID_ID;
+    p_record->store_busy       = false;
+    p_record->store_flash_full = false;
+    p_record->store_requested  = false;
+    p_record->n_bufs           = 0;
+    p_record->prepare_token    = PDS_PREPARE_TOKEN_INVALID;
+    p_record->store_token      = PDS_STORE_TOKEN_INVALID;
+}
+
+
+/**@brief Function for finding a record of a write buffer allocation.
+ *
+ * @param[in]  peer_id  The peer ID in the record.
+ * @param[in]  data_id  The data ID in the record.
+ *
+ * @return  A pointer to the matching record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t      peer_id,
+                                                      pm_peer_data_id_t data_id)
+{
+    for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
+    {
+        if   ((m_pdb.write_buffer_records[i].peer_id == peer_id)
+           && (m_pdb.write_buffer_records[i].data_id == data_id))
+        {
+            return &m_pdb.write_buffer_records[i];
+        }
+    }
+    return NULL;
+}
+
+
+/**@brief Function for finding an available record for write buffer allocation.
+ *
+ * @return  A pointer to the available record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find_unused(void)
+{
+    return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID);
+}
+
+
+/**@brief Function for gracefully deactivating a write buffer record.
+ *
+ * @details This function will first release any buffers, then invalidate the record.
+ *
+ * @param[inout] p_write_buffer_record  The record to release.
+ *
+ * @return  A pointer to the matching record, or NULL if none was found.
+ */
+static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
+{
+    for (int i = 0; i < p_write_buffer_record->n_bufs; i++)
+    {
+        pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i);
+    }
+
+    write_buffer_record_invalidate(p_write_buffer_record);
+}
+
+
+static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_record, pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+    if (pp_write_buffer_record == NULL)
+    {
+        return;
+    }
+    *pp_write_buffer_record = write_buffer_record_find_unused();
+    if (*pp_write_buffer_record == NULL)
+    {
+        // This also means the buffer is full.
+        return;
+    }
+    (*pp_write_buffer_record)->peer_id = peer_id;
+    (*pp_write_buffer_record)->data_id = data_id;
+}
+
+
+/**@brief Function for dispatching outbound events to all registered event handlers.
+ *
+ * @param[in]  p_event  The event to dispatch.
+ */
+static void pdb_evt_send(pdb_evt_t * p_event)
+{
+    for (int i = 0; i < m_pdb.n_registrants; i++)
+    {
+        m_pdb.evt_handlers[i](p_event);
+    }
+}
+
+
+/**@brief Function for resetting the internal state of the Peer Database module.
+ *
+ * @param[out] p_event  The event to dispatch.
+ */
+static void internal_state_reset(pdb_t * pdb)
+{
+    memset(pdb, 0, sizeof(pdb_t));
+    for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
+    {
+        write_buffer_record_invalidate(&pdb->write_buffer_records[i]);
+    }
+}
+
+
+/**@brief Function for handling events from the Peer Data Storage module.
+ *
+ * @param[in]  p_event  The event to handle.
+ */
+static void pds_evt_handler(pds_evt_t const * p_event)
+{
+    ret_code_t            err_code;
+    pdb_buffer_record_t * p_write_buffer_record;
+    bool                  retry_flash_full = false;
+    pdb_evt_t             event =
+    {
+        .peer_id = p_event->peer_id,
+        .data_id = p_event->data_id,
+    };
+
+    p_write_buffer_record = write_buffer_record_find(p_event->peer_id, p_event->data_id);
+
+    switch (p_event->evt_id)
+    {
+        case PDS_EVT_STORED:
+            if (   (p_write_buffer_record != NULL)
+                //&& (p_write_buffer_record->store_token == p_event->store_token)
+                && (p_write_buffer_record->store_requested))
+            {
+                write_buffer_record_release(p_write_buffer_record);
+                event.evt_id = PDB_EVT_WRITE_BUF_STORED;
+                pdb_evt_send(&event);
+            }
+            else
+            {
+                event.evt_id = PDB_EVT_RAW_STORED;
+                pdb_evt_send(&event);
+            }
+            break;
+        case PDS_EVT_ERROR_STORE:
+            if (   (p_write_buffer_record != NULL)
+                && (p_write_buffer_record->store_token == p_event->store_token)
+                && (p_write_buffer_record->store_requested))
+            {
+                // Retry if internal buffer.
+                m_pdb.n_writes++;
+                p_write_buffer_record->store_requested = false;
+                p_write_buffer_record->store_busy      = true;
+            }
+            else
+            {
+                event.evt_id = PDB_EVT_RAW_STORE_FAILED;
+                pdb_evt_send(&event);
+            }
+            break;
+        case PDS_EVT_CLEARED:
+            event.evt_id = PDB_EVT_CLEARED;
+            pdb_evt_send(&event);
+            break;
+        case PDS_EVT_ERROR_CLEAR:
+            event.evt_id = PDB_EVT_CLEAR_FAILED;
+            pdb_evt_send(&event);
+            break;
+        case PDS_EVT_COMPRESSED:
+            retry_flash_full = true;
+            event.evt_id = PDB_EVT_COMPRESSED;
+            pdb_evt_send(&event);
+            break;
+        default:
+            break;
+    }
+
+    if (m_pdb.n_writes > 0)
+    {
+        for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
+        {
+            if  ((m_pdb.write_buffer_records[i].store_busy)
+              || (m_pdb.write_buffer_records[i].store_flash_full && retry_flash_full))
+            {
+                err_code = pdb_write_buf_store(m_pdb.write_buffer_records[i].peer_id,
+                                               m_pdb.write_buffer_records[i].data_id);
+                if (err_code != NRF_SUCCESS)
+                {
+                    event.peer_id = m_pdb.write_buffer_records[i].peer_id;
+                    event.data_id = m_pdb.write_buffer_records[i].data_id;
+                    if (err_code == NRF_ERROR_NO_MEM)
+                    {
+                        event.evt_id = PDB_EVT_ERROR_NO_MEM;
+                    }
+                    else
+                    {
+                        event.evt_id = PDB_EVT_ERROR_UNEXPECTED;
+                    }
+
+                    pdb_evt_send(&event);
+                    break;
+                }
+            }
+        }
+    }
+}
+
+
+ret_code_t pdb_register(pdb_evt_handler_t evt_handler)
+{
+    if (m_pdb.n_registrants >= MAX_REGISTRANTS)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    VERIFY_PARAM_NOT_NULL(evt_handler);
+
+    if (!MODULE_INITIALIZED)
+    {
+        ret_code_t err_code;
+
+        internal_state_reset(&m_pdb);
+        err_code = pds_register(pds_evt_handler);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+        PM_BUFFER_INIT(&m_pdb.write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, err_code);
+        if (err_code != NRF_SUCCESS)
+        {
+            return err_code;
+        }
+    }
+
+    m_pdb.evt_handlers[m_pdb.n_registrants] = evt_handler;
+    m_pdb.n_registrants += 1;
+
+    return NRF_SUCCESS;
+}
+
+
+pm_peer_id_t pdb_peer_allocate(void)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return PM_PEER_ID_INVALID;
+    }
+
+    return pds_peer_id_allocate();
+}
+
+
+ret_code_t pdb_peer_free(pm_peer_id_t peer_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    return pds_peer_id_free(peer_id);
+}
+
+
+ret_code_t pdb_read_buf_get(pm_peer_id_t           peer_id,
+                            pm_peer_data_id_t      data_id,
+                            pm_peer_data_flash_t * p_peer_data,
+                            pm_store_token_t     * p_token)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    return pds_peer_data_read_ptr_get(peer_id, data_id, p_peer_data, p_token);
+}
+
+
+static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs)
+{
+    uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE;
+    p_peer_data->data_type    = data_id;
+
+    switch(p_peer_data->data_type)
+    {
+        case PM_PEER_DATA_ID_BONDING:
+            p_peer_data->data.p_bonding_data = (pm_peer_data_bonding_t *)p_buffer_memory;
+            p_peer_data->length_words = PM_BONDING_DATA_N_WORDS();
+            break;
+        case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+            p_peer_data->data.p_service_changed_pending = (bool *)p_buffer_memory;
+            p_peer_data->length_words = PM_SC_STATE_N_WORDS();
+            break;
+        case PM_PEER_DATA_ID_GATT_LOCAL:
+            p_peer_data->data.p_local_gatt_db = (pm_peer_data_local_gatt_db_t *)p_buffer_memory;
+            p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(n_bytes);
+            break;
+        case PM_PEER_DATA_ID_GATT_REMOTE:
+            p_peer_data->data.p_remote_gatt_db = (pm_peer_data_remote_gatt_db_t *)p_buffer_memory;
+            p_peer_data->length_words = PM_REMOTE_DB_N_WORDS(n_bytes / sizeof(ble_gatt_db_srv_t));
+            break;
+        case PM_PEER_DATA_ID_APPLICATION:
+            p_peer_data->data.p_application_data = p_buffer_memory;
+            p_peer_data->length_words = PM_N_WORDS(n_bytes);
+            break;
+        default:
+            p_peer_data->length_words = 0;
+            break;
+    }
+}
+
+
+static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id,  uint8_t * p_buffer_memory, uint32_t n_bufs)
+{
+    peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs);
+}
+
+
+ret_code_t pdb_write_buf_get(pm_peer_id_t       peer_id,
+                             pm_peer_data_id_t  data_id,
+                             uint32_t           n_bufs,
+                             pm_peer_data_t   * p_peer_data)
+{
+    VERIFY_MODULE_INITIALIZED();
+    VERIFY_PARAM_NOT_NULL(p_peer_data);
+    if (   !PM_PEER_DATA_ID_IS_VALID(data_id)
+        || (n_bufs == 0)
+        || (n_bufs > N_WRITE_BUFFERS)
+        || !pds_peer_id_is_allocated(peer_id))
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    pdb_buffer_record_t * write_buffer_record;
+    uint8_t             * p_buffer_memory;
+
+    write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+    if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs))
+    {
+        // @TODO: Copy?
+        // Existing buffer is too small.
+        for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++)
+        {
+            pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
+        }
+        write_buffer_record_invalidate(write_buffer_record);
+        write_buffer_record = NULL;
+    }
+    else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs)
+    {
+        // Release excess blocks.
+        for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++)
+        {
+            pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
+        }
+    }
+
+    if (write_buffer_record == NULL)
+    {
+        write_buffer_record_get(&write_buffer_record, peer_id, data_id);
+        if (write_buffer_record == NULL)
+        {
+            return NRF_ERROR_BUSY;
+        }
+    }
+
+    if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
+    {
+        write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs);
+
+        if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
+        {
+            write_buffer_record_invalidate(write_buffer_record);
+            return NRF_ERROR_BUSY;
+        }
+    }
+
+    write_buffer_record->n_bufs = n_bufs;
+
+    p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id);
+
+    if (p_buffer_memory == NULL)
+    {
+        return NRF_ERROR_INTERNAL;
+    }
+
+    peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
+    switch(data_id)
+    {
+        case PM_PEER_DATA_ID_BONDING:
+            /* No action needed. */
+            break;
+        case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+            /* No action needed. */
+            break;
+        case PM_PEER_DATA_ID_GATT_LOCAL:
+        {
+            uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t);
+            p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset];
+            p_peer_data->data.p_local_gatt_db->len    = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset;
+        }
+            break;
+        case PM_PEER_DATA_ID_GATT_REMOTE:
+        {
+            uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t);
+            p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]);
+            p_peer_data->data.p_remote_gatt_db->service_count
+                            = ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t);
+        }
+            break;
+        case PM_PEER_DATA_ID_APPLICATION:
+        {
+            p_peer_data->data.p_application_data = p_buffer_memory;
+        }
+            break;
+        default:
+            // Invalid data_id. This should have been picked up earlier.
+            return NRF_ERROR_INTERNAL;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    ret_code_t            err_code = NRF_SUCCESS;
+    pdb_buffer_record_t * p_write_buffer_record;
+    p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+    if (p_write_buffer_record == NULL)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+
+    if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID)
+    {
+        err_code = pds_peer_data_write_prepare_cancel(p_write_buffer_record->prepare_token);
+        if (err_code != NRF_SUCCESS)
+        {
+            err_code = NRF_ERROR_INTERNAL;
+        }
+    }
+
+    write_buffer_record_release(p_write_buffer_record);
+
+    return err_code;
+}
+
+
+ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    ret_code_t            err_code = NRF_SUCCESS;
+    pdb_buffer_record_t * p_write_buffer_record;
+    p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+    if (p_write_buffer_record == NULL)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+
+    if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID)
+    {
+        uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
+        pm_peer_data_const_t peer_data = {.data_type = data_id};
+
+        if (p_buffer_memory == NULL)
+        {
+            return NRF_ERROR_INTERNAL;
+        }
+
+        peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
+
+        err_code = pds_peer_data_write_prepare(&peer_data, &p_write_buffer_record->prepare_token);
+        if (err_code == NRF_ERROR_INVALID_LENGTH)
+        {
+            return NRF_ERROR_INTERNAL;
+        }
+    }
+
+    return err_code;
+}
+
+
+static ret_code_t write_or_update(pm_peer_id_t           peer_id,
+                                  pm_peer_data_id_t      data_id,
+                                  pm_peer_data_const_t * p_peer_data,
+                                  pm_store_token_t     * p_store_token,
+                                  pm_prepare_token_t     prepare_token)
+{
+    pm_peer_data_flash_t old_peer_data;
+    pm_store_token_t     old_store_token;
+    ret_code_t err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &old_peer_data, &old_store_token);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        pds_peer_data_write_prepare_cancel(prepare_token);
+        err_code = pds_peer_data_update(peer_id, p_peer_data, old_store_token, p_store_token);
+    }
+    else if (err_code == NRF_ERROR_NOT_FOUND)
+    {
+        if (prepare_token == PDS_PREPARE_TOKEN_INVALID)
+        {
+            err_code = pds_peer_data_write(peer_id, p_peer_data, p_store_token);
+        }
+        else
+        {
+            err_code = pds_peer_data_write_prepared(peer_id, p_peer_data, prepare_token, p_store_token);
+        }
+    }
+    return err_code;
+}
+
+
+ret_code_t pdb_write_buf_store(pm_peer_id_t      peer_id,
+                               pm_peer_data_id_t data_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    ret_code_t            err_code = NRF_SUCCESS;
+    pdb_buffer_record_t * p_write_buffer_record;
+    uint8_t             * p_buffer_memory;
+    pm_peer_data_const_t  peer_data = {.data_type = data_id};
+
+
+    p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+    if (p_write_buffer_record == NULL)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+
+    if (p_write_buffer_record->store_requested)
+    {
+        return NRF_SUCCESS;
+    }
+
+    p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
+
+    if (p_buffer_memory == NULL)
+    {
+        return NRF_ERROR_INTERNAL;
+    }
+
+    peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
+
+    switch (data_id)
+    {
+        case PM_PEER_DATA_ID_BONDING:
+            peer_data.length_words = PM_BONDING_DATA_N_WORDS();
+            break;
+        case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+            peer_data.length_words = PM_SC_STATE_N_WORDS();
+            break;
+        case PM_PEER_DATA_ID_GATT_LOCAL:
+            peer_data.length_words = PM_LOCAL_DB_N_WORDS(peer_data.data.p_local_gatt_db->len);
+            break;
+        case PM_PEER_DATA_ID_GATT_REMOTE:
+            peer_data.length_words = PM_REMOTE_DB_N_WORDS(peer_data.data.p_remote_gatt_db->service_count);
+            break;
+        case PM_PEER_DATA_ID_APPLICATION:
+            peer_data.length_words = PM_N_WORDS(p_write_buffer_record->n_bufs * PDB_WRITE_BUF_SIZE);
+            break;
+        default:
+            return NRF_ERROR_INVALID_PARAM;
+    }
+
+    err_code = write_or_update(peer_id, data_id, &peer_data, &p_write_buffer_record->store_token, p_write_buffer_record->prepare_token);
+
+    if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full)
+    {
+        m_pdb.n_writes--;
+    }
+
+    if (err_code == NRF_SUCCESS)
+    {
+        p_write_buffer_record->store_requested  = true;
+        p_write_buffer_record->store_busy       = false;
+        p_write_buffer_record->store_flash_full = false;
+    }
+    else
+    {
+        if (err_code == NRF_ERROR_BUSY)
+        {
+            m_pdb.n_writes++;
+            p_write_buffer_record->store_busy       = true;
+            p_write_buffer_record->store_flash_full = false;
+            err_code = NRF_SUCCESS;
+        }
+        else if (err_code == NRF_ERROR_NO_MEM)
+        {
+            m_pdb.n_writes++;
+            p_write_buffer_record->store_busy       = false;
+            p_write_buffer_record->store_flash_full = true;
+        }
+        else if ((err_code != NRF_ERROR_NO_MEM) && (err_code != NRF_ERROR_INVALID_PARAM))
+        {
+            err_code = NRF_ERROR_INTERNAL;
+        }
+    }
+
+    return err_code;
+}
+
+
+ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+
+    return pds_peer_data_clear(peer_id, data_id);
+}
+
+
+uint32_t pdb_n_peers(void)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return 0;
+    }
+
+    return pds_n_peers();
+}
+
+
+pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+    if (!MODULE_INITIALIZED)
+    {
+        return PM_PEER_ID_INVALID;
+    }
+
+    return pds_next_peer_id_get(prev_peer_id);
+}
+
+
+ret_code_t pdb_raw_read(pm_peer_id_t      peer_id,
+                        pm_peer_data_id_t data_id,
+                        pm_peer_data_t  * p_peer_data)
+{
+    VERIFY_MODULE_INITIALIZED();
+    return pds_peer_data_read(peer_id, data_id, p_peer_data, &p_peer_data->length_words);
+}
+
+
+ret_code_t pdb_raw_store(pm_peer_id_t           peer_id,
+                         pm_peer_data_const_t * p_peer_data,
+                         pm_store_token_t     * p_store_token)
+{
+    VERIFY_MODULE_INITIALIZED();
+    
+    return write_or_update(peer_id, p_peer_data->data_type, p_peer_data, p_store_token, PDS_PREPARE_TOKEN_INVALID);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_database.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_DATABASE_H__
+#define PEER_DATABASE_H__
+
+#include <stdint.h>
+#include "peer_manager_types.h"
+#include "sdk_errors.h"
+
+/**
+ * @defgroup peer_database Peer Database
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for simple management of reading and
+ *        writing of peer data into persistent storage.
+ *
+ */
+
+#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t))
+
+/**@brief Events that can come from the peer_database module.
+ */
+typedef enum
+{
+    PDB_EVT_WRITE_BUF_STORED,   /**< A pdb_write_buf_store operation has completed successfully. */
+    PDB_EVT_RAW_STORED,         /**< A pdb_raw_store operation has completed successfully. */
+    PDB_EVT_RAW_STORE_FAILED,   /**< A pdb_raw_store operation has failed. */
+    PDB_EVT_CLEARED,            /**< A pdb_clear operation has completed successfully. */
+    PDB_EVT_CLEAR_FAILED,       /**< A pdb_clear operation has failed. */
+    PDB_EVT_COMPRESSED,         /**< A compress procedure has completed. */
+    PDB_EVT_ERROR_NO_MEM,       /**< An operation is blocked because the flash is full. It will be reattempted automatically after the next compress procedure. */
+    PDB_EVT_ERROR_UNEXPECTED,   /**< An unexpected error occurred. This is a fatal error. */
+} pdb_evt_id_t;
+
+/**@brief Events that can come from the peer_database module.
+ */
+typedef struct
+{
+    pdb_evt_id_t      evt_id;  /**< The event that has happened. */
+    pm_peer_id_t      peer_id; /**< The id of the peer the event pertains to. */
+    pm_peer_data_id_t data_id; /**< The data the event pertains to. */
+    union
+    {
+        struct
+        {
+            pm_store_token_t store_token;  /**< A token identifying the store operation this event pertains to. */
+        } raw_stored_evt;
+        struct
+        {
+            pm_store_token_t store_token;  /**< A token identifying the store operation this event pertains to. */
+        } error_raw_store_evt;
+    } params;
+} pdb_evt_t;
+
+/**@brief Event handler for events from the peer_data_storage module.
+ *
+ * @param[in]  p_event   The event that has happened.
+ */
+typedef void (*pdb_evt_handler_t)(pdb_evt_t const * p_event);
+
+
+/**@brief Function for registering for events from the peer database.
+ *
+ * @note This function will initialize the module if it is not already initialized.
+ *
+ * @param[in]  evt_handler  Event handler to register.
+ *
+ * @retval NRF_SUCCESS              Registration successful.
+ * @retval NRF_ERROR_NO_MEM         No more event handlers can be registered.
+ * @retval NRF_ERROR_NULL           evt_handler was NULL.
+ * @retval NRF_ERROR_INVALID_PARAM  Unexpected return code from @ref pm_buffer_init.
+ * @retval NRF_ERROR_INVALID_STATE  FDS has not been initalized.
+ */
+ret_code_t pdb_register(pdb_evt_handler_t evt_handler);
+
+
+/**@brief Function for allocating persistent bond storage for a peer.
+ *
+ * @return  The ID of the newly allocated storage.
+ * @retval  PM_PEER_ID_INVALID  If no peer ID is available.
+ */
+pm_peer_id_t pdb_peer_allocate(void);
+
+
+/**@brief Function for freeing a peer's persistent bond storage.
+ *
+ * @note This function will call @ref pdb_write_buf_release on the data for this peer.
+ *
+ * @param[in] peer_id  ID to be freed.
+ *
+ * @retval NRF_SUCCESS              Peer ID was released and clear operation was initiated successfully.
+ * @retval NRF_ERROR_BUSY           Another peer_id clear was already requested or could not be started.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_peer_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for retrieving pointers to read-only peer data.
+ *
+ * @note  Reading this pointer is not safe in the strictest sense. If a safe read is required:
+ *          - Disable interrupts
+ *          - Call this function. If the return code is @ref NRF_SUCCESS, the following read is safe.
+ *          - Read memory.
+ *          - Enable interrupts.
+ * @note  This buffer does not need to be released. It is a pointer directly to flash.
+ *
+ * @param[in]  peer_id      ID of peer to retrieve data for.
+ * @param[in]  data_id      Which piece of data to get.
+ * @param[out] p_peer_data  Pointer to immutable peer data.
+ * @param[out] p_token      Token that can be used to lock data in flash and check data validity.
+ *
+ * @retval NRF_SUCCESS              Data retrieved successfully.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_NULL           p_peer_data was NULL.
+ * @retval NRF_ERROR_NOT_FOUND      This data was not found for this peer ID.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_read_buf_get(pm_peer_id_t           peer_id,
+                            pm_peer_data_id_t      data_id,
+                            pm_peer_data_flash_t * p_peer_data,
+                            pm_store_token_t     * p_token);
+
+
+/**@brief Function for retrieving pointers to a write buffer for peer data.
+ *
+ * @details This function will provide pointers to a buffer of the data. The data buffer will not be
+ *          written to persistent storage until @ref pdb_write_buf_store is called. The buffer is
+ *          released by calling either @ref pdb_write_buf_release, @ref pdb_write_buf_store, or
+ *          @ref pdb_peer_free.
+ *
+ *          When the data_id refers to a variable length data type, the available size is written
+ *          to the data, both the top-level, and any internal length fields.
+ *
+ * @note Calling this function on a peer_id/data_id pair that already has a buffer created will
+ *       give the same buffer, not create a new one. If n_bufs was increased since last time, the
+ *       buffer might be relocated to be able to provide additional room. In this case, the data
+ *       will be copied. If n_bufs was increased since last time, this function might return @ref
+ *       NRF_ERROR_BUSY. In that case, the buffer is automatically released.
+ *
+ * @param[in]  peer_id      ID of peer to get a write buffer for.
+ * @param[in]  data_id      Which piece of data to get.
+ * @param[in]  n_bufs       The number of contiguous buffers needed.
+ * @param[out] p_peer_data  Pointers to mutable peer data.
+ *
+ * @retval NRF_SUCCESS              Data retrieved successfully.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID or Peer ID was invalid or unallocated, or n_bufs was 0
+ *                                  or more than the total available buffers.
+ * @retval NRF_ERROR_NULL           p_peer_data was NULL.
+ * @retval NRF_ERROR_BUSY           Not enough buffer(s) available.
+ * @retval NRF_ERROR_INTERNAL       Unexpected internal error.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_write_buf_get(pm_peer_id_t      peer_id,
+                             pm_peer_data_id_t data_id,
+                             uint32_t          n_bufs,
+                             pm_peer_data_t  * p_peer_data);
+
+
+/**@brief Function for freeing a write buffer allocated with @ref pdb_write_buf_get.
+ *
+ * @note This function will not write peer data to persistent memory. Data in released buffer will
+ *       be lost.
+ *
+ * @note This function will undo any previous call to @ref pdb_write_buf_store_prepare for this
+ *       piece of data.
+ *
+ * @param[in]  peer_id  ID of peer to release buffer for.
+ * @param[in]  data_id  Which piece of data to release buffer for.
+ *
+ * @retval NRF_SUCCESS              Successfully released buffer.
+ * @retval NRF_ERROR_NOT_FOUND      No buffer was allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ * @retval NRF_ERROR_INTERNAL       Unexpected internal error.
+ */
+ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for reserving space in persistent storage for data in a buffer.
+ *
+ * @note This function only works for data which has a write buffer allocated. If the write buffer
+ *       is released, this prepare is undone.
+ *
+ * @note If space has already been reserved for this data, nothing is done.
+ *
+ * @param[in]  peer_id  The peer whose data to reserve space for.
+ * @param[in]  data_id  The type of data to reserve space for.
+ *
+ * @retval NRF_SUCCESS              Successfully reserved space in persistent storage.
+ * @retval NRF_ERROR_NO_MEM         Not enough room in persistent storage.
+ * @retval NRF_ERROR_BUSY           Could not process request at this time. Reattempt later.
+ * @retval NRF_ERROR_NOT_FOUND      No buffer has been allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for writing data into persistent storage. Writing happens asynchronously.
+ *
+ * @note This will unlock the data after it has been written.
+ *
+ * @param[in]  peer_id      ID of peer to store data for.
+ * @param[in]  data_id      Which piece of data to store.
+ *
+ * @retval NRF_SUCCESS              Data storing was successfully started.
+ * @retval NRF_ERROR_NO_MEM         No space available in persistent storage. Please clear some
+ *                                  space, the operation will be reattempted after the next compress
+ *                                  procedure. This error will not happen if
+ *                                  @ref pdb_write_buf_store_prepare is called beforehand.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID was invalid.
+ * @retval NRF_ERROR_NOT_FOUND      No buffer has been allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ * @retval NRF_ERROR_INTERNAL       Unexpected internal error.
+ */
+ret_code_t pdb_write_buf_store(pm_peer_id_t      peer_id,
+                               pm_peer_data_id_t data_id);
+
+
+/**@brief Function for clearing data from persistent storage.
+ *
+ * @param[in]  peer_id  ID of peer to clear data for.
+ * @param[in]  data_id  Which piece of data to clear.
+ *
+ * @retval NRF_SUCCESS              Data clear was successfully started.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID was invalid.
+ * @retval NRF_ERROR_NOT_FOUND      Nothing to clear for this data for this peer ID.
+ * @retval NRF_ERROR_BUSY           Could not process request at this time. Reattempt later.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ *        in persistent storage.
+ *
+ * @return  The number of valid peer IDs.
+ */
+uint32_t pdb_n_peers(void);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ *        used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ *       peer ID.
+ *
+ * @param[in]  prev_peer_id  The previous peer ID.
+ *
+ * @return  The next peer ID.
+ * @return  The first ordinary peer ID  if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval  PM_PEER_ID_INVALID          if prev_peer_id was the last ordinary peer ID.
+ */
+pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for updating currently stored peer data to a new version
+ *
+ * @details Updating happens asynchronously. 
+ *          Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token
+ *          and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token 
+ *      
+ * @param[in]   peer_data           New data
+ * @param[in]   old_token           Store token for the old data
+ * @param[out]  p_store_token       Store token for the new data
+ *
+ * @retval NRF_SUCESS               The update was initiated successfully
+ * @retval NRF_ERROR_NOT_FOUND      The old store token was invalid.
+ * @retval NRF_ERROR_NULL           Data contained a NULL pointer.
+ * @retval NRF_ERROR_NO_MEM         No space available in persistent storage.
+ * @retval NRF_ERROR_BUSY           FDS or underlying modules are busy and can't take any 
+ *                                  more requests
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_peer_data_update(pm_peer_data_const_t        peer_data,
+                                pm_store_token_t            old_token,
+                                pm_store_token_t          * p_store_token);
+
+
+/**@brief Function for reading data directly from persistent storage to external memory.
+ *
+ * @param[in]    peer_id      ID of peer to read data for.
+ * @param[in]    data_id      Which piece of data to read.
+ * @param[inout] p_peer_data  Where to store the data. If the data to be read has variable length,
+ *                            the appropriate length field needs to reflect the available buffer
+ *                            space. On a successful read, the length field is updated to match the
+ *                            length of the read data.
+ *
+ * @retval NRF_SUCCESS              Data successfully read.
+ * @retval NRF_ERROR_INVALID_PARAM  Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_NULL           p_peer_data contained a NULL pointer.
+ * @retval NRF_ERROR_NOT_FOUND      This data was not found for this peer ID.
+ * @retval NRF_ERROR_DATA_SIZE      The provided buffer was not large enough.
+ * @retval NRF_ERROR_INVALID_STATE  Module is not initialized.
+ */
+ret_code_t pdb_raw_read(pm_peer_id_t      peer_id,
+                        pm_peer_data_id_t data_id,
+                        pm_peer_data_t  * p_peer_data);
+
+
+/**@brief Function for writing data directly to persistent storage from external memory.
+ *
+ * @param[in]  peer_id        ID of peer to write data for.
+ * @param[in]  p_peer_data    Data to store.
+ * @param[out] p_store_token  A token identifying this particular store operation. The token can be
+ *                            used to identify events pertaining to this operation.
+ *
+ * @retval NRF_SUCCESS               Data successfully written.
+ * @retval NRF_ERROR_INVALID_PARAM   Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_NULL            p_peer_data contained a NULL pointer.
+ * @retval NRF_ERROR_NO_MEM          No space available in persistent storage.
+ * @retval NRF_ERROR_INVALID_LENGTH  Data length above the maximum allowed.
+ * @retval NRF_ERROR_INVALID_STATE   Module is not initialized.
+ */
+ret_code_t pdb_raw_store(pm_peer_id_t           peer_id,
+                         pm_peer_data_const_t * p_peer_data,
+                         pm_store_token_t     * p_store_token);
+
+
+/** @} */
+
+#endif /* PEER_DATABASE_H__ */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_id.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "peer_id.h"
+
+#include <stdint.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "peer_manager_types.h"
+#include "pm_mutex.h"
+
+
+typedef struct
+{
+    uint8_t peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /*< bitmap. */
+} pi_t;
+
+
+static pi_t m_pi = {.peer_ids = {0}};
+
+
+static void internal_state_reset(pi_t * p_pi)
+{
+    memset(p_pi, 0, sizeof(pi_t));
+}
+
+
+void peer_id_init(void)
+{
+    internal_state_reset(&m_pi);
+    pm_mutex_init(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
+}
+
+
+pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id)
+{
+    pm_peer_id_t allocated_peer_id = PM_PEER_ID_INVALID;
+    if (peer_id == PM_PEER_ID_INVALID)
+    {
+        allocated_peer_id = pm_mutex_lock_first_available(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
+        if (allocated_peer_id == PM_PEER_ID_N_AVAILABLE_IDS)
+        {
+            allocated_peer_id = PM_PEER_ID_INVALID;
+        }
+    }
+    else if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+    {
+        bool lock_success = pm_mutex_lock(m_pi.peer_ids, peer_id);
+        allocated_peer_id = lock_success ? peer_id : PM_PEER_ID_INVALID;
+    }
+    return allocated_peer_id;
+}
+
+
+void peer_id_free(pm_peer_id_t peer_id)
+{
+    if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+    {
+        pm_mutex_unlock(m_pi.peer_ids, peer_id);
+    }
+}
+
+
+bool peer_id_is_allocated(pm_peer_id_t peer_id)
+{
+    if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+    {
+        return pm_mutex_lock_status_get(m_pi.peer_ids, peer_id);
+    }
+    return false;
+}
+
+
+pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id)
+{
+    pm_peer_id_t i = (prev_peer_id == PM_PEER_ID_INVALID) ? 0 : (prev_peer_id + 1);
+    for (; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
+    {
+        if (pm_mutex_lock_status_get(m_pi.peer_ids, i))
+        {
+            return i;
+        }
+    }
+
+    return PM_PEER_ID_INVALID;
+}
+
+
+uint32_t peer_id_n_ids(void)
+{
+    uint32_t n_ids = 0;
+
+    for (pm_peer_id_t i = 0; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
+    {
+        n_ids += pm_mutex_lock_status_get(m_pi.peer_ids, i);
+    }
+
+    return n_ids;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_id.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_ID_H__
+#define PEER_ID_H__
+
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+
+/**
+ * @defgroup peer_id Peer IDs
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module keeps track of which peer IDs are in
+ *        use and which are free.
+ */
+
+
+/**@brief Function for initializing the module.
+ */
+void peer_id_init(void);
+
+
+/**@brief Function for claiming an unused peer ID.
+ *
+ * @param peer_id  The peer ID to allocate. If this is @ref PM_PEER_ID_INVALID, the first available
+ *                 will be allocated.
+ *
+ * @return  The allocated peer ID.
+ * @retval  PM_PEER_ID_INVALID  If no peer ID could be allocated or module is not initialized.
+ */
+pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id);
+
+
+/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent
+ *        storage.
+ *
+ * @param[in]  peer_id  Peer ID to free.
+ */
+void peer_id_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for finding out whether a peer ID is in use.
+ *
+ * @param[in]  peer_id  The peer ID to inquire about.
+ *
+ * @retval  true   peer_id is in use.
+ * @retval  false  peer_id is free, or the module is not initialized.
+ */
+bool peer_id_is_allocated(pm_peer_id_t peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ *        used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ *       peer ID.
+ *
+ * @param[in]  prev_peer_id  The previous peer ID.
+ *
+ * @return  The next peer ID.
+ * @return  The first used peer ID  if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval  PM_PEER_ID_INVALID      if prev_peer_id was the last ordinary peer ID or the module is
+ *                                  not initialized.
+ */
+pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ *        in persistent storage.
+ *
+ * @return  The number of valid peer IDs, or 0 if module is not initialized.
+ */
+uint32_t peer_id_n_ids(void);
+
+/** @} */
+
+#endif /* PEER_ID_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/peer_manager_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 PEER_MANAGER_TYPES_H__
+#define PEER_MANAGER_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/**
+ * @file peer_manager_types.h
+ *
+ * @addtogroup peer_manager
+ * @{
+ */
+
+
+#include <stdint.h>
+#include <stddef.h>
+#include "ble_gap.h"
+#include "ble_hci.h"
+#include "ble_gatt_db.h"
+#include "compiler_abstraction.h"
+
+
+/**@brief Handle to uniquely identify a peer for which we have persistently stored data.
+ */
+typedef uint16_t pm_peer_id_t;
+
+#define PM_PEER_ID_INVALID              0xFFFF /**< Invalid value for @ref pm_peer_id_t. */
+#define PM_PEER_ID_N_AVAILABLE_IDS      256    /**< The number of available peer IDs. */
+#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES  offsetof(pm_peer_data_local_gatt_db_flash_t, p_data)
+#define PM_REMOTE_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_remote_gatt_db_flash_t, p_data)
+
+static __INLINE uint16_t PM_N_WORDS(uint16_t n_bytes)
+{
+    return ((n_bytes + 3) >> 2);
+}
+
+/**@brief Errors originating from the Peer Manager module.
+ */
+typedef enum
+{
+    PM_SEC_ERROR_CODE_PIN_OR_KEY_MISSING = BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING,  /**< Encryption failed because the peripheral has lost the LTK for this bond. */
+    PM_SEC_ERROR_CODE_MIC_FAILURE = BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE,     /**< Pairing ended with disconnection because of mismatching keys. */
+    PM_SEC_ERROR_SMP_TIMEOUT,                                                       /**< Pairing/bonding could not start because an SMP timeout has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth specification 4.2 section 3.H.3.4 */
+} pm_sec_error_code_t;
+
+
+/**@brief Enumeration describing the different procedures that can lead to an encrypted link.
+ */
+typedef enum
+{
+    PM_LINK_SECURED_PROCEDURE_ENCRYPTION, /**< Using an LTK shared during a previous bonding procedure to encrypt the link. */
+    PM_LINK_SECURED_PROCEDURE_BONDING,    /**< A pairing procedure, followed by a bonding procedure. */
+    PM_LINK_SECURED_PROCEDURE_PAIRING,    /**< A pairing procedure with no bonding. */
+} pm_sec_procedure_t;
+
+
+/**@brief Data associated with a bond to a peer.
+ */
+typedef struct
+{
+    uint8_t           own_role; /**< The role of the local device during bonding. */
+    ble_gap_id_key_t  peer_id;  /**< The peer's peer address and identity resolution key. */
+    ble_gap_enc_key_t peer_ltk; /**< The peer's long term encryption key. */
+    ble_gap_enc_key_t own_ltk;  /**< Locally generated long term encryption key, distributed to the peer. */
+} pm_peer_data_bonding_t;
+
+
+/**@brief Function for calculating the flash size of bonding data.
+ *
+ * @return The number of words the data will take in flash.
+ */
+static __INLINE uint16_t PM_BONDING_DATA_N_WORDS(void)
+{
+    return PM_N_WORDS(sizeof(pm_peer_data_bonding_t));
+}
+
+
+/**@brief Function for calculating the flash size of service changed pending state.
+ *
+ * @return The number of words the data will take in flash.
+ */
+static __INLINE uint16_t PM_SC_STATE_N_WORDS(void)
+{
+    return PM_N_WORDS(sizeof(bool));
+}
+
+
+/**@brief Data on a local GATT database.
+ */
+typedef struct
+{
+    uint32_t  flags;   /**< Flags describing the database attributes. */
+    uint16_t  len;     /**< Size of attribute array. */
+    uint8_t * p_data;  /**< Array to hold the database attributes. */
+} pm_peer_data_local_gatt_db_t;
+
+
+/**@brief Data on a local GATT database, as formatted in flash.
+ */
+typedef struct
+{
+    uint32_t flags;
+    uint16_t len;
+    uint16_t _padding;
+    uint8_t  p_data[];
+} pm_peer_data_local_gatt_db_flash_t;
+
+
+/**@brief Function for calculating the flash size of local GATT database data.
+ *
+ * @param[in]  local_db_len  The length of the database as reported by the SoftDevice.
+ *
+ * @return The number of words the data will take in flash.
+ */
+static __INLINE uint16_t PM_LOCAL_DB_N_WORDS(uint16_t local_db_len)
+{
+    return PM_N_WORDS(local_db_len + PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
+}
+
+
+/**@brief Function for calculating the length of a local GATT database attribute array.
+ *
+ * @param[in]  n_words  The number of words the data takes in flash.
+ *
+ * @return The length of the database attribute array.
+ */
+static __INLINE uint16_t PM_LOCAL_DB_LEN(uint16_t n_words)
+{
+    return ((n_words * 4) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
+}
+
+
+/**@brief Data on a remote GATT database.
+ */
+typedef struct
+{
+    uint32_t            service_count; /**< Number of stored services. */
+    ble_gatt_db_srv_t * p_data;        /**< Array to hold the database attributes. */
+} pm_peer_data_remote_gatt_db_t;
+
+
+/**@brief Data on a remote GATT database, as formatted in flash.
+ */
+typedef struct
+{
+    uint32_t          service_count;
+    ble_gatt_db_srv_t p_data[];
+} pm_peer_data_remote_gatt_db_flash_t;
+
+
+
+/**@brief Function for calculating the flash size of remote GATT database data.
+ *
+ * @param[in]  service_count  The number of services in the service array.
+ *
+ * @return The number of words the data will take in flash.
+ */
+static __INLINE uint16_t PM_REMOTE_DB_N_WORDS(uint16_t service_count)
+{
+    return PM_N_WORDS((sizeof(ble_gatt_db_srv_t) * service_count) + PM_REMOTE_DB_LEN_OVERHEAD_BYTES);
+}
+
+
+/**@brief Union of all data associated with one peer.
+ */
+typedef union
+{
+    pm_peer_data_bonding_t        * p_bonding_data;            /**< The exchanged bond information in addition to metadata of the bonding. */
+    bool                          * p_service_changed_pending; /**< Whether a service changed indication should be sent to the peer. */
+    pm_peer_data_local_gatt_db_t  * p_local_gatt_db;           /**< Persistent information pertaining to a peer GATT client. */
+    pm_peer_data_remote_gatt_db_t * p_remote_gatt_db;          /**< Persistent information pertaining to a peer GATT server. */
+    uint8_t                       * p_application_data;        /**< Arbitrary data to associate with the peer. This data can be freely used by the application. */
+} pm_peer_data_unit_t;
+
+
+/**@brief Immutable version of @ref pm_peer_data_unit_t.
+ */
+typedef union
+{
+    pm_peer_data_bonding_t        const * p_bonding_data;
+    bool                          const * p_service_changed_pending;
+    pm_peer_data_local_gatt_db_t  const * p_local_gatt_db;
+    pm_peer_data_remote_gatt_db_t const * p_remote_gatt_db;
+    uint8_t                       const * p_application_data;
+} pm_peer_data_unit_const_t;
+
+
+/**@brief Data from @ref pm_peer_data_unit_t, as mapped in flash.
+ */
+typedef union
+{
+    pm_peer_data_bonding_t              const * p_bonding_data;
+    bool                                const * p_service_changed_pending;
+    pm_peer_data_local_gatt_db_flash_t  const * p_local_gatt_db;
+    pm_peer_data_remote_gatt_db_flash_t const * p_remote_gatt_db;
+    uint8_t                             const * p_application_data;
+} pm_peer_data_unit_flash_t;
+
+
+/**@brief The different types of data associated with a peer.
+ */
+typedef enum
+{
+    PM_PEER_DATA_ID_BONDING,
+    PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING,
+    PM_PEER_DATA_ID_GATT_LOCAL,
+    PM_PEER_DATA_ID_GATT_REMOTE,
+    PM_PEER_DATA_ID_APPLICATION,
+    PM_PEER_DATA_ID_INVALID,
+} pm_peer_data_id_t;
+
+
+//STATIC_ASSERT_MSG(sizeof(pm_peer_data_t) == sizeof(pm_peer_data_const_t), "Size of pm_peer_data_t different from immutable version.");
+
+
+/**@brief Macro saying whether a data_id is valid, i.e. one of the valid enum values.
+ *
+ * @param[in] data_id  The data_id to check.
+ */
+static __INLINE bool PM_PEER_DATA_ID_IS_VALID(pm_peer_data_id_t data_id)
+{
+    return ((data_id - PM_PEER_DATA_ID_BONDING) < (PM_PEER_DATA_ID_INVALID - PM_PEER_DATA_ID_BONDING));
+}
+
+
+/**@brief One piece of data associated with a peer, together with the type.
+ */
+typedef struct
+{
+    uint16_t            length_words;
+    pm_peer_data_id_t   data_type;
+    pm_peer_data_unit_t data;
+} pm_peer_data_t;
+
+/**@brief Immutable version of @ref pm_peer_data_t.
+ */
+typedef struct
+{
+    uint16_t                    length_words;
+    pm_peer_data_id_t           data_type;
+    pm_peer_data_unit_const_t   data;
+} pm_peer_data_const_t;
+
+/**@brief Data from @ref pm_peer_data_t, as mapped in flash.
+ */
+typedef struct
+{
+    uint16_t                  length_words;
+    pm_peer_data_id_t         data_type;
+    pm_peer_data_unit_flash_t data;
+} pm_peer_data_flash_t;
+
+
+/**@brief Typedef for type used for write prepares. Used to reserve space in flash
+ */
+typedef uint32_t pm_prepare_token_t;
+
+
+/**@brief Typedef for type used to hold reference to stored item in flash.
+ *        this token can be used for locking and validity check
+ */
+typedef uint32_t pm_store_token_t;
+
+ /** @} */
+
+#endif /* PEER_MANAGER_TYPES_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_buffer.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "pm_buffer.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "pm_mutex.h"
+
+
+#define BUFFER_IS_VALID(p_buffer) ((p_buffer != NULL)             \
+                                && (p_buffer->p_memory != NULL)   \
+                                && (p_buffer->p_mutex  != NULL))
+
+
+
+ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
+                          uint8_t     * p_buffer_memory,
+                          uint32_t      buffer_memory_size,
+                          uint8_t     * p_mutex_memory,
+                          uint32_t      mutex_memory_size,
+                          uint32_t      n_blocks,
+                          uint32_t      block_size)
+{
+    if (   (p_buffer           != NULL)
+        && (p_buffer_memory    != NULL)
+        && (p_mutex_memory     != NULL)
+        && (buffer_memory_size >= (n_blocks*block_size))
+        && (mutex_memory_size  >= MUTEX_STORAGE_SIZE(n_blocks))
+        && (n_blocks           != 0)
+        && (block_size         != 0))
+    {
+        p_buffer->p_memory   = p_buffer_memory;
+        p_buffer->p_mutex    = p_mutex_memory;
+        p_buffer->n_blocks   = n_blocks;
+        p_buffer->block_size = block_size;
+        pm_mutex_init(p_buffer->p_mutex, n_blocks);
+
+        return NRF_SUCCESS;
+    }
+    else
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+}
+
+
+uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks)
+{
+    if (!BUFFER_IS_VALID(p_buffer))
+    {
+        return ( BUFFER_INVALID_ID );
+    }
+
+    uint8_t first_locked_mutex = BUFFER_INVALID_ID;
+
+    for (uint8_t i = 0; i < p_buffer->n_blocks; i++)
+    {
+        if (pm_mutex_lock(p_buffer->p_mutex, i))
+        {
+            if (first_locked_mutex == BUFFER_INVALID_ID)
+            {
+                first_locked_mutex = i;
+            }
+            if ((i - first_locked_mutex + 1) == n_blocks)
+            {
+                return first_locked_mutex;
+            }
+        }
+        else if (first_locked_mutex != BUFFER_INVALID_ID)
+        {
+            for (uint8_t j = first_locked_mutex; j < i; j++)
+            {
+                pm_buffer_release(p_buffer, j);
+            }
+            first_locked_mutex = BUFFER_INVALID_ID;
+        }
+    }
+
+    return ( BUFFER_INVALID_ID );
+}
+
+
+uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id)
+{
+    if (!BUFFER_IS_VALID(p_buffer))
+    {
+        return ( NULL );
+    }
+
+    if ( (id != BUFFER_INVALID_ID)
+    &&   pm_mutex_lock_status_get(p_buffer->p_mutex, id) )
+    {
+        return ( &p_buffer->p_memory[id*p_buffer->block_size] );
+    }
+    else
+    {
+        return ( NULL );
+    }
+}
+
+
+void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id)
+{
+    if (    BUFFER_IS_VALID(p_buffer)
+       &&  (id != BUFFER_INVALID_ID)
+       &&   pm_mutex_lock_status_get(p_buffer->p_mutex, id))
+    {
+        pm_mutex_unlock(p_buffer->p_mutex, id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_buffer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 BUFFER_H__
+#define BUFFER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "pm_mutex.h"
+
+
+/**
+ * @defgroup pm_buffer Buffer
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides a simple buffer.
+ */
+
+
+#define BUFFER_INVALID_ID 0xFF
+
+#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code)    \
+do                                                                  \
+{                                                                   \
+    static uint8_t buffer_memory[(n_blocks) * (block_size)];        \
+    static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)];      \
+    err_code = pm_buffer_init((p_buffer),                           \
+                               buffer_memory,                       \
+                              (n_blocks) * (block_size),            \
+                               mutex_memory,                        \
+                               MUTEX_STORAGE_SIZE(n_blocks),        \
+                              (n_blocks),                           \
+                              (block_size));                        \
+} while(0)
+
+
+typedef struct
+{
+    uint8_t * p_memory;   /**< The storage for all buffer entries. The size of the buffer must be n_blocks*block_size. */
+    uint8_t * p_mutex;    /**< A mutex group with one mutex for each buffer entry. */
+    uint32_t  n_blocks;   /**< The number of allocatable blocks in the buffer. */
+    uint32_t  block_size; /**< The size of each block in the buffer. */
+} pm_buffer_t;
+
+/**@brief Function for initializing a buffer instance.
+ *
+ * @param[out] p_buffer            The buffer instance to initialize.
+ * @param[in]  p_buffer_memory     The memory this buffer will use.
+ * @param[in]  buffer_memory_size  The size of p_buffer_memory. This must be at least
+ *                                 n_blocks*block_size.
+ * @param[in]  p_mutex_memory      The memory for the mutexes. This must be at least
+ *                                 @ref MUTEX_STORAGE_SIZE(n_blocks).
+ * @param[in]  mutex_memory_size   The size of p_mutex_memory.
+ * @param[in]  n_blocks            The number of blocks in the buffer.
+ * @param[in]  block_size          The size of each block.
+ *
+ * @retval NRF_SUCCESS              Successfully initialized buffer instance.
+ * @retval NRF_ERROR_INVALID_PARAM  A parameter was 0 or NULL or a size was too small.
+ */
+ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
+                          uint8_t     * p_buffer_memory,
+                          uint32_t      buffer_memory_size,
+                          uint8_t     * p_mutex_memory,
+                          uint32_t      mutex_memory_size,
+                          uint32_t      n_blocks,
+                          uint32_t      block_size);
+
+
+/**@brief Function for acquiring a buffer block in a buffer.
+ *
+ * @param[in]  p_buffer  The buffer instance acquire from.
+ * @param[in]  n_blocks  The number of contiguous blocks to acquire.
+ *
+ * @return The id of the acquired block, if successful.
+ * @retval BUFFER_INVALID_ID  If unsuccessful.
+ */
+uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks);
+
+
+/**@brief Function for getting a pointer to a specific buffer block.
+ *
+ * @param[in]  p_buffer  The buffer instance get from.
+ * @param[in]  id        The id of the buffer to get the pointer for.
+ *
+ * @return A pointer to the buffer for the specified id, if the id is valid.
+ * @retval NULL  If the id is invalid.
+ */
+uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id);
+
+
+/**@brief Function for releasing a buffer block.
+ *
+ * @param[in]  p_buffer  The buffer instance containing the block to release.
+ * @param[in]  id        The id of the block to release.
+ */
+void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id);
+
+
+#endif // BUFFER_H__
+
+/**
+ * @}
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_mutex.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "pm_mutex.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "app_util_platform.h"
+
+
+
+/**@brief Locks the mutex defined by the mask.
+ *
+ * @param p_mutex pointer to the mutex storage.
+ * @param mutex_mask the mask identifying the mutex position.
+ *
+ * @retval true if the mutex could be locked.
+ * @retval false if the mutex was already locked.
+ */
+static bool lock_by_mask(uint8_t * p_mutex, uint8_t mutex_mask)
+{
+    bool success = false;
+
+    if ( (*p_mutex & mutex_mask) == 0 )
+    {
+        CRITICAL_REGION_ENTER();
+        if ( (*p_mutex & mutex_mask) == 0 )
+        {
+            *p_mutex |= mutex_mask;
+
+            success = true;
+        }
+        CRITICAL_REGION_EXIT();
+    }
+
+    return ( success );
+}
+
+
+void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size)
+{
+    if (p_mutex != NULL)
+    {
+        memset(&p_mutex[0], 0, MUTEX_STORAGE_SIZE(mutex_size));
+    }
+}
+
+
+bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_id)
+{
+    if (p_mutex != NULL)
+    {
+        return ( lock_by_mask(&(p_mutex[mutex_id >> 3]), (1 << (mutex_id & 0x07))) );
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_id)
+{
+    uint8_t mutex_base = mutex_id >> 3;
+    uint8_t mutex_mask = (1 << (mutex_id & 0x07));
+
+    if   ((p_mutex != NULL)
+       && (p_mutex[mutex_base] & mutex_mask))
+    {
+        CRITICAL_REGION_ENTER();
+        p_mutex[mutex_base] &= ~mutex_mask;
+        CRITICAL_REGION_EXIT();
+    }
+}
+
+
+uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size)
+{
+    if (p_mutex != NULL)
+    {
+        for ( uint16_t i = 0; i < mutex_size; i++ )
+        {
+            if ( lock_by_mask(&(p_mutex[i >> 3]), 1 << (i & 0x07)) )
+            {
+                return ( i );
+            }
+        }
+    }
+
+    return ( mutex_size );
+}
+
+
+bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id)
+{
+    if (p_mutex != NULL)
+    {
+        return ( (p_mutex[mutex_id >> 3] & (1 << (mutex_id & 0x07))) );
+    }
+    else
+    {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/ble/peer_manager/pm_mutex.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 MUTEX_H__
+#define MUTEX_H__
+
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * @defgroup pm_mutex Mutex
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides thread-safe mutexes.
+ */
+
+
+/**@brief Defines the storage size of a specified mutex group.
+ *
+ * @param number_of_mutexes the number of mutexes in the group.
+ */
+#define MUTEX_STORAGE_SIZE(number_of_mutexes) ((7 + (number_of_mutexes)) >> 3)
+
+
+/**@brief Initializes a mutex group.
+ *
+ * @param[in] p_mutex     Pointer to the mutex group. See @ref MUTEX_STORAGE_SIZE().
+ * @param[in] mutex_size  The size of the mutex group in number of mutexes.
+ */
+void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size);
+
+
+/**@brief Locks the mutex specified by the bit id.
+ *
+ * @param[inout] p_mutex       Pointer to the mutex group.
+ * @param[in]    mutex_bit_id  The bit id of the mutex.
+ *
+ * @retval true   if it was possible to lock the mutex.
+ * @retval false  otherwise.
+ */
+bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+/**@brief Locks the first unlocked mutex within the mutex group.
+ *
+ * @param[in, out] p_mutex     Pointer to the mutex group.
+ * @param[in]      mutex_size  The size of the mutex group.
+ *
+ * @return The first unlocked mutex id in the group.
+ * @retval group-size  if there was no unlocked mutex available.
+ */
+uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size);
+
+
+/**@brief Unlocks the mutex specified by the bit id.
+ *
+ * @param[in, out] p_mutex       Pointer to the mutex group.
+ * @param[in]      mutex_bit_id  The bit id of the mutex.
+ */
+void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+/**@brief Gets the locking status of the specified mutex.
+ *
+ * @param[in, out] p_mutex      Pointer to the mutex group.
+ * @param[in]      mutex_bit_id The bit id of the mutex.
+ *
+ * @retval true   if the mutex was locked.
+ * @retval false  otherwise.
+ */
+bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+#endif // MUTEX_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/compiler_abstraction.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 _COMPILER_ABSTRACTION_H
+#define _COMPILER_ABSTRACTION_H
+
+/*lint ++flb "Enter library region" */
+
+#if defined ( __CC_ARM )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            __inline                    
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __align(n)                  
+    #endif
+    
+    #define GET_SP()                __current_sp()              
+  
+#elif defined ( __ICCARM__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      
+    #endif
+
+    /* Not defined for IAR since it requires a new line to work, and C preprocessor does not allow that. */
+    #ifndef __ALIGN
+        #define __ALIGN(n)          
+    #endif
+    
+    #define GET_SP()                __get_SP()                  
+    
+#elif defined   ( __GNUC__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))       
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __attribute__((aligned(n))) 
+    #endif
+    
+    #define GET_SP()                gcc_current_sp()            
+
+    static inline unsigned int gcc_current_sp(void)
+    {
+        register unsigned sp __ASM("sp");
+        return sp;
+    }
+    
+#elif defined   ( __TASKING__ )
+        
+    #ifndef __ASM        
+        #define __ASM               __asm                      
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                     
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))      
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __align(n)                  
+    #endif
+    
+    #define GET_SP()                __get_MSP()                
+    
+#endif
+
+/*lint --flb "Leave library region" */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF_H
+#define NRF_H
+
+#if defined(_WIN32)         
+    /* Do not include nrf51 specific files when building for PC host */
+#elif defined(__unix)       
+    /* Do not include nrf51 specific files when building for PC host */
+#elif defined(__APPLE__)    
+    /* Do not include nrf51 specific files when building for PC host */
+#else
+
+    /* Family selection for family includes. */
+    #if defined (NRF51)
+        #include "nrf51.h"
+        #include "nrf51_bitfields.h"
+        #include "nrf51_deprecated.h"
+    #elif defined (NRF52)
+        #include "nrf52.h"
+        #include "nrf52_bitfields.h"
+        #include "nrf51_to_nrf52.h"
+    #else
+        #error "Device family must be defined. See nrf.h."
+    #endif /* NRF51, NRF52 */
+
+    #include "compiler_abstraction.h"
+
+#endif /* _WIN32 || __unix || __APPLE__ */
+
+#endif /* NRF_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1263 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF51_H
+#define NRF51_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* -------------------------  Interrupt Number Definition  ------------------------ */
+
+typedef enum {
+/* -------------------  Cortex-M0 Processor Exceptions Numbers  ------------------- */
+  Reset_IRQn                    = -15,              /*!<   1  Reset Vector, invoked on Power up and warm reset                 */
+  NonMaskableInt_IRQn           = -14,              /*!<   2  Non maskable Interrupt, cannot be stopped or preempted           */
+  HardFault_IRQn                = -13,              /*!<   3  Hard Fault, all classes of Fault                                 */
+  SVCall_IRQn                   =  -5,              /*!<  11  System Service Call via SVC instruction                          */
+  DebugMonitor_IRQn             =  -4,              /*!<  12  Debug Monitor                                                    */
+  PendSV_IRQn                   =  -2,              /*!<  14  Pendable request for system service                              */
+  SysTick_IRQn                  =  -1,              /*!<  15  System Tick Timer                                                */
+/* ----------------------  nrf51 Specific Interrupt Numbers  ---------------------- */
+  POWER_CLOCK_IRQn              =   0,              /*!<   0  POWER_CLOCK                                                      */
+  RADIO_IRQn                    =   1,              /*!<   1  RADIO                                                            */
+  UART0_IRQn                    =   2,              /*!<   2  UART0                                                            */
+  SPI0_TWI0_IRQn                =   3,              /*!<   3  SPI0_TWI0                                                        */
+  SPI1_TWI1_IRQn                =   4,              /*!<   4  SPI1_TWI1                                                        */
+  GPIOTE_IRQn                   =   6,              /*!<   6  GPIOTE                                                           */
+  ADC_IRQn                      =   7,              /*!<   7  ADC                                                              */
+  TIMER0_IRQn                   =   8,              /*!<   8  TIMER0                                                           */
+  TIMER1_IRQn                   =   9,              /*!<   9  TIMER1                                                           */
+  TIMER2_IRQn                   =  10,              /*!<  10  TIMER2                                                           */
+  RTC0_IRQn                     =  11,              /*!<  11  RTC0                                                             */
+  TEMP_IRQn                     =  12,              /*!<  12  TEMP                                                             */
+  RNG_IRQn                      =  13,              /*!<  13  RNG                                                              */
+  ECB_IRQn                      =  14,              /*!<  14  ECB                                                              */
+  CCM_AAR_IRQn                  =  15,              /*!<  15  CCM_AAR                                                          */
+  WDT_IRQn                      =  16,              /*!<  16  WDT                                                              */
+  RTC1_IRQn                     =  17,              /*!<  17  RTC1                                                             */
+  QDEC_IRQn                     =  18,              /*!<  18  QDEC                                                             */
+  LPCOMP_IRQn                   =  19,              /*!<  19  LPCOMP                                                           */
+  SWI0_IRQn                     =  20,              /*!<  20  SWI0                                                             */
+  SWI1_IRQn                     =  21,              /*!<  21  SWI1                                                             */
+  SWI2_IRQn                     =  22,              /*!<  22  SWI2                                                             */
+  SWI3_IRQn                     =  23,              /*!<  23  SWI3                                                             */
+  SWI4_IRQn                     =  24,              /*!<  24  SWI4                                                             */
+  SWI5_IRQn                     =  25               /*!<  25  SWI5                                                             */
+} IRQn_Type;
+
+
+/** @addtogroup Configuration_of_CMSIS
+  * @{
+  */
+
+
+/* ================================================================================ */
+/* ================      Processor and Core Peripheral Section     ================ */
+/* ================================================================================ */
+
+/* ----------------Configuration of the Cortex-M0 Processor and Core Peripherals---------------- */
+#define __CM0_REV                 0x0301            /*!< Cortex-M0 Core Revision                                               */
+#define __MPU_PRESENT                  0            /*!< MPU present or not                                                    */
+#define __NVIC_PRIO_BITS               2            /*!< Number of Bits used for Priority Levels                               */
+#define __Vendor_SysTickConfig         0            /*!< Set to 1 if different SysTick Config is used                          */
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+#include "core_cm0.h"                               /*!< Cortex-M0 processor and core peripherals                              */
+#include "system_nrf51.h"                           /*!< nrf51 System                                                          */
+
+
+/* ================================================================================ */
+/* ================       Device Specific Peripheral Section       ================ */
+/* ================================================================================ */
+
+
+/** @addtogroup Device_Peripheral_Registers
+  * @{
+  */
+
+
+/* -------------------  Start of section using anonymous unions  ------------------ */
+#if defined(__CC_ARM)
+  #pragma push
+  #pragma anon_unions
+#elif defined(__ICCARM__)
+  #pragma language=extended
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TMS470__)
+/* anonymous unions are enabled by default */
+#elif defined(__TASKING__)
+  #pragma warning 586
+#else
+  #warning Not supported compiler type
+#endif
+
+
+typedef struct {
+  __IO uint32_t  CPU0;                              /*!< Configurable priority configuration register for CPU0.                */
+  __IO uint32_t  SPIS1;                             /*!< Configurable priority configuration register for SPIS1.               */
+  __IO uint32_t  RADIO;                             /*!< Configurable priority configuration register for RADIO.               */
+  __IO uint32_t  ECB;                               /*!< Configurable priority configuration register for ECB.                 */
+  __IO uint32_t  CCM;                               /*!< Configurable priority configuration register for CCM.                 */
+  __IO uint32_t  AAR;                               /*!< Configurable priority configuration register for AAR.                 */
+} AMLI_RAMPRI_Type;
+
+typedef struct {
+  __IO uint32_t  SCK;                               /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  MOSI;                              /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  MISO;                              /*!< Pin select for MISO.                                                  */
+} SPIM_PSEL_Type;
+
+typedef struct {
+  __IO uint32_t  PTR;                               /*!< Data pointer.                                                         */
+  __IO uint32_t  MAXCNT;                            /*!< Maximum number of buffer bytes to receive.                            */
+  __I  uint32_t  AMOUNT;                            /*!< Number of bytes received in the last transaction.                     */
+} SPIM_RXD_Type;
+
+typedef struct {
+  __IO uint32_t  PTR;                               /*!< Data pointer.                                                         */
+  __IO uint32_t  MAXCNT;                            /*!< Maximum number of buffer bytes to send.                               */
+  __I  uint32_t  AMOUNT;                            /*!< Number of bytes sent in the last transaction.                         */
+} SPIM_TXD_Type;
+
+typedef struct {
+  __O  uint32_t  EN;                                /*!< Enable channel group.                                                 */
+  __O  uint32_t  DIS;                               /*!< Disable channel group.                                                */
+} PPI_TASKS_CHG_Type;
+
+typedef struct {
+  __IO uint32_t  EEP;                               /*!< Channel event end-point.                                              */
+  __IO uint32_t  TEP;                               /*!< Channel task end-point.                                               */
+} PPI_CH_Type;
+
+
+/* ================================================================================ */
+/* ================                      POWER                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Power Control. (POWER)
+  */
+
+typedef struct {                                    /*!< POWER Structure                                                       */
+  __I  uint32_t  RESERVED0[30];
+  __O  uint32_t  TASKS_CONSTLAT;                    /*!< Enable constant latency mode.                                         */
+  __O  uint32_t  TASKS_LOWPWR;                      /*!< Enable low power mode (variable latency).                             */
+  __I  uint32_t  RESERVED1[34];
+  __IO uint32_t  EVENTS_POFWARN;                    /*!< Power failure warning.                                                */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __IO uint32_t  RESETREAS;                         /*!< Reset reason.                                                         */
+  __I  uint32_t  RESERVED4[9];
+  __I  uint32_t  RAMSTATUS;                         /*!< Ram status register.                                                  */
+  __I  uint32_t  RESERVED5[53];
+  __O  uint32_t  SYSTEMOFF;                         /*!< System off register.                                                  */
+  __I  uint32_t  RESERVED6[3];
+  __IO uint32_t  POFCON;                            /*!< Power failure configuration.                                          */
+  __I  uint32_t  RESERVED7[2];
+  __IO uint32_t  GPREGRET;                          /*!< General purpose retention register. This register is a retained
+                                                         register.                                                             */
+  __I  uint32_t  RESERVED8;
+  __IO uint32_t  RAMON;                             /*!< Ram on/off.                                                           */
+  __I  uint32_t  RESERVED9[7];
+  __IO uint32_t  RESET;                             /*!< Pin reset functionality configuration register. This register
+                                                         is a retained register.                                               */
+  __I  uint32_t  RESERVED10[3];
+  __IO uint32_t  RAMONB;                            /*!< Ram on/off.                                                           */
+  __I  uint32_t  RESERVED11[8];
+  __IO uint32_t  DCDCEN;                            /*!< DCDC converter enable configuration register.                         */
+  __I  uint32_t  RESERVED12[291];
+  __IO uint32_t  DCDCFORCE;                         /*!< DCDC power-up force register.                                         */
+} NRF_POWER_Type;
+
+
+/* ================================================================================ */
+/* ================                      CLOCK                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Clock control. (CLOCK)
+  */
+
+typedef struct {                                    /*!< CLOCK Structure                                                       */
+  __O  uint32_t  TASKS_HFCLKSTART;                  /*!< Start HFCLK clock source.                                             */
+  __O  uint32_t  TASKS_HFCLKSTOP;                   /*!< Stop HFCLK clock source.                                              */
+  __O  uint32_t  TASKS_LFCLKSTART;                  /*!< Start LFCLK clock source.                                             */
+  __O  uint32_t  TASKS_LFCLKSTOP;                   /*!< Stop LFCLK clock source.                                              */
+  __O  uint32_t  TASKS_CAL;                         /*!< Start calibration of LFCLK RC oscillator.                             */
+  __O  uint32_t  TASKS_CTSTART;                     /*!< Start calibration timer.                                              */
+  __O  uint32_t  TASKS_CTSTOP;                      /*!< Stop calibration timer.                                               */
+  __I  uint32_t  RESERVED0[57];
+  __IO uint32_t  EVENTS_HFCLKSTARTED;               /*!< HFCLK oscillator started.                                             */
+  __IO uint32_t  EVENTS_LFCLKSTARTED;               /*!< LFCLK oscillator started.                                             */
+  __I  uint32_t  RESERVED1;
+  __IO uint32_t  EVENTS_DONE;                       /*!< Calibration of LFCLK RC oscillator completed.                         */
+  __IO uint32_t  EVENTS_CTTO;                       /*!< Calibration timer timeout.                                            */
+  __I  uint32_t  RESERVED2[124];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[63];
+  __I  uint32_t  HFCLKRUN;                          /*!< Task HFCLKSTART trigger status.                                       */
+  __I  uint32_t  HFCLKSTAT;                         /*!< High frequency clock status.                                          */
+  __I  uint32_t  RESERVED4;
+  __I  uint32_t  LFCLKRUN;                          /*!< Task LFCLKSTART triggered status.                                     */
+  __I  uint32_t  LFCLKSTAT;                         /*!< Low frequency clock status.                                           */
+  __I  uint32_t  LFCLKSRCCOPY;                      /*!< Clock source for the LFCLK clock, set when task LKCLKSTART is
+                                                         triggered.                                                            */
+  __I  uint32_t  RESERVED5[62];
+  __IO uint32_t  LFCLKSRC;                          /*!< Clock source for the LFCLK clock.                                     */
+  __I  uint32_t  RESERVED6[7];
+  __IO uint32_t  CTIV;                              /*!< Calibration timer interval.                                           */
+  __I  uint32_t  RESERVED7[5];
+  __IO uint32_t  XTALFREQ;                          /*!< Crystal frequency.                                                    */
+} NRF_CLOCK_Type;
+
+
+/* ================================================================================ */
+/* ================                       MPU                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Memory Protection Unit. (MPU)
+  */
+
+typedef struct {                                    /*!< MPU Structure                                                         */
+  __I  uint32_t  RESERVED0[330];
+  __IO uint32_t  PERR0;                             /*!< Configuration of peripherals in mpu regions.                          */
+  __IO uint32_t  RLENR0;                            /*!< Length of RAM region 0.                                               */
+  __I  uint32_t  RESERVED1[52];
+  __IO uint32_t  PROTENSET0;                        /*!< Erase and write protection bit enable set register.                   */
+  __IO uint32_t  PROTENSET1;                        /*!< Erase and write protection bit enable set register.                   */
+  __IO uint32_t  DISABLEINDEBUG;                    /*!< Disable erase and write protection mechanism in debug mode.           */
+  __IO uint32_t  PROTBLOCKSIZE;                     /*!< Erase and write protection block size.                                */
+} NRF_MPU_Type;
+
+
+/* ================================================================================ */
+/* ================                      AMLI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AHB Multi-Layer Interface. (AMLI)
+  */
+
+typedef struct {                                    /*!< AMLI Structure                                                        */
+  __I  uint32_t  RESERVED0[896];
+  AMLI_RAMPRI_Type RAMPRI;                          /*!< RAM configurable priority configuration structure.                    */
+} NRF_AMLI_Type;
+
+
+/* ================================================================================ */
+/* ================                      RADIO                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief The radio. (RADIO)
+  */
+
+typedef struct {                                    /*!< RADIO Structure                                                       */
+  __O  uint32_t  TASKS_TXEN;                        /*!< Enable radio in TX mode.                                              */
+  __O  uint32_t  TASKS_RXEN;                        /*!< Enable radio in RX mode.                                              */
+  __O  uint32_t  TASKS_START;                       /*!< Start radio.                                                          */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop radio.                                                           */
+  __O  uint32_t  TASKS_DISABLE;                     /*!< Disable radio.                                                        */
+  __O  uint32_t  TASKS_RSSISTART;                   /*!< Start the RSSI and take one sample of the receive signal strength.    */
+  __O  uint32_t  TASKS_RSSISTOP;                    /*!< Stop the RSSI measurement.                                            */
+  __O  uint32_t  TASKS_BCSTART;                     /*!< Start the bit counter.                                                */
+  __O  uint32_t  TASKS_BCSTOP;                      /*!< Stop the bit counter.                                                 */
+  __I  uint32_t  RESERVED0[55];
+  __IO uint32_t  EVENTS_READY;                      /*!< Ready event.                                                          */
+  __IO uint32_t  EVENTS_ADDRESS;                    /*!< Address event.                                                        */
+  __IO uint32_t  EVENTS_PAYLOAD;                    /*!< Payload event.                                                        */
+  __IO uint32_t  EVENTS_END;                        /*!< End event.                                                            */
+  __IO uint32_t  EVENTS_DISABLED;                   /*!< Disable event.                                                        */
+  __IO uint32_t  EVENTS_DEVMATCH;                   /*!< A device address match occurred on the last received packet.          */
+  __IO uint32_t  EVENTS_DEVMISS;                    /*!< No device address match occurred on the last received packet.         */
+  __IO uint32_t  EVENTS_RSSIEND;                    /*!< Sampling of the receive signal strength complete. A new RSSI
+                                                         sample is ready for readout at the RSSISAMPLE register.               */
+  __I  uint32_t  RESERVED1[2];
+  __IO uint32_t  EVENTS_BCMATCH;                    /*!< Bit counter reached bit count value specified in BCC register.        */
+  __I  uint32_t  RESERVED2[53];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the radio.                                              */
+  __I  uint32_t  RESERVED3[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED4[61];
+  __I  uint32_t  CRCSTATUS;                         /*!< CRC status of received packet.                                        */
+  __I  uint32_t  RESERVED5;
+  __I  uint32_t  RXMATCH;                           /*!< Received address.                                                     */
+  __I  uint32_t  RXCRC;                             /*!< Received CRC.                                                         */
+  __I  uint32_t  DAI;                               /*!< Device address match index.                                           */
+  __I  uint32_t  RESERVED6[60];
+  __IO uint32_t  PACKETPTR;                         /*!< Packet pointer. Decision point: START task.                           */
+  __IO uint32_t  FREQUENCY;                         /*!< Frequency.                                                            */
+  __IO uint32_t  TXPOWER;                           /*!< Output power.                                                         */
+  __IO uint32_t  MODE;                              /*!< Data rate and modulation.                                             */
+  __IO uint32_t  PCNF0;                             /*!< Packet configuration 0.                                               */
+  __IO uint32_t  PCNF1;                             /*!< Packet configuration 1.                                               */
+  __IO uint32_t  BASE0;                             /*!< Radio base address 0. Decision point: START task.                     */
+  __IO uint32_t  BASE1;                             /*!< Radio base address 1. Decision point: START task.                     */
+  __IO uint32_t  PREFIX0;                           /*!< Prefixes bytes for logical addresses 0 to 3.                          */
+  __IO uint32_t  PREFIX1;                           /*!< Prefixes bytes for logical addresses 4 to 7.                          */
+  __IO uint32_t  TXADDRESS;                         /*!< Transmit address select.                                              */
+  __IO uint32_t  RXADDRESSES;                       /*!< Receive address select.                                               */
+  __IO uint32_t  CRCCNF;                            /*!< CRC configuration.                                                    */
+  __IO uint32_t  CRCPOLY;                           /*!< CRC polynomial.                                                       */
+  __IO uint32_t  CRCINIT;                           /*!< CRC initial value.                                                    */
+  __IO uint32_t  TEST;                              /*!< Test features enable register.                                        */
+  __IO uint32_t  TIFS;                              /*!< Inter Frame Spacing in microseconds.                                  */
+  __I  uint32_t  RSSISAMPLE;                        /*!< RSSI sample.                                                          */
+  __I  uint32_t  RESERVED7;
+  __I  uint32_t  STATE;                             /*!< Current radio state.                                                  */
+  __IO uint32_t  DATAWHITEIV;                       /*!< Data whitening initial value.                                         */
+  __I  uint32_t  RESERVED8[2];
+  __IO uint32_t  BCC;                               /*!< Bit counter compare.                                                  */
+  __I  uint32_t  RESERVED9[39];
+  __IO uint32_t  DAB[8];                            /*!< Device address base segment.                                          */
+  __IO uint32_t  DAP[8];                            /*!< Device address prefix.                                                */
+  __IO uint32_t  DACNF;                             /*!< Device address match configuration.                                   */
+  __I  uint32_t  RESERVED10[56];
+  __IO uint32_t  OVERRIDE0;                         /*!< Trim value override register 0.                                       */
+  __IO uint32_t  OVERRIDE1;                         /*!< Trim value override register 1.                                       */
+  __IO uint32_t  OVERRIDE2;                         /*!< Trim value override register 2.                                       */
+  __IO uint32_t  OVERRIDE3;                         /*!< Trim value override register 3.                                       */
+  __IO uint32_t  OVERRIDE4;                         /*!< Trim value override register 4.                                       */
+  __I  uint32_t  RESERVED11[561];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RADIO_Type;
+
+
+/* ================================================================================ */
+/* ================                      UART                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Universal Asynchronous Receiver/Transmitter. (UART)
+  */
+
+typedef struct {                                    /*!< UART Structure                                                        */
+  __O  uint32_t  TASKS_STARTRX;                     /*!< Start UART receiver.                                                  */
+  __O  uint32_t  TASKS_STOPRX;                      /*!< Stop UART receiver.                                                   */
+  __O  uint32_t  TASKS_STARTTX;                     /*!< Start UART transmitter.                                               */
+  __O  uint32_t  TASKS_STOPTX;                      /*!< Stop UART transmitter.                                                */
+  __I  uint32_t  RESERVED0[3];
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend UART.                                                         */
+  __I  uint32_t  RESERVED1[56];
+  __IO uint32_t  EVENTS_CTS;                        /*!< CTS activated.                                                        */
+  __IO uint32_t  EVENTS_NCTS;                       /*!< CTS deactivated.                                                      */
+  __IO uint32_t  EVENTS_RXDRDY;                     /*!< Data received in RXD.                                                 */
+  __I  uint32_t  RESERVED2[4];
+  __IO uint32_t  EVENTS_TXDRDY;                     /*!< Data sent from TXD.                                                   */
+  __I  uint32_t  RESERVED3;
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Error detected.                                                       */
+  __I  uint32_t  RESERVED4[7];
+  __IO uint32_t  EVENTS_RXTO;                       /*!< Receiver timeout.                                                     */
+  __I  uint32_t  RESERVED5[46];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for UART.                                                   */
+  __I  uint32_t  RESERVED6[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED7[93];
+  __IO uint32_t  ERRORSRC;                          /*!< Error source. Write error field to 1 to clear error.                  */
+  __I  uint32_t  RESERVED8[31];
+  __IO uint32_t  ENABLE;                            /*!< Enable UART and acquire IOs.                                          */
+  __I  uint32_t  RESERVED9;
+  __IO uint32_t  PSELRTS;                           /*!< Pin select for RTS.                                                   */
+  __IO uint32_t  PSELTXD;                           /*!< Pin select for TXD.                                                   */
+  __IO uint32_t  PSELCTS;                           /*!< Pin select for CTS.                                                   */
+  __IO uint32_t  PSELRXD;                           /*!< Pin select for RXD.                                                   */
+  __I  uint32_t  RXD;                               /*!< RXD register. On read action the buffer pointer is displaced.
+                                                         Once read the character is consumed. If read when no character
+                                                          available, the UART will stop working.                               */
+  __O  uint32_t  TXD;                               /*!< TXD register.                                                         */
+  __I  uint32_t  RESERVED10;
+  __IO uint32_t  BAUDRATE;                          /*!< UART Baudrate.                                                        */
+  __I  uint32_t  RESERVED11[17];
+  __IO uint32_t  CONFIG;                            /*!< Configuration of parity and hardware flow control register.           */
+  __I  uint32_t  RESERVED12[675];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_UART_Type;
+
+
+/* ================================================================================ */
+/* ================                       SPI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI master 0. (SPI)
+  */
+
+typedef struct {                                    /*!< SPI Structure                                                         */
+  __I  uint32_t  RESERVED0[66];
+  __IO uint32_t  EVENTS_READY;                      /*!< TXD byte sent and RXD byte received.                                  */
+  __I  uint32_t  RESERVED1[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPI.                                                           */
+  __I  uint32_t  RESERVED3;
+  __IO uint32_t  PSELSCK;                           /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  PSELMOSI;                          /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  PSELMISO;                          /*!< Pin select for MISO.                                                  */
+  __I  uint32_t  RESERVED4;
+  __I  uint32_t  RXD;                               /*!< RX data.                                                              */
+  __IO uint32_t  TXD;                               /*!< TX data.                                                              */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  FREQUENCY;                         /*!< SPI frequency                                                         */
+  __I  uint32_t  RESERVED6[11];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED7[681];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPI_Type;
+
+
+/* ================================================================================ */
+/* ================                       TWI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Two-wire interface master 0. (TWI)
+  */
+
+typedef struct {                                    /*!< TWI Structure                                                         */
+  __O  uint32_t  TASKS_STARTRX;                     /*!< Start 2-Wire master receive sequence.                                 */
+  __I  uint32_t  RESERVED0;
+  __O  uint32_t  TASKS_STARTTX;                     /*!< Start 2-Wire master transmit sequence.                                */
+  __I  uint32_t  RESERVED1[2];
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop 2-Wire transaction.                                              */
+  __I  uint32_t  RESERVED2;
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend 2-Wire transaction.                                           */
+  __O  uint32_t  TASKS_RESUME;                      /*!< Resume 2-Wire transaction.                                            */
+  __I  uint32_t  RESERVED3[56];
+  __IO uint32_t  EVENTS_STOPPED;                    /*!< Two-wire stopped.                                                     */
+  __IO uint32_t  EVENTS_RXDREADY;                   /*!< Two-wire ready to deliver new RXD byte received.                      */
+  __I  uint32_t  RESERVED4[4];
+  __IO uint32_t  EVENTS_TXDSENT;                    /*!< Two-wire finished sending last TXD byte.                              */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Two-wire error detected.                                              */
+  __I  uint32_t  RESERVED6[4];
+  __IO uint32_t  EVENTS_BB;                         /*!< Two-wire byte boundary.                                               */
+  __I  uint32_t  RESERVED7[3];
+  __IO uint32_t  EVENTS_SUSPENDED;                  /*!< Two-wire suspended.                                                   */
+  __I  uint32_t  RESERVED8[45];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for TWI.                                                    */
+  __I  uint32_t  RESERVED9[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED10[110];
+  __IO uint32_t  ERRORSRC;                          /*!< Two-wire error source. Write error field to 1 to clear error.         */
+  __I  uint32_t  RESERVED11[14];
+  __IO uint32_t  ENABLE;                            /*!< Enable two-wire master.                                               */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  PSELSCL;                           /*!< Pin select for SCL.                                                   */
+  __IO uint32_t  PSELSDA;                           /*!< Pin select for SDA.                                                   */
+  __I  uint32_t  RESERVED13[2];
+  __I  uint32_t  RXD;                               /*!< RX data register.                                                     */
+  __IO uint32_t  TXD;                               /*!< TX data register.                                                     */
+  __I  uint32_t  RESERVED14;
+  __IO uint32_t  FREQUENCY;                         /*!< Two-wire frequency.                                                   */
+  __I  uint32_t  RESERVED15[24];
+  __IO uint32_t  ADDRESS;                           /*!< Address used in the two-wire transfer.                                */
+  __I  uint32_t  RESERVED16[668];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TWI_Type;
+
+
+/* ================================================================================ */
+/* ================                      SPIS                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI slave 1. (SPIS)
+  */
+
+typedef struct {                                    /*!< SPIS Structure                                                        */
+  __I  uint32_t  RESERVED0[9];
+  __O  uint32_t  TASKS_ACQUIRE;                     /*!< Acquire SPI semaphore.                                                */
+  __O  uint32_t  TASKS_RELEASE;                     /*!< Release SPI semaphore.                                                */
+  __I  uint32_t  RESERVED1[54];
+  __IO uint32_t  EVENTS_END;                        /*!< Granted transaction completed.                                        */
+  __I  uint32_t  RESERVED2[2];
+  __IO uint32_t  EVENTS_ENDRX;                      /*!< End of RXD buffer reached                                             */
+  __I  uint32_t  RESERVED3[5];
+  __IO uint32_t  EVENTS_ACQUIRED;                   /*!< Semaphore acquired.                                                   */
+  __I  uint32_t  RESERVED4[53];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for SPIS.                                                   */
+  __I  uint32_t  RESERVED5[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED6[61];
+  __I  uint32_t  SEMSTAT;                           /*!< Semaphore status.                                                     */
+  __I  uint32_t  RESERVED7[15];
+  __IO uint32_t  STATUS;                            /*!< Status from last transaction.                                         */
+  __I  uint32_t  RESERVED8[47];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPIS.                                                          */
+  __I  uint32_t  RESERVED9;
+  __IO uint32_t  PSELSCK;                           /*!< Pin select for SCK.                                                   */
+  __IO uint32_t  PSELMISO;                          /*!< Pin select for MISO.                                                  */
+  __IO uint32_t  PSELMOSI;                          /*!< Pin select for MOSI.                                                  */
+  __IO uint32_t  PSELCSN;                           /*!< Pin select for CSN.                                                   */
+  __I  uint32_t  RESERVED10[7];
+  __IO uint32_t  RXDPTR;                            /*!< RX data pointer.                                                      */
+  __IO uint32_t  MAXRX;                             /*!< Maximum number of bytes in the receive buffer.                        */
+  __I  uint32_t  AMOUNTRX;                          /*!< Number of bytes received in last granted transaction.                 */
+  __I  uint32_t  RESERVED11;
+  __IO uint32_t  TXDPTR;                            /*!< TX data pointer.                                                      */
+  __IO uint32_t  MAXTX;                             /*!< Maximum number of bytes in the transmit buffer.                       */
+  __I  uint32_t  AMOUNTTX;                          /*!< Number of bytes transmitted in last granted transaction.              */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED13;
+  __IO uint32_t  DEF;                               /*!< Default character.                                                    */
+  __I  uint32_t  RESERVED14[24];
+  __IO uint32_t  ORC;                               /*!< Over-read character.                                                  */
+  __I  uint32_t  RESERVED15[654];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPIS_Type;
+
+
+/* ================================================================================ */
+/* ================                      SPIM                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SPI master with easyDMA 1. (SPIM)
+  */
+
+typedef struct {                                    /*!< SPIM Structure                                                        */
+  __I  uint32_t  RESERVED0[4];
+  __O  uint32_t  TASKS_START;                       /*!< Start SPI transaction.                                                */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop SPI transaction.                                                 */
+  __I  uint32_t  RESERVED1;
+  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend SPI transaction.                                              */
+  __O  uint32_t  TASKS_RESUME;                      /*!< Resume SPI transaction.                                               */
+  __I  uint32_t  RESERVED2[56];
+  __IO uint32_t  EVENTS_STOPPED;                    /*!< SPI transaction has stopped.                                          */
+  __I  uint32_t  RESERVED3[2];
+  __IO uint32_t  EVENTS_ENDRX;                      /*!< End of RXD buffer reached.                                            */
+  __I  uint32_t  RESERVED4[3];
+  __IO uint32_t  EVENTS_ENDTX;                      /*!< End of TXD buffer reached.                                            */
+  __I  uint32_t  RESERVED5[10];
+  __IO uint32_t  EVENTS_STARTED;                    /*!< Transaction started.                                                  */
+  __I  uint32_t  RESERVED6[109];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED7[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable SPIM.                                                          */
+  __I  uint32_t  RESERVED8;
+  SPIM_PSEL_Type PSEL;                              /*!< Pin select configuration.                                             */
+  __I  uint32_t  RESERVED9[4];
+  __IO uint32_t  FREQUENCY;                         /*!< SPI frequency.                                                        */
+  __I  uint32_t  RESERVED10[3];
+  SPIM_RXD_Type RXD;                                /*!< RXD EasyDMA configuration and status.                                 */
+  __I  uint32_t  RESERVED11;
+  SPIM_TXD_Type TXD;                                /*!< TXD EasyDMA configuration and status.                                 */
+  __I  uint32_t  RESERVED12;
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED13[26];
+  __IO uint32_t  ORC;                               /*!< Over-read character.                                                  */
+  __I  uint32_t  RESERVED14[654];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_SPIM_Type;
+
+
+/* ================================================================================ */
+/* ================                     GPIOTE                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief GPIO tasks and events. (GPIOTE)
+  */
+
+typedef struct {                                    /*!< GPIOTE Structure                                                      */
+  __O  uint32_t  TASKS_OUT[4];                      /*!< Tasks asssociated with GPIOTE channels.                               */
+  __I  uint32_t  RESERVED0[60];
+  __IO uint32_t  EVENTS_IN[4];                      /*!< Tasks asssociated with GPIOTE channels.                               */
+  __I  uint32_t  RESERVED1[27];
+  __IO uint32_t  EVENTS_PORT;                       /*!< Event generated from multiple pins.                                   */
+  __I  uint32_t  RESERVED2[97];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[129];
+  __IO uint32_t  CONFIG[4];                         /*!< Channel configuration registers.                                      */
+  __I  uint32_t  RESERVED4[695];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_GPIOTE_Type;
+
+
+/* ================================================================================ */
+/* ================                       ADC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Analog to digital converter. (ADC)
+  */
+
+typedef struct {                                    /*!< ADC Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start an ADC conversion.                                              */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop ADC.                                                             */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_END;                        /*!< ADC conversion complete.                                              */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[61];
+  __I  uint32_t  BUSY;                              /*!< ADC busy register.                                                    */
+  __I  uint32_t  RESERVED3[63];
+  __IO uint32_t  ENABLE;                            /*!< ADC enable.                                                           */
+  __IO uint32_t  CONFIG;                            /*!< ADC configuration register.                                           */
+  __I  uint32_t  RESULT;                            /*!< Result of ADC conversion.                                             */
+  __I  uint32_t  RESERVED4[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_ADC_Type;
+
+
+/* ================================================================================ */
+/* ================                      TIMER                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Timer 0. (TIMER)
+  */
+
+typedef struct {                                    /*!< TIMER Structure                                                       */
+  __O  uint32_t  TASKS_START;                       /*!< Start Timer.                                                          */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop Timer.                                                           */
+  __O  uint32_t  TASKS_COUNT;                       /*!< Increment Timer (In counter mode).                                    */
+  __O  uint32_t  TASKS_CLEAR;                       /*!< Clear timer.                                                          */
+  __O  uint32_t  TASKS_SHUTDOWN;                    /*!< Shutdown timer.                                                       */
+  __I  uint32_t  RESERVED0[11];
+  __O  uint32_t  TASKS_CAPTURE[4];                  /*!< Capture Timer value to CC[n] registers.                               */
+  __I  uint32_t  RESERVED1[60];
+  __IO uint32_t  EVENTS_COMPARE[4];                 /*!< Compare event on CC[n] match.                                         */
+  __I  uint32_t  RESERVED2[44];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for Timer.                                                  */
+  __I  uint32_t  RESERVED3[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED4[126];
+  __IO uint32_t  MODE;                              /*!< Timer Mode selection.                                                 */
+  __IO uint32_t  BITMODE;                           /*!< Sets timer behaviour.                                                 */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  PRESCALER;                         /*!< 4-bit prescaler to source clock frequency (max value 9). Source
+                                                         clock frequency is divided by 2^SCALE.                                */
+  __I  uint32_t  RESERVED6[11];
+  __IO uint32_t  CC[4];                             /*!< Capture/compare registers.                                            */
+  __I  uint32_t  RESERVED7[683];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TIMER_Type;
+
+
+/* ================================================================================ */
+/* ================                       RTC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Real time counter 0. (RTC)
+  */
+
+typedef struct {                                    /*!< RTC Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start RTC Counter.                                                    */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop RTC Counter.                                                     */
+  __O  uint32_t  TASKS_CLEAR;                       /*!< Clear RTC Counter.                                                    */
+  __O  uint32_t  TASKS_TRIGOVRFLW;                  /*!< Set COUNTER to 0xFFFFFFF0.                                            */
+  __I  uint32_t  RESERVED0[60];
+  __IO uint32_t  EVENTS_TICK;                       /*!< Event on COUNTER increment.                                           */
+  __IO uint32_t  EVENTS_OVRFLW;                     /*!< Event on COUNTER overflow.                                            */
+  __I  uint32_t  RESERVED1[14];
+  __IO uint32_t  EVENTS_COMPARE[4];                 /*!< Compare event on CC[n] match.                                         */
+  __I  uint32_t  RESERVED2[109];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[13];
+  __IO uint32_t  EVTEN;                             /*!< Configures event enable routing to PPI for each RTC event.            */
+  __IO uint32_t  EVTENSET;                          /*!< Enable events routing to PPI. The reading of this register gives
+                                                         the value of EVTEN.                                                   */
+  __IO uint32_t  EVTENCLR;                          /*!< Disable events routing to PPI. The reading of this register
+                                                         gives the value of EVTEN.                                             */
+  __I  uint32_t  RESERVED4[110];
+  __I  uint32_t  COUNTER;                           /*!< Current COUNTER value.                                                */
+  __IO uint32_t  PRESCALER;                         /*!< 12-bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).
+                                                         Must be written when RTC is STOPed.                                   */
+  __I  uint32_t  RESERVED5[13];
+  __IO uint32_t  CC[4];                             /*!< Capture/compare registers.                                            */
+  __I  uint32_t  RESERVED6[683];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RTC_Type;
+
+
+/* ================================================================================ */
+/* ================                      TEMP                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Temperature Sensor. (TEMP)
+  */
+
+typedef struct {                                    /*!< TEMP Structure                                                        */
+  __O  uint32_t  TASKS_START;                       /*!< Start temperature measurement.                                        */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop temperature measurement.                                         */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_DATARDY;                    /*!< Temperature measurement complete, data ready event.                   */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[127];
+  __I  int32_t   TEMP;                              /*!< Die temperature in degC, 2's complement format, 0.25 degC pecision.   */
+  __I  uint32_t  RESERVED3[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_TEMP_Type;
+
+
+/* ================================================================================ */
+/* ================                       RNG                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Random Number Generator. (RNG)
+  */
+
+typedef struct {                                    /*!< RNG Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start the random number generator.                                    */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the random number generator.                                     */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_VALRDY;                     /*!< New random number generated and written to VALUE register.            */
+  __I  uint32_t  RESERVED1[63];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the RNG.                                                */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register                                         */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register                                       */
+  __I  uint32_t  RESERVED3[126];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  VALUE;                             /*!< RNG random number.                                                    */
+  __I  uint32_t  RESERVED4[700];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_RNG_Type;
+
+
+/* ================================================================================ */
+/* ================                       ECB                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AES ECB Mode Encryption. (ECB)
+  */
+
+typedef struct {                                    /*!< ECB Structure                                                         */
+  __O  uint32_t  TASKS_STARTECB;                    /*!< Start ECB block encrypt. If a crypto operation is running, this
+                                                         will not initiate a new encryption and the ERRORECB event will
+                                                          be triggered.                                                        */
+  __O  uint32_t  TASKS_STOPECB;                     /*!< Stop current ECB encryption. If a crypto operation is running,
+                                                         this will will trigger the ERRORECB event.                            */
+  __I  uint32_t  RESERVED0[62];
+  __IO uint32_t  EVENTS_ENDECB;                     /*!< ECB block encrypt complete.                                           */
+  __IO uint32_t  EVENTS_ERRORECB;                   /*!< ECB block encrypt aborted due to a STOPECB task or due to an
+                                                         error.                                                                */
+  __I  uint32_t  RESERVED1[127];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  ECBDATAPTR;                        /*!< ECB block encrypt memory pointer.                                     */
+  __I  uint32_t  RESERVED3[701];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_ECB_Type;
+
+
+/* ================================================================================ */
+/* ================                       AAR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Accelerated Address Resolver. (AAR)
+  */
+
+typedef struct {                                    /*!< AAR Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start resolving addresses based on IRKs specified in the IRK
+                                                         data structure.                                                       */
+  __I  uint32_t  RESERVED0;
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop resolving addresses.                                             */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  EVENTS_END;                        /*!< Address resolution procedure completed.                               */
+  __IO uint32_t  EVENTS_RESOLVED;                   /*!< Address resolved.                                                     */
+  __IO uint32_t  EVENTS_NOTRESOLVED;                /*!< Address not resolved.                                                 */
+  __I  uint32_t  RESERVED2[126];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  STATUS;                            /*!< Resolution status.                                                    */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< Enable AAR.                                                           */
+  __IO uint32_t  NIRK;                              /*!< Number of Identity root Keys in the IRK data structure.               */
+  __IO uint32_t  IRKPTR;                            /*!< Pointer to the IRK data structure.                                    */
+  __I  uint32_t  RESERVED5;
+  __IO uint32_t  ADDRPTR;                           /*!< Pointer to the resolvable address (6 bytes).                          */
+  __IO uint32_t  SCRATCHPTR;                        /*!< Pointer to a "scratch" data area used for temporary storage
+                                                         during resolution. A minimum of 3 bytes must be reserved.             */
+  __I  uint32_t  RESERVED6[697];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_AAR_Type;
+
+
+/* ================================================================================ */
+/* ================                       CCM                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief AES CCM Mode Encryption. (CCM)
+  */
+
+typedef struct {                                    /*!< CCM Structure                                                         */
+  __O  uint32_t  TASKS_KSGEN;                       /*!< Start generation of key-stream. This operation will stop by
+                                                         itself when completed.                                                */
+  __O  uint32_t  TASKS_CRYPT;                       /*!< Start encrypt/decrypt. This operation will stop by itself when
+                                                         completed.                                                            */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop encrypt/decrypt.                                                 */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_ENDKSGEN;                   /*!< Keystream generation completed.                                       */
+  __IO uint32_t  EVENTS_ENDCRYPT;                   /*!< Encrypt/decrypt completed.                                            */
+  __IO uint32_t  EVENTS_ERROR;                      /*!< Error happened.                                                       */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the CCM.                                                */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  MICSTATUS;                         /*!< CCM RX MIC check result.                                              */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< CCM enable.                                                           */
+  __IO uint32_t  MODE;                              /*!< Operation mode.                                                       */
+  __IO uint32_t  CNFPTR;                            /*!< Pointer to a data structure holding AES key and NONCE vector.         */
+  __IO uint32_t  INPTR;                             /*!< Pointer to the input packet.                                          */
+  __IO uint32_t  OUTPTR;                            /*!< Pointer to the output packet.                                         */
+  __IO uint32_t  SCRATCHPTR;                        /*!< Pointer to a "scratch" data area used for temporary storage
+                                                         during resolution. A minimum of 43 bytes must be reserved.            */
+  __I  uint32_t  RESERVED5[697];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_CCM_Type;
+
+
+/* ================================================================================ */
+/* ================                       WDT                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Watchdog Timer. (WDT)
+  */
+
+typedef struct {                                    /*!< WDT Structure                                                         */
+  __O  uint32_t  TASKS_START;                       /*!< Start the watchdog.                                                   */
+  __I  uint32_t  RESERVED0[63];
+  __IO uint32_t  EVENTS_TIMEOUT;                    /*!< Watchdog timeout.                                                     */
+  __I  uint32_t  RESERVED1[128];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED2[61];
+  __I  uint32_t  RUNSTATUS;                         /*!< Watchdog running status.                                              */
+  __I  uint32_t  REQSTATUS;                         /*!< Request status.                                                       */
+  __I  uint32_t  RESERVED3[63];
+  __IO uint32_t  CRV;                               /*!< Counter reload value in number of 32kiHz clock cycles.                */
+  __IO uint32_t  RREN;                              /*!< Reload request enable.                                                */
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  __I  uint32_t  RESERVED4[60];
+  __O  uint32_t  RR[8];                             /*!< Reload requests registers.                                            */
+  __I  uint32_t  RESERVED5[631];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_WDT_Type;
+
+
+/* ================================================================================ */
+/* ================                      QDEC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Rotary decoder. (QDEC)
+  */
+
+typedef struct {                                    /*!< QDEC Structure                                                        */
+  __O  uint32_t  TASKS_START;                       /*!< Start the quadrature decoder.                                         */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the quadrature decoder.                                          */
+  __O  uint32_t  TASKS_READCLRACC;                  /*!< Transfers the content from ACC registers to ACCREAD registers,
+                                                         and clears the ACC registers.                                         */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_SAMPLERDY;                  /*!< A new sample is written to the sample register.                       */
+  __IO uint32_t  EVENTS_REPORTRDY;                  /*!< REPORTPER number of samples accumulated in ACC register, and
+                                                         ACC register different than zero.                                     */
+  __IO uint32_t  EVENTS_ACCOF;                      /*!< ACC or ACCDBL register overflow.                                      */
+  __I  uint32_t  RESERVED1[61];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the QDEC.                                               */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[125];
+  __IO uint32_t  ENABLE;                            /*!< Enable the QDEC.                                                      */
+  __IO uint32_t  LEDPOL;                            /*!< LED output pin polarity.                                              */
+  __IO uint32_t  SAMPLEPER;                         /*!< Sample period.                                                        */
+  __I  int32_t   SAMPLE;                            /*!< Motion sample value.                                                  */
+  __IO uint32_t  REPORTPER;                         /*!< Number of samples to generate an EVENT_REPORTRDY.                     */
+  __I  int32_t   ACC;                               /*!< Accumulated valid transitions register.                               */
+  __I  int32_t   ACCREAD;                           /*!< Snapshot of ACC register. Value generated by the TASKS_READCLEACC
+                                                         task.                                                                 */
+  __IO uint32_t  PSELLED;                           /*!< Pin select for LED output.                                            */
+  __IO uint32_t  PSELA;                             /*!< Pin select for phase A input.                                         */
+  __IO uint32_t  PSELB;                             /*!< Pin select for phase B input.                                         */
+  __IO uint32_t  DBFEN;                             /*!< Enable debouncer input filters.                                       */
+  __I  uint32_t  RESERVED4[5];
+  __IO uint32_t  LEDPRE;                            /*!< Time LED is switched ON before the sample.                            */
+  __I  uint32_t  ACCDBL;                            /*!< Accumulated double (error) transitions register.                      */
+  __I  uint32_t  ACCDBLREAD;                        /*!< Snapshot of ACCDBL register. Value generated by the TASKS_READCLEACC
+                                                         task.                                                                 */
+  __I  uint32_t  RESERVED5[684];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_QDEC_Type;
+
+
+/* ================================================================================ */
+/* ================                     LPCOMP                     ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Low power comparator. (LPCOMP)
+  */
+
+typedef struct {                                    /*!< LPCOMP Structure                                                      */
+  __O  uint32_t  TASKS_START;                       /*!< Start the comparator.                                                 */
+  __O  uint32_t  TASKS_STOP;                        /*!< Stop the comparator.                                                  */
+  __O  uint32_t  TASKS_SAMPLE;                      /*!< Sample comparator value.                                              */
+  __I  uint32_t  RESERVED0[61];
+  __IO uint32_t  EVENTS_READY;                      /*!< LPCOMP is ready and output is valid.                                  */
+  __IO uint32_t  EVENTS_DOWN;                       /*!< Input voltage crossed the threshold going down.                       */
+  __IO uint32_t  EVENTS_UP;                         /*!< Input voltage crossed the threshold going up.                         */
+  __IO uint32_t  EVENTS_CROSS;                      /*!< Input voltage crossed the threshold in any direction.                 */
+  __I  uint32_t  RESERVED1[60];
+  __IO uint32_t  SHORTS;                            /*!< Shortcuts for the LPCOMP.                                             */
+  __I  uint32_t  RESERVED2[64];
+  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
+  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
+  __I  uint32_t  RESERVED3[61];
+  __I  uint32_t  RESULT;                            /*!< Result of last compare.                                               */
+  __I  uint32_t  RESERVED4[63];
+  __IO uint32_t  ENABLE;                            /*!< Enable the LPCOMP.                                                    */
+  __IO uint32_t  PSEL;                              /*!< Input pin select.                                                     */
+  __IO uint32_t  REFSEL;                            /*!< Reference select.                                                     */
+  __IO uint32_t  EXTREFSEL;                         /*!< External reference select.                                            */
+  __I  uint32_t  RESERVED5[4];
+  __IO uint32_t  ANADETECT;                         /*!< Analog detect configuration.                                          */
+  __I  uint32_t  RESERVED6[694];
+  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
+} NRF_LPCOMP_Type;
+
+
+/* ================================================================================ */
+/* ================                       SWI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief SW Interrupts. (SWI)
+  */
+
+typedef struct {                                    /*!< SWI Structure                                                         */
+  __I  uint32_t  UNUSED;                            /*!< Unused.                                                               */
+} NRF_SWI_Type;
+
+
+/* ================================================================================ */
+/* ================                      NVMC                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Non Volatile Memory Controller. (NVMC)
+  */
+
+typedef struct {                                    /*!< NVMC Structure                                                        */
+  __I  uint32_t  RESERVED0[256];
+  __I  uint32_t  READY;                             /*!< Ready flag.                                                           */
+  __I  uint32_t  RESERVED1[64];
+  __IO uint32_t  CONFIG;                            /*!< Configuration register.                                               */
+  
+  union {
+    __IO uint32_t  ERASEPCR1;                       /*!< Register for erasing a non-protected non-volatile memory page.        */
+    __IO uint32_t  ERASEPAGE;                       /*!< Register for erasing a non-protected non-volatile memory page.        */
+  };
+  __IO uint32_t  ERASEALL;                          /*!< Register for erasing all non-volatile user memory.                    */
+  __IO uint32_t  ERASEPCR0;                         /*!< Register for erasing a protected non-volatile memory page.            */
+  __IO uint32_t  ERASEUICR;                         /*!< Register for start erasing User Information Congfiguration Registers. */
+} NRF_NVMC_Type;
+
+
+/* ================================================================================ */
+/* ================                       PPI                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief PPI controller. (PPI)
+  */
+
+typedef struct {                                    /*!< PPI Structure                                                         */
+  PPI_TASKS_CHG_Type TASKS_CHG[4];                  /*!< Channel group tasks.                                                  */
+  __I  uint32_t  RESERVED0[312];
+  __IO uint32_t  CHEN;                              /*!< Channel enable.                                                       */
+  __IO uint32_t  CHENSET;                           /*!< Channel enable set.                                                   */
+  __IO uint32_t  CHENCLR;                           /*!< Channel enable clear.                                                 */
+  __I  uint32_t  RESERVED1;
+  PPI_CH_Type CH[16];                               /*!< PPI Channel.                                                          */
+  __I  uint32_t  RESERVED2[156];
+  __IO uint32_t  CHG[4];                            /*!< Channel group configuration.                                          */
+} NRF_PPI_Type;
+
+
+/* ================================================================================ */
+/* ================                      FICR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief Factory Information Configuration. (FICR)
+  */
+
+typedef struct {                                    /*!< FICR Structure                                                        */
+  __I  uint32_t  RESERVED0[4];
+  __I  uint32_t  CODEPAGESIZE;                      /*!< Code memory page size in bytes.                                       */
+  __I  uint32_t  CODESIZE;                          /*!< Code memory size in pages.                                            */
+  __I  uint32_t  RESERVED1[4];
+  __I  uint32_t  CLENR0;                            /*!< Length of code region 0 in bytes.                                     */
+  __I  uint32_t  PPFC;                              /*!< Pre-programmed factory code present.                                  */
+  __I  uint32_t  RESERVED2;
+  __I  uint32_t  NUMRAMBLOCK;                       /*!< Number of individualy controllable RAM blocks.                        */
+  
+  union {
+    __I  uint32_t  SIZERAMBLOCK[4];                 /*!< Deprecated array of size of RAM block in bytes. This name is
+                                                         kept for backward compatinility purposes. Use SIZERAMBLOCKS
+                                                          instead.                                                             */
+    __I  uint32_t  SIZERAMBLOCKS;                   /*!< Size of RAM blocks in bytes.                                          */
+  };
+  __I  uint32_t  RESERVED3[5];
+  __I  uint32_t  CONFIGID;                          /*!< Configuration identifier.                                             */
+  __I  uint32_t  DEVICEID[2];                       /*!< Device identifier.                                                    */
+  __I  uint32_t  RESERVED4[6];
+  __I  uint32_t  ER[4];                             /*!< Encryption root.                                                      */
+  __I  uint32_t  IR[4];                             /*!< Identity root.                                                        */
+  __I  uint32_t  DEVICEADDRTYPE;                    /*!< Device address type.                                                  */
+  __I  uint32_t  DEVICEADDR[2];                     /*!< Device address.                                                       */
+  __I  uint32_t  OVERRIDEEN;                        /*!< Radio calibration override enable.                                    */
+  __I  uint32_t  NRF_1MBIT[5];                      /*!< Override values for the OVERRIDEn registers in RADIO for NRF_1Mbit
+                                                         mode.                                                                 */
+  __I  uint32_t  RESERVED5[10];
+  __I  uint32_t  BLE_1MBIT[5];                      /*!< Override values for the OVERRIDEn registers in RADIO for BLE_1Mbit
+                                                         mode.                                                                 */
+} NRF_FICR_Type;
+
+
+/* ================================================================================ */
+/* ================                      UICR                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief User Information Configuration. (UICR)
+  */
+
+typedef struct {                                    /*!< UICR Structure                                                        */
+  __IO uint32_t  CLENR0;                            /*!< Length of code region 0.                                              */
+  __IO uint32_t  RBPCONF;                           /*!< Readback protection configuration.                                    */
+  __IO uint32_t  XTALFREQ;                          /*!< Reset value for CLOCK XTALFREQ register.                              */
+  __I  uint32_t  RESERVED0;
+  __I  uint32_t  FWID;                              /*!< Firmware ID.                                                          */
+  
+  union {
+    __IO uint32_t  NRFFW[15];                       /*!< Reserved for Nordic firmware design.                                  */
+    __IO uint32_t  BOOTLOADERADDR;                  /*!< Bootloader start address.                                             */
+  };
+  __IO uint32_t  NRFHW[12];                         /*!< Reserved for Nordic hardware design.                                  */
+  __IO uint32_t  CUSTOMER[32];                      /*!< Reserved for customer.                                                */
+} NRF_UICR_Type;
+
+
+/* ================================================================================ */
+/* ================                      GPIO                      ================ */
+/* ================================================================================ */
+
+
+/**
+  * @brief General purpose input and output. (GPIO)
+  */
+
+typedef struct {                                    /*!< GPIO Structure                                                        */
+  __I  uint32_t  RESERVED0[321];
+  __IO uint32_t  OUT;                               /*!< Write GPIO port.                                                      */
+  __IO uint32_t  OUTSET;                            /*!< Set individual bits in GPIO port.                                     */
+  __IO uint32_t  OUTCLR;                            /*!< Clear individual bits in GPIO port.                                   */
+  __I  uint32_t  IN;                                /*!< Read GPIO port.                                                       */
+  __IO uint32_t  DIR;                               /*!< Direction of GPIO pins.                                               */
+  __IO uint32_t  DIRSET;                            /*!< DIR set register.                                                     */
+  __IO uint32_t  DIRCLR;                            /*!< DIR clear register.                                                   */
+  __I  uint32_t  RESERVED1[120];
+  __IO uint32_t  PIN_CNF[32];                       /*!< Configuration of GPIO pins.                                           */
+} NRF_GPIO_Type;
+
+
+/* --------------------  End of section using anonymous unions  ------------------- */
+#if defined(__CC_ARM)
+  #pragma pop
+#elif defined(__ICCARM__)
+  /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TMS470__)
+  /* anonymous unions are enabled by default */
+#elif defined(__TASKING__)
+  #pragma warning restore
+#else
+  #warning Not supported compiler type
+#endif
+
+
+
+
+/* ================================================================================ */
+/* ================              Peripheral memory map             ================ */
+/* ================================================================================ */
+
+#define NRF_POWER_BASE                  0x40000000UL
+#define NRF_CLOCK_BASE                  0x40000000UL
+#define NRF_MPU_BASE                    0x40000000UL
+#define NRF_AMLI_BASE                   0x40000000UL
+#define NRF_RADIO_BASE                  0x40001000UL
+#define NRF_UART0_BASE                  0x40002000UL
+#define NRF_SPI0_BASE                   0x40003000UL
+#define NRF_TWI0_BASE                   0x40003000UL
+#define NRF_SPI1_BASE                   0x40004000UL
+#define NRF_TWI1_BASE                   0x40004000UL
+#define NRF_SPIS1_BASE                  0x40004000UL
+#define NRF_SPIM1_BASE                  0x40004000UL
+#define NRF_GPIOTE_BASE                 0x40006000UL
+#define NRF_ADC_BASE                    0x40007000UL
+#define NRF_TIMER0_BASE                 0x40008000UL
+#define NRF_TIMER1_BASE                 0x40009000UL
+#define NRF_TIMER2_BASE                 0x4000A000UL
+#define NRF_RTC0_BASE                   0x4000B000UL
+#define NRF_TEMP_BASE                   0x4000C000UL
+#define NRF_RNG_BASE                    0x4000D000UL
+#define NRF_ECB_BASE                    0x4000E000UL
+#define NRF_AAR_BASE                    0x4000F000UL
+#define NRF_CCM_BASE                    0x4000F000UL
+#define NRF_WDT_BASE                    0x40010000UL
+#define NRF_RTC1_BASE                   0x40011000UL
+#define NRF_QDEC_BASE                   0x40012000UL
+#define NRF_LPCOMP_BASE                 0x40013000UL
+#define NRF_SWI_BASE                    0x40014000UL
+#define NRF_NVMC_BASE                   0x4001E000UL
+#define NRF_PPI_BASE                    0x4001F000UL
+#define NRF_FICR_BASE                   0x10000000UL
+#define NRF_UICR_BASE                   0x10001000UL
+#define NRF_GPIO_BASE                   0x50000000UL
+
+
+/* ================================================================================ */
+/* ================             Peripheral declaration             ================ */
+/* ================================================================================ */
+
+#define NRF_POWER                       ((NRF_POWER_Type          *) NRF_POWER_BASE)
+#define NRF_CLOCK                       ((NRF_CLOCK_Type          *) NRF_CLOCK_BASE)
+#define NRF_MPU                         ((NRF_MPU_Type            *) NRF_MPU_BASE)
+#define NRF_AMLI                        ((NRF_AMLI_Type           *) NRF_AMLI_BASE)
+#define NRF_RADIO                       ((NRF_RADIO_Type          *) NRF_RADIO_BASE)
+#define NRF_UART0                       ((NRF_UART_Type           *) NRF_UART0_BASE)
+#define NRF_SPI0                        ((NRF_SPI_Type            *) NRF_SPI0_BASE)
+#define NRF_TWI0                        ((NRF_TWI_Type            *) NRF_TWI0_BASE)
+#define NRF_SPI1                        ((NRF_SPI_Type            *) NRF_SPI1_BASE)
+#define NRF_TWI1                        ((NRF_TWI_Type            *) NRF_TWI1_BASE)
+#define NRF_SPIS1                       ((NRF_SPIS_Type           *) NRF_SPIS1_BASE)
+#define NRF_SPIM1                       ((NRF_SPIM_Type           *) NRF_SPIM1_BASE)
+#define NRF_GPIOTE                      ((NRF_GPIOTE_Type         *) NRF_GPIOTE_BASE)
+#define NRF_ADC                         ((NRF_ADC_Type            *) NRF_ADC_BASE)
+#define NRF_TIMER0                      ((NRF_TIMER_Type          *) NRF_TIMER0_BASE)
+#define NRF_TIMER1                      ((NRF_TIMER_Type          *) NRF_TIMER1_BASE)
+#define NRF_TIMER2                      ((NRF_TIMER_Type          *) NRF_TIMER2_BASE)
+#define NRF_RTC0                        ((NRF_RTC_Type            *) NRF_RTC0_BASE)
+#define NRF_TEMP                        ((NRF_TEMP_Type           *) NRF_TEMP_BASE)
+#define NRF_RNG                         ((NRF_RNG_Type            *) NRF_RNG_BASE)
+#define NRF_ECB                         ((NRF_ECB_Type            *) NRF_ECB_BASE)
+#define NRF_AAR                         ((NRF_AAR_Type            *) NRF_AAR_BASE)
+#define NRF_CCM                         ((NRF_CCM_Type            *) NRF_CCM_BASE)
+#define NRF_WDT                         ((NRF_WDT_Type            *) NRF_WDT_BASE)
+#define NRF_RTC1                        ((NRF_RTC_Type            *) NRF_RTC1_BASE)
+#define NRF_QDEC                        ((NRF_QDEC_Type           *) NRF_QDEC_BASE)
+#define NRF_LPCOMP                      ((NRF_LPCOMP_Type         *) NRF_LPCOMP_BASE)
+#define NRF_SWI                         ((NRF_SWI_Type            *) NRF_SWI_BASE)
+#define NRF_NVMC                        ((NRF_NVMC_Type           *) NRF_NVMC_BASE)
+#define NRF_PPI                         ((NRF_PPI_Type            *) NRF_PPI_BASE)
+#define NRF_FICR                        ((NRF_FICR_Type           *) NRF_FICR_BASE)
+#define NRF_UICR                        ((NRF_UICR_Type           *) NRF_UICR_BASE)
+#define NRF_GPIO                        ((NRF_GPIO_Type           *) NRF_GPIO_BASE)
+
+
+/** @} */ /* End of group Device_Peripheral_Registers */
+/** @} */ /* End of group nrf51 */
+/** @} */ /* End of group Nordic Semiconductor */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif  /* nrf51_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51_bitfields.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,6894 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 __NRF51_BITS_H
+#define __NRF51_BITS_H
+
+/*lint ++flb "Enter library region" */
+
+/* Peripheral: AAR */
+/* Description: Accelerated Address Resolver. */
+
+/* Register: AAR_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on NOTRESOLVED event. */
+#define AAR_INTENSET_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */
+#define AAR_INTENSET_NOTRESOLVED_Msk (0x1UL << AAR_INTENSET_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */
+#define AAR_INTENSET_NOTRESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_NOTRESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_NOTRESOLVED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on RESOLVED event. */
+#define AAR_INTENSET_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */
+#define AAR_INTENSET_RESOLVED_Msk (0x1UL << AAR_INTENSET_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */
+#define AAR_INTENSET_RESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_RESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_RESOLVED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on END event. */
+#define AAR_INTENSET_END_Pos (0UL) /*!< Position of END field. */
+#define AAR_INTENSET_END_Msk (0x1UL << AAR_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define AAR_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: AAR_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on NOTRESOLVED event. */
+#define AAR_INTENCLR_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */
+#define AAR_INTENCLR_NOTRESOLVED_Msk (0x1UL << AAR_INTENCLR_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */
+#define AAR_INTENCLR_NOTRESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_NOTRESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_NOTRESOLVED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on RESOLVED event. */
+#define AAR_INTENCLR_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */
+#define AAR_INTENCLR_RESOLVED_Msk (0x1UL << AAR_INTENCLR_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */
+#define AAR_INTENCLR_RESOLVED_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_RESOLVED_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_RESOLVED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDKSGEN event. */
+#define AAR_INTENCLR_END_Pos (0UL) /*!< Position of END field. */
+#define AAR_INTENCLR_END_Msk (0x1UL << AAR_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define AAR_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define AAR_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define AAR_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: AAR_STATUS */
+/* Description: Resolution status. */
+
+/* Bits 3..0 : The IRK used last time an address was resolved. */
+#define AAR_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define AAR_STATUS_STATUS_Msk (0xFUL << AAR_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */
+
+/* Register: AAR_ENABLE */
+/* Description: Enable AAR. */
+
+/* Bits 1..0 : Enable AAR. */
+#define AAR_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define AAR_ENABLE_ENABLE_Msk (0x3UL << AAR_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define AAR_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled AAR. */
+#define AAR_ENABLE_ENABLE_Enabled (0x03UL) /*!< Enable AAR. */
+
+/* Register: AAR_NIRK */
+/* Description: Number of Identity root Keys in the IRK data structure. */
+
+/* Bits 4..0 : Number of Identity root Keys in the IRK data structure. */
+#define AAR_NIRK_NIRK_Pos (0UL) /*!< Position of NIRK field. */
+#define AAR_NIRK_NIRK_Msk (0x1FUL << AAR_NIRK_NIRK_Pos) /*!< Bit mask of NIRK field. */
+
+/* Register: AAR_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define AAR_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define AAR_POWER_POWER_Msk (0x1UL << AAR_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define AAR_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define AAR_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: ADC */
+/* Description: Analog to digital converter. */
+
+/* Register: ADC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on END event. */
+#define ADC_INTENSET_END_Pos (0UL) /*!< Position of END field. */
+#define ADC_INTENSET_END_Msk (0x1UL << ADC_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define ADC_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define ADC_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define ADC_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: ADC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on END event. */
+#define ADC_INTENCLR_END_Pos (0UL) /*!< Position of END field. */
+#define ADC_INTENCLR_END_Msk (0x1UL << ADC_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define ADC_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define ADC_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define ADC_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: ADC_BUSY */
+/* Description: ADC busy register. */
+
+/* Bit 0 : ADC busy register. */
+#define ADC_BUSY_BUSY_Pos (0UL) /*!< Position of BUSY field. */
+#define ADC_BUSY_BUSY_Msk (0x1UL << ADC_BUSY_BUSY_Pos) /*!< Bit mask of BUSY field. */
+#define ADC_BUSY_BUSY_Ready (0UL) /*!< No ongoing ADC conversion is taking place. ADC is ready. */
+#define ADC_BUSY_BUSY_Busy (1UL) /*!< An ADC conversion is taking place. ADC is busy. */
+
+/* Register: ADC_ENABLE */
+/* Description: ADC enable. */
+
+/* Bits 1..0 : ADC enable. */
+#define ADC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define ADC_ENABLE_ENABLE_Msk (0x3UL << ADC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define ADC_ENABLE_ENABLE_Disabled (0x00UL) /*!< ADC is disabled. */
+#define ADC_ENABLE_ENABLE_Enabled (0x01UL) /*!< ADC is enabled. If an analog input pin is selected as source of the conversion, the selected pin is configured as an analog input. */
+
+/* Register: ADC_CONFIG */
+/* Description: ADC configuration register. */
+
+/* Bits 17..16 : ADC external reference pin selection. */
+#define ADC_CONFIG_EXTREFSEL_Pos (16UL) /*!< Position of EXTREFSEL field. */
+#define ADC_CONFIG_EXTREFSEL_Msk (0x3UL << ADC_CONFIG_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */
+#define ADC_CONFIG_EXTREFSEL_None (0UL) /*!< Analog external reference inputs disabled. */
+#define ADC_CONFIG_EXTREFSEL_AnalogReference0 (1UL) /*!< Use analog reference 0 as reference. */
+#define ADC_CONFIG_EXTREFSEL_AnalogReference1 (2UL) /*!< Use analog reference 1 as reference. */
+
+/* Bits 15..8 : ADC analog pin selection. */
+#define ADC_CONFIG_PSEL_Pos (8UL) /*!< Position of PSEL field. */
+#define ADC_CONFIG_PSEL_Msk (0xFFUL << ADC_CONFIG_PSEL_Pos) /*!< Bit mask of PSEL field. */
+#define ADC_CONFIG_PSEL_Disabled (0UL) /*!< Analog input pins disabled. */
+#define ADC_CONFIG_PSEL_AnalogInput0 (1UL) /*!< Use analog input 0 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput1 (2UL) /*!< Use analog input 1 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput2 (4UL) /*!< Use analog input 2 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput3 (8UL) /*!< Use analog input 3 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput4 (16UL) /*!< Use analog input 4 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput5 (32UL) /*!< Use analog input 5 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput6 (64UL) /*!< Use analog input 6 as analog input. */
+#define ADC_CONFIG_PSEL_AnalogInput7 (128UL) /*!< Use analog input 7 as analog input. */
+
+/* Bits 6..5 : ADC reference selection. */
+#define ADC_CONFIG_REFSEL_Pos (5UL) /*!< Position of REFSEL field. */
+#define ADC_CONFIG_REFSEL_Msk (0x3UL << ADC_CONFIG_REFSEL_Pos) /*!< Bit mask of REFSEL field. */
+#define ADC_CONFIG_REFSEL_VBG (0x00UL) /*!< Use internal 1.2V bandgap voltage as reference for conversion. */
+#define ADC_CONFIG_REFSEL_External (0x01UL) /*!< Use external source configured by EXTREFSEL as reference for conversion. */
+#define ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling (0x02UL) /*!< Use supply voltage with 1/2 prescaling as reference for conversion. Only usable when supply voltage is between 1.7V and 2.6V. */
+#define ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling (0x03UL) /*!< Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V. */
+
+/* Bits 4..2 : ADC input selection. */
+#define ADC_CONFIG_INPSEL_Pos (2UL) /*!< Position of INPSEL field. */
+#define ADC_CONFIG_INPSEL_Msk (0x7UL << ADC_CONFIG_INPSEL_Pos) /*!< Bit mask of INPSEL field. */
+#define ADC_CONFIG_INPSEL_AnalogInputNoPrescaling (0x00UL) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling (0x01UL) /*!< Analog input specified by PSEL with 2/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling (0x02UL) /*!< Analog input specified by PSEL with 1/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling (0x05UL) /*!< Supply voltage with 2/3 prescaling used as input for the conversion. */
+#define ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling (0x06UL) /*!< Supply voltage with 1/3 prescaling used as input for the conversion. */
+
+/* Bits 1..0 : ADC resolution. */
+#define ADC_CONFIG_RES_Pos (0UL) /*!< Position of RES field. */
+#define ADC_CONFIG_RES_Msk (0x3UL << ADC_CONFIG_RES_Pos) /*!< Bit mask of RES field. */
+#define ADC_CONFIG_RES_8bit (0x00UL) /*!< 8bit ADC resolution. */
+#define ADC_CONFIG_RES_9bit (0x01UL) /*!< 9bit ADC resolution. */
+#define ADC_CONFIG_RES_10bit (0x02UL) /*!< 10bit ADC resolution. */
+
+/* Register: ADC_RESULT */
+/* Description: Result of ADC conversion. */
+
+/* Bits 9..0 : Result of ADC conversion. */
+#define ADC_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */
+#define ADC_RESULT_RESULT_Msk (0x3FFUL << ADC_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */
+
+/* Register: ADC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define ADC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define ADC_POWER_POWER_Msk (0x1UL << ADC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define ADC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define ADC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: AMLI */
+/* Description: AHB Multi-Layer Interface. */
+
+/* Register: AMLI_RAMPRI_CPU0 */
+/* Description: Configurable priority configuration register for CPU0. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_CPU0_RAM7_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_CPU0_RAM6_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_CPU0_RAM5_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_CPU0_RAM4_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_CPU0_RAM3_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_CPU0_RAM2_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_CPU0_RAM1_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_CPU0_RAM0_Msk (0xFUL << AMLI_RAMPRI_CPU0_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CPU0_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_SPIS1 */
+/* Description: Configurable priority configuration register for SPIS1. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Msk (0xFUL << AMLI_RAMPRI_SPIS1_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_SPIS1_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_RADIO */
+/* Description: Configurable priority configuration register for RADIO. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_RADIO_RAM7_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_RADIO_RAM6_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_RADIO_RAM5_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_RADIO_RAM4_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_RADIO_RAM3_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_RADIO_RAM2_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_RADIO_RAM1_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_RADIO_RAM0_Msk (0xFUL << AMLI_RAMPRI_RADIO_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_RADIO_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_ECB */
+/* Description: Configurable priority configuration register for ECB. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_ECB_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_ECB_RAM7_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_ECB_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_ECB_RAM6_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_ECB_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_ECB_RAM5_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_ECB_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_ECB_RAM4_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_ECB_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_ECB_RAM3_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_ECB_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_ECB_RAM2_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_ECB_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_ECB_RAM1_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_ECB_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_ECB_RAM0_Msk (0xFUL << AMLI_RAMPRI_ECB_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_ECB_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_CCM */
+/* Description: Configurable priority configuration register for CCM. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_CCM_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_CCM_RAM7_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_CCM_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_CCM_RAM6_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_CCM_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_CCM_RAM5_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_CCM_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_CCM_RAM4_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_CCM_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_CCM_RAM3_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_CCM_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_CCM_RAM2_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_CCM_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_CCM_RAM1_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_CCM_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_CCM_RAM0_Msk (0xFUL << AMLI_RAMPRI_CCM_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_CCM_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Register: AMLI_RAMPRI_AAR */
+/* Description: Configurable priority configuration register for AAR. */
+
+/* Bits 31..28 : Configuration field for RAM block 7. */
+#define AMLI_RAMPRI_AAR_RAM7_Pos (28UL) /*!< Position of RAM7 field. */
+#define AMLI_RAMPRI_AAR_RAM7_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM7_Pos) /*!< Bit mask of RAM7 field. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM7_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 27..24 : Configuration field for RAM block 6. */
+#define AMLI_RAMPRI_AAR_RAM6_Pos (24UL) /*!< Position of RAM6 field. */
+#define AMLI_RAMPRI_AAR_RAM6_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM6_Pos) /*!< Bit mask of RAM6 field. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM6_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 23..20 : Configuration field for RAM block 5. */
+#define AMLI_RAMPRI_AAR_RAM5_Pos (20UL) /*!< Position of RAM5 field. */
+#define AMLI_RAMPRI_AAR_RAM5_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM5_Pos) /*!< Bit mask of RAM5 field. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM5_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 19..16 : Configuration field for RAM block 4. */
+#define AMLI_RAMPRI_AAR_RAM4_Pos (16UL) /*!< Position of RAM4 field. */
+#define AMLI_RAMPRI_AAR_RAM4_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM4_Pos) /*!< Bit mask of RAM4 field. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM4_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 15..12 : Configuration field for RAM block 3. */
+#define AMLI_RAMPRI_AAR_RAM3_Pos (12UL) /*!< Position of RAM3 field. */
+#define AMLI_RAMPRI_AAR_RAM3_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM3_Pos) /*!< Bit mask of RAM3 field. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM3_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 11..8 : Configuration field for RAM block 2. */
+#define AMLI_RAMPRI_AAR_RAM2_Pos (8UL) /*!< Position of RAM2 field. */
+#define AMLI_RAMPRI_AAR_RAM2_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM2_Pos) /*!< Bit mask of RAM2 field. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM2_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 7..4 : Configuration field for RAM block 1. */
+#define AMLI_RAMPRI_AAR_RAM1_Pos (4UL) /*!< Position of RAM1 field. */
+#define AMLI_RAMPRI_AAR_RAM1_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM1_Pos) /*!< Bit mask of RAM1 field. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM1_Pri14 (0xEUL) /*!< Priority 14. */
+
+/* Bits 3..0 : Configuration field for RAM block 0. */
+#define AMLI_RAMPRI_AAR_RAM0_Pos (0UL) /*!< Position of RAM0 field. */
+#define AMLI_RAMPRI_AAR_RAM0_Msk (0xFUL << AMLI_RAMPRI_AAR_RAM0_Pos) /*!< Bit mask of RAM0 field. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri0 (0x0UL) /*!< Priority 0. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri2 (0x2UL) /*!< Priority 2. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri4 (0x4UL) /*!< Priority 4. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri6 (0x6UL) /*!< Priority 6. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri8 (0x8UL) /*!< Priority 8. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri10 (0xAUL) /*!< Priority 10. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri12 (0xCUL) /*!< Priority 12. */
+#define AMLI_RAMPRI_AAR_RAM0_Pri14 (0xEUL) /*!< Priority 14. */
+
+
+/* Peripheral: CCM */
+/* Description: AES CCM Mode Encryption. */
+
+/* Register: CCM_SHORTS */
+/* Description: Shortcuts for the CCM. */
+
+/* Bit 0 : Shortcut between ENDKSGEN event and CRYPT task. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Pos (0UL) /*!< Position of ENDKSGEN_CRYPT field. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Msk (0x1UL << CCM_SHORTS_ENDKSGEN_CRYPT_Pos) /*!< Bit mask of ENDKSGEN_CRYPT field. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Disabled (0UL) /*!< Shortcut disabled. */
+#define CCM_SHORTS_ENDKSGEN_CRYPT_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: CCM_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on ERROR event. */
+#define CCM_INTENSET_ERROR_Pos (2UL) /*!< Position of ERROR field. */
+#define CCM_INTENSET_ERROR_Msk (0x1UL << CCM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define CCM_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on ENDCRYPT event. */
+#define CCM_INTENSET_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */
+#define CCM_INTENSET_ENDCRYPT_Msk (0x1UL << CCM_INTENSET_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */
+#define CCM_INTENSET_ENDCRYPT_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ENDCRYPT_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ENDCRYPT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on ENDKSGEN event. */
+#define CCM_INTENSET_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */
+#define CCM_INTENSET_ENDKSGEN_Msk (0x1UL << CCM_INTENSET_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */
+#define CCM_INTENSET_ENDKSGEN_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENSET_ENDKSGEN_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENSET_ENDKSGEN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: CCM_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on ERROR event. */
+#define CCM_INTENCLR_ERROR_Pos (2UL) /*!< Position of ERROR field. */
+#define CCM_INTENCLR_ERROR_Msk (0x1UL << CCM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define CCM_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on ENDCRYPT event. */
+#define CCM_INTENCLR_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */
+#define CCM_INTENCLR_ENDCRYPT_Msk (0x1UL << CCM_INTENCLR_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */
+#define CCM_INTENCLR_ENDCRYPT_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ENDCRYPT_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ENDCRYPT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDKSGEN event. */
+#define CCM_INTENCLR_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */
+#define CCM_INTENCLR_ENDKSGEN_Msk (0x1UL << CCM_INTENCLR_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */
+#define CCM_INTENCLR_ENDKSGEN_Disabled (0UL) /*!< Interrupt disabled. */
+#define CCM_INTENCLR_ENDKSGEN_Enabled (1UL) /*!< Interrupt enabled. */
+#define CCM_INTENCLR_ENDKSGEN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: CCM_MICSTATUS */
+/* Description: CCM RX MIC check result. */
+
+/* Bit 0 : Result of the MIC check performed during the previous CCM RX STARTCRYPT */
+#define CCM_MICSTATUS_MICSTATUS_Pos (0UL) /*!< Position of MICSTATUS field. */
+#define CCM_MICSTATUS_MICSTATUS_Msk (0x1UL << CCM_MICSTATUS_MICSTATUS_Pos) /*!< Bit mask of MICSTATUS field. */
+#define CCM_MICSTATUS_MICSTATUS_CheckFailed (0UL) /*!< MIC check failed. */
+#define CCM_MICSTATUS_MICSTATUS_CheckPassed (1UL) /*!< MIC check passed. */
+
+/* Register: CCM_ENABLE */
+/* Description: CCM enable. */
+
+/* Bits 1..0 : CCM enable. */
+#define CCM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define CCM_ENABLE_ENABLE_Msk (0x3UL << CCM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define CCM_ENABLE_ENABLE_Disabled (0x00UL) /*!< CCM is disabled. */
+#define CCM_ENABLE_ENABLE_Enabled (0x02UL) /*!< CCM is enabled. */
+
+/* Register: CCM_MODE */
+/* Description: Operation mode. */
+
+/* Bit 0 : CCM mode operation. */
+#define CCM_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define CCM_MODE_MODE_Msk (0x1UL << CCM_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define CCM_MODE_MODE_Encryption (0UL) /*!< CCM mode TX */
+#define CCM_MODE_MODE_Decryption (1UL) /*!< CCM mode TX */
+
+/* Register: CCM_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define CCM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define CCM_POWER_POWER_Msk (0x1UL << CCM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define CCM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define CCM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: CLOCK */
+/* Description: Clock control. */
+
+/* Register: CLOCK_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 4 : Enable interrupt on CTTO event. */
+#define CLOCK_INTENSET_CTTO_Pos (4UL) /*!< Position of CTTO field. */
+#define CLOCK_INTENSET_CTTO_Msk (0x1UL << CLOCK_INTENSET_CTTO_Pos) /*!< Bit mask of CTTO field. */
+#define CLOCK_INTENSET_CTTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_CTTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_CTTO_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on DONE event. */
+#define CLOCK_INTENSET_DONE_Pos (3UL) /*!< Position of DONE field. */
+#define CLOCK_INTENSET_DONE_Msk (0x1UL << CLOCK_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */
+#define CLOCK_INTENSET_DONE_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_DONE_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_DONE_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on LFCLKSTARTED event. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_LFCLKSTARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on HFCLKSTARTED event. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENSET_HFCLKSTARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: CLOCK_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 4 : Disable interrupt on CTTO event. */
+#define CLOCK_INTENCLR_CTTO_Pos (4UL) /*!< Position of CTTO field. */
+#define CLOCK_INTENCLR_CTTO_Msk (0x1UL << CLOCK_INTENCLR_CTTO_Pos) /*!< Bit mask of CTTO field. */
+#define CLOCK_INTENCLR_CTTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_CTTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_CTTO_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on DONE event. */
+#define CLOCK_INTENCLR_DONE_Pos (3UL) /*!< Position of DONE field. */
+#define CLOCK_INTENCLR_DONE_Msk (0x1UL << CLOCK_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */
+#define CLOCK_INTENCLR_DONE_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_DONE_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_DONE_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on LFCLKSTARTED event. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_LFCLKSTARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on HFCLKSTARTED event. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define CLOCK_INTENCLR_HFCLKSTARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: CLOCK_HFCLKRUN */
+/* Description: Task HFCLKSTART trigger status. */
+
+/* Bit 0 : Task HFCLKSTART trigger status. */
+#define CLOCK_HFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define CLOCK_HFCLKRUN_STATUS_Msk (0x1UL << CLOCK_HFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */
+#define CLOCK_HFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task HFCLKSTART has not been triggered. */
+#define CLOCK_HFCLKRUN_STATUS_Triggered (1UL) /*!< Task HFCLKSTART has been triggered. */
+
+/* Register: CLOCK_HFCLKSTAT */
+/* Description: High frequency clock status. */
+
+/* Bit 16 : State for the HFCLK. */
+#define CLOCK_HFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */
+#define CLOCK_HFCLKSTAT_STATE_Msk (0x1UL << CLOCK_HFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */
+#define CLOCK_HFCLKSTAT_STATE_NotRunning (0UL) /*!< HFCLK clock not running. */
+#define CLOCK_HFCLKSTAT_STATE_Running (1UL) /*!< HFCLK clock running. */
+
+/* Bit 0 : Active clock source for the HF clock. */
+#define CLOCK_HFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_HFCLKSTAT_SRC_Msk (0x1UL << CLOCK_HFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_HFCLKSTAT_SRC_RC (0UL) /*!< Internal 16MHz RC oscillator running and generating the HFCLK clock. */
+#define CLOCK_HFCLKSTAT_SRC_Xtal (1UL) /*!< External 16MHz/32MHz crystal oscillator running and generating the HFCLK clock. */
+
+/* Register: CLOCK_LFCLKRUN */
+/* Description: Task LFCLKSTART triggered status. */
+
+/* Bit 0 : Task LFCLKSTART triggered status. */
+#define CLOCK_LFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */
+#define CLOCK_LFCLKRUN_STATUS_Msk (0x1UL << CLOCK_LFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */
+#define CLOCK_LFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task LFCLKSTART has not been triggered. */
+#define CLOCK_LFCLKRUN_STATUS_Triggered (1UL) /*!< Task LFCLKSTART has been triggered. */
+
+/* Register: CLOCK_LFCLKSTAT */
+/* Description: Low frequency clock status. */
+
+/* Bit 16 : State for the LF clock. */
+#define CLOCK_LFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */
+#define CLOCK_LFCLKSTAT_STATE_Msk (0x1UL << CLOCK_LFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */
+#define CLOCK_LFCLKSTAT_STATE_NotRunning (0UL) /*!< LFCLK clock not running. */
+#define CLOCK_LFCLKSTAT_STATE_Running (1UL) /*!< LFCLK clock running. */
+
+/* Bits 1..0 : Active clock source for the LF clock. */
+#define CLOCK_LFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSTAT_SRC_Msk (0x3UL << CLOCK_LFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSTAT_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator running and generating the LFCLK clock. */
+#define CLOCK_LFCLKSTAT_SRC_Xtal (1UL) /*!< External 32KiHz crystal oscillator running and generating the LFCLK clock. */
+#define CLOCK_LFCLKSTAT_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from the HFCLK running and generating the LFCLK clock. */
+
+/* Register: CLOCK_LFCLKSRCCOPY */
+/* Description: Clock source for the LFCLK clock, set when task LKCLKSTART is triggered. */
+
+/* Bits 1..0 : Clock source for the LFCLK clock, set when task LKCLKSTART is triggered. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Msk (0x3UL << CLOCK_LFCLKSRCCOPY_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSRCCOPY_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Xtal (1UL) /*!< External 32KiHz crystal. */
+#define CLOCK_LFCLKSRCCOPY_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from HFCLK system clock. */
+
+/* Register: CLOCK_LFCLKSRC */
+/* Description: Clock source for the LFCLK clock. */
+
+/* Bits 1..0 : Clock source. */
+#define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */
+#define CLOCK_LFCLKSRC_SRC_Msk (0x3UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of SRC field. */
+#define CLOCK_LFCLKSRC_SRC_RC (0UL) /*!< Internal 32KiHz RC oscillator. */
+#define CLOCK_LFCLKSRC_SRC_Xtal (1UL) /*!< External 32KiHz crystal. */
+#define CLOCK_LFCLKSRC_SRC_Synth (2UL) /*!< Internal 32KiHz synthesizer from HFCLK system clock. */
+
+/* Register: CLOCK_CTIV */
+/* Description: Calibration timer interval. */
+
+/* Bits 6..0 : Calibration timer interval in 0.25s resolution. */
+#define CLOCK_CTIV_CTIV_Pos (0UL) /*!< Position of CTIV field. */
+#define CLOCK_CTIV_CTIV_Msk (0x7FUL << CLOCK_CTIV_CTIV_Pos) /*!< Bit mask of CTIV field. */
+
+/* Register: CLOCK_XTALFREQ */
+/* Description: Crystal frequency. */
+
+/* Bits 7..0 : External Xtal frequency selection. */
+#define CLOCK_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
+#define CLOCK_XTALFREQ_XTALFREQ_Msk (0xFFUL << CLOCK_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
+#define CLOCK_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz xtal is used as source for the HFCLK oscillator. */
+#define CLOCK_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz xtal is used as source for the HFCLK oscillator. */
+
+
+/* Peripheral: ECB */
+/* Description: AES ECB Mode Encryption. */
+
+/* Register: ECB_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 1 : Enable interrupt on ERRORECB event. */
+#define ECB_INTENSET_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */
+#define ECB_INTENSET_ERRORECB_Msk (0x1UL << ECB_INTENSET_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */
+#define ECB_INTENSET_ERRORECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENSET_ERRORECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENSET_ERRORECB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on ENDECB event. */
+#define ECB_INTENSET_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */
+#define ECB_INTENSET_ENDECB_Msk (0x1UL << ECB_INTENSET_ENDECB_Pos) /*!< Bit mask of ENDECB field. */
+#define ECB_INTENSET_ENDECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENSET_ENDECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENSET_ENDECB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: ECB_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 1 : Disable interrupt on ERRORECB event. */
+#define ECB_INTENCLR_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */
+#define ECB_INTENCLR_ERRORECB_Msk (0x1UL << ECB_INTENCLR_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */
+#define ECB_INTENCLR_ERRORECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENCLR_ERRORECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENCLR_ERRORECB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on ENDECB event. */
+#define ECB_INTENCLR_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */
+#define ECB_INTENCLR_ENDECB_Msk (0x1UL << ECB_INTENCLR_ENDECB_Pos) /*!< Bit mask of ENDECB field. */
+#define ECB_INTENCLR_ENDECB_Disabled (0UL) /*!< Interrupt disabled. */
+#define ECB_INTENCLR_ENDECB_Enabled (1UL) /*!< Interrupt enabled. */
+#define ECB_INTENCLR_ENDECB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: ECB_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define ECB_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define ECB_POWER_POWER_Msk (0x1UL << ECB_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define ECB_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define ECB_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: FICR */
+/* Description: Factory Information Configuration. */
+
+/* Register: FICR_PPFC */
+/* Description: Pre-programmed factory code present. */
+
+/* Bits 7..0 : Pre-programmed factory code present. */
+#define FICR_PPFC_PPFC_Pos (0UL) /*!< Position of PPFC field. */
+#define FICR_PPFC_PPFC_Msk (0xFFUL << FICR_PPFC_PPFC_Pos) /*!< Bit mask of PPFC field. */
+#define FICR_PPFC_PPFC_Present (0x00UL) /*!< Present. */
+#define FICR_PPFC_PPFC_NotPresent (0xFFUL) /*!< Not present. */
+
+/* Register: FICR_CONFIGID */
+/* Description: Configuration identifier. */
+
+/* Bits 31..16 : Firmware Identification Number pre-loaded into the flash. */
+#define FICR_CONFIGID_FWID_Pos (16UL) /*!< Position of FWID field. */
+#define FICR_CONFIGID_FWID_Msk (0xFFFFUL << FICR_CONFIGID_FWID_Pos) /*!< Bit mask of FWID field. */
+
+/* Bits 15..0 : Hardware Identification Number. */
+#define FICR_CONFIGID_HWID_Pos (0UL) /*!< Position of HWID field. */
+#define FICR_CONFIGID_HWID_Msk (0xFFFFUL << FICR_CONFIGID_HWID_Pos) /*!< Bit mask of HWID field. */
+
+/* Register: FICR_DEVICEADDRTYPE */
+/* Description: Device address type. */
+
+/* Bit 0 : Device address type. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos (0UL) /*!< Position of DEVICEADDRTYPE field. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Msk (0x1UL << FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos) /*!< Bit mask of DEVICEADDRTYPE field. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Public (0UL) /*!< Public address. */
+#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Random (1UL) /*!< Random address. */
+
+/* Register: FICR_OVERRIDEEN */
+/* Description: Radio calibration override enable. */
+
+/* Bit 3 : Override default values for BLE_1Mbit mode. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Pos (3UL) /*!< Position of BLE_1MBIT field. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Msk (0x1UL << FICR_OVERRIDEEN_BLE_1MBIT_Pos) /*!< Bit mask of BLE_1MBIT field. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_Override (0UL) /*!< Override the default values for BLE_1Mbit mode. */
+#define FICR_OVERRIDEEN_BLE_1MBIT_NotOverride (1UL) /*!< Do not override the default values for BLE_1Mbit mode. */
+
+/* Bit 0 : Override default values for NRF_1Mbit mode. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Pos (0UL) /*!< Position of NRF_1MBIT field. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Msk (0x1UL << FICR_OVERRIDEEN_NRF_1MBIT_Pos) /*!< Bit mask of NRF_1MBIT field. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_Override (0UL) /*!< Override the default values for NRF_1Mbit mode. */
+#define FICR_OVERRIDEEN_NRF_1MBIT_NotOverride (1UL) /*!< Do not override the default values for NRF_1Mbit mode. */
+
+
+/* Peripheral: GPIO */
+/* Description: General purpose input and output. */
+
+/* Register: GPIO_OUT */
+/* Description: Write GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUT_PIN0_High (1UL) /*!< Pin driver is high. */
+
+/* Register: GPIO_OUTSET */
+/* Description: Set individual bits in GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUTSET_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN31_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN31_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUTSET_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN30_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN30_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUTSET_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN29_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN29_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUTSET_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN28_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN28_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUTSET_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN27_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN27_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUTSET_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN26_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN26_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUTSET_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN25_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN25_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUTSET_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN24_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN24_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUTSET_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN23_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN23_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUTSET_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN22_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN22_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUTSET_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN21_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN21_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUTSET_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN20_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN20_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUTSET_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN19_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN19_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUTSET_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN18_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN18_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUTSET_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN17_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN17_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUTSET_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN16_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN16_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUTSET_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN15_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN15_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUTSET_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN14_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN14_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUTSET_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN13_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN13_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUTSET_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN12_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN12_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUTSET_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN11_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN11_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUTSET_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN10_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN10_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUTSET_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN9_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN9_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUTSET_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN8_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN8_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUTSET_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN7_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN7_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUTSET_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN6_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN6_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUTSET_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN5_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN5_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUTSET_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN4_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN4_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUTSET_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN3_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN3_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUTSET_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN2_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN2_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUTSET_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN1_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN1_Set (1UL) /*!< Set pin driver high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUTSET_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTSET_PIN0_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTSET_PIN0_Set (1UL) /*!< Set pin driver high. */
+
+/* Register: GPIO_OUTCLR */
+/* Description: Clear individual bits in GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN31_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN30_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN29_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN28_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN27_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN26_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN25_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN24_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN23_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN22_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN21_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN20_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN19_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN18_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN17_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN16_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN15_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN14_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN13_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN12_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN11_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN10_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN9_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN8_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN7_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN6_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN5_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN4_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN3_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN2_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN1_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Set pin driver low. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Pin driver is low. */
+#define GPIO_OUTCLR_PIN0_High (1UL) /*!< Pin driver is high. */
+#define GPIO_OUTCLR_PIN0_Clear (1UL) /*!< Set pin driver low. */
+
+/* Register: GPIO_IN */
+/* Description: Read GPIO port. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low. */
+#define GPIO_IN_PIN0_High (1UL) /*!< Pin input is high. */
+
+/* Register: GPIO_DIR */
+/* Description: Direction of GPIO pins. */
+
+/* Bit 31 : Pin 31. */
+#define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 30 : Pin 30. */
+#define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 29 : Pin 29. */
+#define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 28 : Pin 28. */
+#define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 27 : Pin 27. */
+#define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 26 : Pin 26. */
+#define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 25 : Pin 25. */
+#define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 24 : Pin 24. */
+#define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 23 : Pin 23. */
+#define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 22 : Pin 22. */
+#define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 21 : Pin 21. */
+#define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 20 : Pin 20. */
+#define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 19 : Pin 19. */
+#define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 18 : Pin 18. */
+#define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 17 : Pin 17. */
+#define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 16 : Pin 16. */
+#define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 15 : Pin 15. */
+#define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 14 : Pin 14. */
+#define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 13 : Pin 13. */
+#define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 12 : Pin 12. */
+#define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 11 : Pin 11. */
+#define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 10 : Pin 10. */
+#define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 9 : Pin 9. */
+#define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 8 : Pin 8. */
+#define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 7 : Pin 7. */
+#define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 6 : Pin 6. */
+#define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 5 : Pin 5. */
+#define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 4 : Pin 4. */
+#define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 3 : Pin 3. */
+#define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 2 : Pin 2. */
+#define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 1 : Pin 1. */
+#define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output. */
+
+/* Bit 0 : Pin 0. */
+#define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIR_PIN0_Output (1UL) /*!< Pin set as output. */
+
+/* Register: GPIO_DIRSET */
+/* Description: DIR set register. */
+
+/* Bit 31 : Set as output pin 31. */
+#define GPIO_DIRSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIRSET_PIN31_Msk (0x1UL << GPIO_DIRSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIRSET_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN31_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN31_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 30 : Set as output pin 30. */
+#define GPIO_DIRSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIRSET_PIN30_Msk (0x1UL << GPIO_DIRSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIRSET_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN30_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN30_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 29 : Set as output pin 29. */
+#define GPIO_DIRSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIRSET_PIN29_Msk (0x1UL << GPIO_DIRSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIRSET_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN29_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN29_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 28 : Set as output pin 28. */
+#define GPIO_DIRSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIRSET_PIN28_Msk (0x1UL << GPIO_DIRSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIRSET_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN28_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN28_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 27 : Set as output pin 27. */
+#define GPIO_DIRSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIRSET_PIN27_Msk (0x1UL << GPIO_DIRSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIRSET_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN27_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN27_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 26 : Set as output pin 26. */
+#define GPIO_DIRSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIRSET_PIN26_Msk (0x1UL << GPIO_DIRSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIRSET_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN26_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN26_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 25 : Set as output pin 25. */
+#define GPIO_DIRSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIRSET_PIN25_Msk (0x1UL << GPIO_DIRSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIRSET_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN25_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN25_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 24 : Set as output pin 24. */
+#define GPIO_DIRSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIRSET_PIN24_Msk (0x1UL << GPIO_DIRSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIRSET_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN24_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN24_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 23 : Set as output pin 23. */
+#define GPIO_DIRSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIRSET_PIN23_Msk (0x1UL << GPIO_DIRSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIRSET_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN23_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN23_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 22 : Set as output pin 22. */
+#define GPIO_DIRSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIRSET_PIN22_Msk (0x1UL << GPIO_DIRSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIRSET_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN22_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN22_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 21 : Set as output pin 21. */
+#define GPIO_DIRSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIRSET_PIN21_Msk (0x1UL << GPIO_DIRSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIRSET_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN21_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN21_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 20 : Set as output pin 20. */
+#define GPIO_DIRSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIRSET_PIN20_Msk (0x1UL << GPIO_DIRSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIRSET_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN20_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN20_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 19 : Set as output pin 19. */
+#define GPIO_DIRSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIRSET_PIN19_Msk (0x1UL << GPIO_DIRSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIRSET_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN19_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN19_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 18 : Set as output pin 18. */
+#define GPIO_DIRSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIRSET_PIN18_Msk (0x1UL << GPIO_DIRSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIRSET_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN18_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN18_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 17 : Set as output pin 17. */
+#define GPIO_DIRSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIRSET_PIN17_Msk (0x1UL << GPIO_DIRSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIRSET_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN17_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN17_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 16 : Set as output pin 16. */
+#define GPIO_DIRSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIRSET_PIN16_Msk (0x1UL << GPIO_DIRSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIRSET_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN16_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN16_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 15 : Set as output pin 15. */
+#define GPIO_DIRSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIRSET_PIN15_Msk (0x1UL << GPIO_DIRSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIRSET_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN15_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN15_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 14 : Set as output pin 14. */
+#define GPIO_DIRSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIRSET_PIN14_Msk (0x1UL << GPIO_DIRSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIRSET_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN14_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN14_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 13 : Set as output pin 13. */
+#define GPIO_DIRSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIRSET_PIN13_Msk (0x1UL << GPIO_DIRSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIRSET_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN13_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN13_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 12 : Set as output pin 12. */
+#define GPIO_DIRSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIRSET_PIN12_Msk (0x1UL << GPIO_DIRSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIRSET_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN12_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN12_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 11 : Set as output pin 11. */
+#define GPIO_DIRSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIRSET_PIN11_Msk (0x1UL << GPIO_DIRSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIRSET_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN11_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN11_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 10 : Set as output pin 10. */
+#define GPIO_DIRSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIRSET_PIN10_Msk (0x1UL << GPIO_DIRSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIRSET_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN10_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN10_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 9 : Set as output pin 9. */
+#define GPIO_DIRSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIRSET_PIN9_Msk (0x1UL << GPIO_DIRSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIRSET_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN9_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN9_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 8 : Set as output pin 8. */
+#define GPIO_DIRSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIRSET_PIN8_Msk (0x1UL << GPIO_DIRSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIRSET_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN8_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN8_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 7 : Set as output pin 7. */
+#define GPIO_DIRSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIRSET_PIN7_Msk (0x1UL << GPIO_DIRSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIRSET_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN7_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN7_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 6 : Set as output pin 6. */
+#define GPIO_DIRSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIRSET_PIN6_Msk (0x1UL << GPIO_DIRSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIRSET_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN6_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN6_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 5 : Set as output pin 5. */
+#define GPIO_DIRSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIRSET_PIN5_Msk (0x1UL << GPIO_DIRSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIRSET_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN5_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN5_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 4 : Set as output pin 4. */
+#define GPIO_DIRSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIRSET_PIN4_Msk (0x1UL << GPIO_DIRSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIRSET_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN4_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN4_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 3 : Set as output pin 3. */
+#define GPIO_DIRSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIRSET_PIN3_Msk (0x1UL << GPIO_DIRSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIRSET_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN3_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN3_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 2 : Set as output pin 2. */
+#define GPIO_DIRSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIRSET_PIN2_Msk (0x1UL << GPIO_DIRSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIRSET_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN2_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN2_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 1 : Set as output pin 1. */
+#define GPIO_DIRSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIRSET_PIN1_Msk (0x1UL << GPIO_DIRSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIRSET_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN1_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN1_Set (1UL) /*!< Set pin as output. */
+
+/* Bit 0 : Set as output pin 0. */
+#define GPIO_DIRSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIRSET_PIN0_Msk (0x1UL << GPIO_DIRSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIRSET_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRSET_PIN0_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRSET_PIN0_Set (1UL) /*!< Set pin as output. */
+
+/* Register: GPIO_DIRCLR */
+/* Description: DIR clear register. */
+
+/* Bit 31 : Set as input pin 31. */
+#define GPIO_DIRCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */
+#define GPIO_DIRCLR_PIN31_Msk (0x1UL << GPIO_DIRCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */
+#define GPIO_DIRCLR_PIN31_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN31_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN31_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 30 : Set as input pin 30. */
+#define GPIO_DIRCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */
+#define GPIO_DIRCLR_PIN30_Msk (0x1UL << GPIO_DIRCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */
+#define GPIO_DIRCLR_PIN30_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN30_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN30_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 29 : Set as input pin 29. */
+#define GPIO_DIRCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */
+#define GPIO_DIRCLR_PIN29_Msk (0x1UL << GPIO_DIRCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */
+#define GPIO_DIRCLR_PIN29_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN29_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN29_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 28 : Set as input pin 28. */
+#define GPIO_DIRCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */
+#define GPIO_DIRCLR_PIN28_Msk (0x1UL << GPIO_DIRCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */
+#define GPIO_DIRCLR_PIN28_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN28_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN28_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 27 : Set as input pin 27. */
+#define GPIO_DIRCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */
+#define GPIO_DIRCLR_PIN27_Msk (0x1UL << GPIO_DIRCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */
+#define GPIO_DIRCLR_PIN27_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN27_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN27_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 26 : Set as input pin 26. */
+#define GPIO_DIRCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */
+#define GPIO_DIRCLR_PIN26_Msk (0x1UL << GPIO_DIRCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */
+#define GPIO_DIRCLR_PIN26_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN26_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN26_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 25 : Set as input pin 25. */
+#define GPIO_DIRCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */
+#define GPIO_DIRCLR_PIN25_Msk (0x1UL << GPIO_DIRCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */
+#define GPIO_DIRCLR_PIN25_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN25_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN25_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 24 : Set as input pin 24. */
+#define GPIO_DIRCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */
+#define GPIO_DIRCLR_PIN24_Msk (0x1UL << GPIO_DIRCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */
+#define GPIO_DIRCLR_PIN24_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN24_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN24_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 23 : Set as input pin 23. */
+#define GPIO_DIRCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */
+#define GPIO_DIRCLR_PIN23_Msk (0x1UL << GPIO_DIRCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */
+#define GPIO_DIRCLR_PIN23_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN23_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN23_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 22 : Set as input pin 22. */
+#define GPIO_DIRCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */
+#define GPIO_DIRCLR_PIN22_Msk (0x1UL << GPIO_DIRCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */
+#define GPIO_DIRCLR_PIN22_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN22_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN22_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 21 : Set as input pin 21. */
+#define GPIO_DIRCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */
+#define GPIO_DIRCLR_PIN21_Msk (0x1UL << GPIO_DIRCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */
+#define GPIO_DIRCLR_PIN21_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN21_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN21_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 20 : Set as input pin 20. */
+#define GPIO_DIRCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */
+#define GPIO_DIRCLR_PIN20_Msk (0x1UL << GPIO_DIRCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */
+#define GPIO_DIRCLR_PIN20_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN20_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN20_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 19 : Set as input pin 19. */
+#define GPIO_DIRCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */
+#define GPIO_DIRCLR_PIN19_Msk (0x1UL << GPIO_DIRCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */
+#define GPIO_DIRCLR_PIN19_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN19_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN19_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 18 : Set as input pin 18. */
+#define GPIO_DIRCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */
+#define GPIO_DIRCLR_PIN18_Msk (0x1UL << GPIO_DIRCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */
+#define GPIO_DIRCLR_PIN18_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN18_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN18_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 17 : Set as input pin 17. */
+#define GPIO_DIRCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */
+#define GPIO_DIRCLR_PIN17_Msk (0x1UL << GPIO_DIRCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */
+#define GPIO_DIRCLR_PIN17_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN17_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN17_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 16 : Set as input pin 16. */
+#define GPIO_DIRCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */
+#define GPIO_DIRCLR_PIN16_Msk (0x1UL << GPIO_DIRCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */
+#define GPIO_DIRCLR_PIN16_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN16_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN16_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 15 : Set as input pin 15. */
+#define GPIO_DIRCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */
+#define GPIO_DIRCLR_PIN15_Msk (0x1UL << GPIO_DIRCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */
+#define GPIO_DIRCLR_PIN15_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN15_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN15_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 14 : Set as input pin 14. */
+#define GPIO_DIRCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */
+#define GPIO_DIRCLR_PIN14_Msk (0x1UL << GPIO_DIRCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */
+#define GPIO_DIRCLR_PIN14_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN14_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN14_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 13 : Set as input pin 13. */
+#define GPIO_DIRCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */
+#define GPIO_DIRCLR_PIN13_Msk (0x1UL << GPIO_DIRCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */
+#define GPIO_DIRCLR_PIN13_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN13_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN13_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 12 : Set as input pin 12. */
+#define GPIO_DIRCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */
+#define GPIO_DIRCLR_PIN12_Msk (0x1UL << GPIO_DIRCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */
+#define GPIO_DIRCLR_PIN12_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN12_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN12_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 11 : Set as input pin 11. */
+#define GPIO_DIRCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */
+#define GPIO_DIRCLR_PIN11_Msk (0x1UL << GPIO_DIRCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */
+#define GPIO_DIRCLR_PIN11_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN11_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN11_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 10 : Set as input pin 10. */
+#define GPIO_DIRCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */
+#define GPIO_DIRCLR_PIN10_Msk (0x1UL << GPIO_DIRCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */
+#define GPIO_DIRCLR_PIN10_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN10_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN10_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 9 : Set as input pin 9. */
+#define GPIO_DIRCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */
+#define GPIO_DIRCLR_PIN9_Msk (0x1UL << GPIO_DIRCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */
+#define GPIO_DIRCLR_PIN9_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN9_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN9_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 8 : Set as input pin 8. */
+#define GPIO_DIRCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */
+#define GPIO_DIRCLR_PIN8_Msk (0x1UL << GPIO_DIRCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */
+#define GPIO_DIRCLR_PIN8_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN8_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN8_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 7 : Set as input pin 7. */
+#define GPIO_DIRCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */
+#define GPIO_DIRCLR_PIN7_Msk (0x1UL << GPIO_DIRCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */
+#define GPIO_DIRCLR_PIN7_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN7_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN7_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 6 : Set as input pin 6. */
+#define GPIO_DIRCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */
+#define GPIO_DIRCLR_PIN6_Msk (0x1UL << GPIO_DIRCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */
+#define GPIO_DIRCLR_PIN6_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN6_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN6_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 5 : Set as input pin 5. */
+#define GPIO_DIRCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */
+#define GPIO_DIRCLR_PIN5_Msk (0x1UL << GPIO_DIRCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */
+#define GPIO_DIRCLR_PIN5_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN5_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN5_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 4 : Set as input pin 4. */
+#define GPIO_DIRCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */
+#define GPIO_DIRCLR_PIN4_Msk (0x1UL << GPIO_DIRCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */
+#define GPIO_DIRCLR_PIN4_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN4_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN4_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 3 : Set as input pin 3. */
+#define GPIO_DIRCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */
+#define GPIO_DIRCLR_PIN3_Msk (0x1UL << GPIO_DIRCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */
+#define GPIO_DIRCLR_PIN3_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN3_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN3_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 2 : Set as input pin 2. */
+#define GPIO_DIRCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */
+#define GPIO_DIRCLR_PIN2_Msk (0x1UL << GPIO_DIRCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */
+#define GPIO_DIRCLR_PIN2_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN2_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN2_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 1 : Set as input pin 1. */
+#define GPIO_DIRCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */
+#define GPIO_DIRCLR_PIN1_Msk (0x1UL << GPIO_DIRCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */
+#define GPIO_DIRCLR_PIN1_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN1_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN1_Clear (1UL) /*!< Set pin as input. */
+
+/* Bit 0 : Set as input pin 0. */
+#define GPIO_DIRCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */
+#define GPIO_DIRCLR_PIN0_Msk (0x1UL << GPIO_DIRCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */
+#define GPIO_DIRCLR_PIN0_Input (0UL) /*!< Pin set as input. */
+#define GPIO_DIRCLR_PIN0_Output (1UL) /*!< Pin set as output. */
+#define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Set pin as input. */
+
+/* Register: GPIO_PIN_CNF */
+/* Description: Configuration of GPIO pins. */
+
+/* Bits 17..16 : Pin sensing mechanism. */
+#define GPIO_PIN_CNF_SENSE_Pos (16UL) /*!< Position of SENSE field. */
+#define GPIO_PIN_CNF_SENSE_Msk (0x3UL << GPIO_PIN_CNF_SENSE_Pos) /*!< Bit mask of SENSE field. */
+#define GPIO_PIN_CNF_SENSE_Disabled (0x00UL) /*!< Disabled. */
+#define GPIO_PIN_CNF_SENSE_High (0x02UL) /*!< Wakeup on high level. */
+#define GPIO_PIN_CNF_SENSE_Low (0x03UL) /*!< Wakeup on low level. */
+
+/* Bits 10..8 : Drive configuration. */
+#define GPIO_PIN_CNF_DRIVE_Pos (8UL) /*!< Position of DRIVE field. */
+#define GPIO_PIN_CNF_DRIVE_Msk (0x7UL << GPIO_PIN_CNF_DRIVE_Pos) /*!< Bit mask of DRIVE field. */
+#define GPIO_PIN_CNF_DRIVE_S0S1 (0x00UL) /*!< Standard '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0S1 (0x01UL) /*!< High '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_S0H1 (0x02UL) /*!< Standard '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0H1 (0x03UL) /*!< High '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_D0S1 (0x04UL) /*!< Disconnected '0', Standard '1'. */
+#define GPIO_PIN_CNF_DRIVE_D0H1 (0x05UL) /*!< Disconnected '0', High '1'. */
+#define GPIO_PIN_CNF_DRIVE_S0D1 (0x06UL) /*!< Standard '0', Disconnected '1'. */
+#define GPIO_PIN_CNF_DRIVE_H0D1 (0x07UL) /*!< High '0', Disconnected '1'. */
+
+/* Bits 3..2 : Pull-up or -down configuration. */
+#define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */
+#define GPIO_PIN_CNF_PULL_Msk (0x3UL << GPIO_PIN_CNF_PULL_Pos) /*!< Bit mask of PULL field. */
+#define GPIO_PIN_CNF_PULL_Disabled (0x00UL) /*!< No pull. */
+#define GPIO_PIN_CNF_PULL_Pulldown (0x01UL) /*!< Pulldown on pin. */
+#define GPIO_PIN_CNF_PULL_Pullup (0x03UL) /*!< Pullup on pin. */
+
+/* Bit 1 : Connect or disconnect input path. */
+#define GPIO_PIN_CNF_INPUT_Pos (1UL) /*!< Position of INPUT field. */
+#define GPIO_PIN_CNF_INPUT_Msk (0x1UL << GPIO_PIN_CNF_INPUT_Pos) /*!< Bit mask of INPUT field. */
+#define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input pin. */
+#define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input pin. */
+
+/* Bit 0 : Pin direction. */
+#define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */
+#define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */
+#define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin. */
+#define GPIO_PIN_CNF_DIR_Output (1UL) /*!< Configure pin as an output pin. */
+
+
+/* Peripheral: GPIOTE */
+/* Description: GPIO tasks and events. */
+
+/* Register: GPIOTE_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 31 : Enable interrupt on PORT event. */
+#define GPIOTE_INTENSET_PORT_Pos (31UL) /*!< Position of PORT field. */
+#define GPIOTE_INTENSET_PORT_Msk (0x1UL << GPIOTE_INTENSET_PORT_Pos) /*!< Bit mask of PORT field. */
+#define GPIOTE_INTENSET_PORT_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_PORT_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_PORT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on IN[3] event. */
+#define GPIOTE_INTENSET_IN3_Pos (3UL) /*!< Position of IN3 field. */
+#define GPIOTE_INTENSET_IN3_Msk (0x1UL << GPIOTE_INTENSET_IN3_Pos) /*!< Bit mask of IN3 field. */
+#define GPIOTE_INTENSET_IN3_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN3_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on IN[2] event. */
+#define GPIOTE_INTENSET_IN2_Pos (2UL) /*!< Position of IN2 field. */
+#define GPIOTE_INTENSET_IN2_Msk (0x1UL << GPIOTE_INTENSET_IN2_Pos) /*!< Bit mask of IN2 field. */
+#define GPIOTE_INTENSET_IN2_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN2_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on IN[1] event. */
+#define GPIOTE_INTENSET_IN1_Pos (1UL) /*!< Position of IN1 field. */
+#define GPIOTE_INTENSET_IN1_Msk (0x1UL << GPIOTE_INTENSET_IN1_Pos) /*!< Bit mask of IN1 field. */
+#define GPIOTE_INTENSET_IN1_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN1_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on IN[0] event. */
+#define GPIOTE_INTENSET_IN0_Pos (0UL) /*!< Position of IN0 field. */
+#define GPIOTE_INTENSET_IN0_Msk (0x1UL << GPIOTE_INTENSET_IN0_Pos) /*!< Bit mask of IN0 field. */
+#define GPIOTE_INTENSET_IN0_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENSET_IN0_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENSET_IN0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: GPIOTE_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 31 : Disable interrupt on PORT event. */
+#define GPIOTE_INTENCLR_PORT_Pos (31UL) /*!< Position of PORT field. */
+#define GPIOTE_INTENCLR_PORT_Msk (0x1UL << GPIOTE_INTENCLR_PORT_Pos) /*!< Bit mask of PORT field. */
+#define GPIOTE_INTENCLR_PORT_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_PORT_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_PORT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on IN[3] event. */
+#define GPIOTE_INTENCLR_IN3_Pos (3UL) /*!< Position of IN3 field. */
+#define GPIOTE_INTENCLR_IN3_Msk (0x1UL << GPIOTE_INTENCLR_IN3_Pos) /*!< Bit mask of IN3 field. */
+#define GPIOTE_INTENCLR_IN3_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN3_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on IN[2] event. */
+#define GPIOTE_INTENCLR_IN2_Pos (2UL) /*!< Position of IN2 field. */
+#define GPIOTE_INTENCLR_IN2_Msk (0x1UL << GPIOTE_INTENCLR_IN2_Pos) /*!< Bit mask of IN2 field. */
+#define GPIOTE_INTENCLR_IN2_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN2_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on IN[1] event. */
+#define GPIOTE_INTENCLR_IN1_Pos (1UL) /*!< Position of IN1 field. */
+#define GPIOTE_INTENCLR_IN1_Msk (0x1UL << GPIOTE_INTENCLR_IN1_Pos) /*!< Bit mask of IN1 field. */
+#define GPIOTE_INTENCLR_IN1_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN1_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on IN[0] event. */
+#define GPIOTE_INTENCLR_IN0_Pos (0UL) /*!< Position of IN0 field. */
+#define GPIOTE_INTENCLR_IN0_Msk (0x1UL << GPIOTE_INTENCLR_IN0_Pos) /*!< Bit mask of IN0 field. */
+#define GPIOTE_INTENCLR_IN0_Disabled (0UL) /*!< Interrupt disabled. */
+#define GPIOTE_INTENCLR_IN0_Enabled (1UL) /*!< Interrupt enabled. */
+#define GPIOTE_INTENCLR_IN0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: GPIOTE_CONFIG */
+/* Description: Channel configuration registers. */
+
+/* Bit 20 : Initial value of the output when the GPIOTE channel is configured as a Task. */
+#define GPIOTE_CONFIG_OUTINIT_Pos (20UL) /*!< Position of OUTINIT field. */
+#define GPIOTE_CONFIG_OUTINIT_Msk (0x1UL << GPIOTE_CONFIG_OUTINIT_Pos) /*!< Bit mask of OUTINIT field. */
+#define GPIOTE_CONFIG_OUTINIT_Low (0UL) /*!< Initial low output when in task mode. */
+#define GPIOTE_CONFIG_OUTINIT_High (1UL) /*!< Initial high output when in task mode. */
+
+/* Bits 17..16 : Effects on output when in Task mode, or events on input that generates an event. */
+#define GPIOTE_CONFIG_POLARITY_Pos (16UL) /*!< Position of POLARITY field. */
+#define GPIOTE_CONFIG_POLARITY_Msk (0x3UL << GPIOTE_CONFIG_POLARITY_Pos) /*!< Bit mask of POLARITY field. */
+#define GPIOTE_CONFIG_POLARITY_None (0x00UL) /*!< No task or event. */
+#define GPIOTE_CONFIG_POLARITY_LoToHi (0x01UL) /*!< Low to high. */
+#define GPIOTE_CONFIG_POLARITY_HiToLo (0x02UL) /*!< High to low. */
+#define GPIOTE_CONFIG_POLARITY_Toggle (0x03UL) /*!< Toggle. */
+
+/* Bits 12..8 : Pin select. */
+#define GPIOTE_CONFIG_PSEL_Pos (8UL) /*!< Position of PSEL field. */
+#define GPIOTE_CONFIG_PSEL_Msk (0x1FUL << GPIOTE_CONFIG_PSEL_Pos) /*!< Bit mask of PSEL field. */
+
+/* Bits 1..0 : Mode */
+#define GPIOTE_CONFIG_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define GPIOTE_CONFIG_MODE_Msk (0x3UL << GPIOTE_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */
+#define GPIOTE_CONFIG_MODE_Disabled (0x00UL) /*!< Disabled. */
+#define GPIOTE_CONFIG_MODE_Event (0x01UL) /*!< Channel configure in event mode. */
+#define GPIOTE_CONFIG_MODE_Task (0x03UL) /*!< Channel configure in task mode. */
+
+/* Register: GPIOTE_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define GPIOTE_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define GPIOTE_POWER_POWER_Msk (0x1UL << GPIOTE_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define GPIOTE_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define GPIOTE_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: LPCOMP */
+/* Description: Low power comparator. */
+
+/* Register: LPCOMP_SHORTS */
+/* Description: Shortcuts for the LPCOMP. */
+
+/* Bit 4 : Shortcut between CROSS event and STOP task. */
+#define LPCOMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */
+#define LPCOMP_SHORTS_CROSS_STOP_Msk (0x1UL << LPCOMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */
+#define LPCOMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between UP event and STOP task. */
+#define LPCOMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */
+#define LPCOMP_SHORTS_UP_STOP_Msk (0x1UL << LPCOMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */
+#define LPCOMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between DOWN event and STOP task. */
+#define LPCOMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */
+#define LPCOMP_SHORTS_DOWN_STOP_Msk (0x1UL << LPCOMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */
+#define LPCOMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between RADY event and STOP task. */
+#define LPCOMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */
+#define LPCOMP_SHORTS_READY_STOP_Msk (0x1UL << LPCOMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */
+#define LPCOMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between READY event and SAMPLE task. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Msk (0x1UL << LPCOMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Shortcut disabled. */
+#define LPCOMP_SHORTS_READY_SAMPLE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: LPCOMP_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 3 : Enable interrupt on CROSS event. */
+#define LPCOMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */
+#define LPCOMP_INTENSET_CROSS_Msk (0x1UL << LPCOMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */
+#define LPCOMP_INTENSET_CROSS_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_CROSS_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_CROSS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on UP event. */
+#define LPCOMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */
+#define LPCOMP_INTENSET_UP_Msk (0x1UL << LPCOMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */
+#define LPCOMP_INTENSET_UP_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_UP_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_UP_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on DOWN event. */
+#define LPCOMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */
+#define LPCOMP_INTENSET_DOWN_Msk (0x1UL << LPCOMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */
+#define LPCOMP_INTENSET_DOWN_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_DOWN_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_DOWN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on READY event. */
+#define LPCOMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */
+#define LPCOMP_INTENSET_READY_Msk (0x1UL << LPCOMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define LPCOMP_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: LPCOMP_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 3 : Disable interrupt on CROSS event. */
+#define LPCOMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */
+#define LPCOMP_INTENCLR_CROSS_Msk (0x1UL << LPCOMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */
+#define LPCOMP_INTENCLR_CROSS_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_CROSS_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on UP event. */
+#define LPCOMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */
+#define LPCOMP_INTENCLR_UP_Msk (0x1UL << LPCOMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */
+#define LPCOMP_INTENCLR_UP_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_UP_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_UP_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on DOWN event. */
+#define LPCOMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */
+#define LPCOMP_INTENCLR_DOWN_Msk (0x1UL << LPCOMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */
+#define LPCOMP_INTENCLR_DOWN_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_DOWN_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on READY event. */
+#define LPCOMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */
+#define LPCOMP_INTENCLR_READY_Msk (0x1UL << LPCOMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define LPCOMP_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define LPCOMP_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define LPCOMP_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: LPCOMP_RESULT */
+/* Description: Result of last compare. */
+
+/* Bit 0 : Result of last compare. Decision point SAMPLE task. */
+#define LPCOMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */
+#define LPCOMP_RESULT_RESULT_Msk (0x1UL << LPCOMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */
+#define LPCOMP_RESULT_RESULT_Bellow (0UL) /*!< Input voltage is bellow the reference threshold. */
+#define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold. */
+
+/* Register: LPCOMP_ENABLE */
+/* Description: Enable the LPCOMP. */
+
+/* Bits 1..0 : Enable or disable LPCOMP. */
+#define LPCOMP_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define LPCOMP_ENABLE_ENABLE_Msk (0x3UL << LPCOMP_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define LPCOMP_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled LPCOMP. */
+#define LPCOMP_ENABLE_ENABLE_Enabled (0x01UL) /*!< Enable LPCOMP. */
+
+/* Register: LPCOMP_PSEL */
+/* Description: Input pin select. */
+
+/* Bits 2..0 : Analog input pin select. */
+#define LPCOMP_PSEL_PSEL_Pos (0UL) /*!< Position of PSEL field. */
+#define LPCOMP_PSEL_PSEL_Msk (0x7UL << LPCOMP_PSEL_PSEL_Pos) /*!< Bit mask of PSEL field. */
+#define LPCOMP_PSEL_PSEL_AnalogInput0 (0UL) /*!< Use analog input 0 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput1 (1UL) /*!< Use analog input 1 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput2 (2UL) /*!< Use analog input 2 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput3 (3UL) /*!< Use analog input 3 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput4 (4UL) /*!< Use analog input 4 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput5 (5UL) /*!< Use analog input 5 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput6 (6UL) /*!< Use analog input 6 as analog input. */
+#define LPCOMP_PSEL_PSEL_AnalogInput7 (7UL) /*!< Use analog input 7 as analog input. */
+
+/* Register: LPCOMP_REFSEL */
+/* Description: Reference select. */
+
+/* Bits 2..0 : Reference select. */
+#define LPCOMP_REFSEL_REFSEL_Pos (0UL) /*!< Position of REFSEL field. */
+#define LPCOMP_REFSEL_REFSEL_Msk (0x7UL << LPCOMP_REFSEL_REFSEL_Pos) /*!< Bit mask of REFSEL field. */
+#define LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling (0UL) /*!< Use supply with a 1/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling (1UL) /*!< Use supply with a 2/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling (2UL) /*!< Use supply with a 3/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling (3UL) /*!< Use supply with a 4/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling (4UL) /*!< Use supply with a 5/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling (5UL) /*!< Use supply with a 6/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling (6UL) /*!< Use supply with a 7/8 prescaler as reference. */
+#define LPCOMP_REFSEL_REFSEL_ARef (7UL) /*!< Use external analog reference as reference. */
+
+/* Register: LPCOMP_EXTREFSEL */
+/* Description: External reference select. */
+
+/* Bit 0 : External analog reference pin selection. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_Pos (0UL) /*!< Position of EXTREFSEL field. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_Msk (0x1UL << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 (0UL) /*!< Use analog reference 0 as reference. */
+#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 (1UL) /*!< Use analog reference 1 as reference. */
+
+/* Register: LPCOMP_ANADETECT */
+/* Description: Analog detect configuration. */
+
+/* Bits 1..0 : Analog detect configuration. */
+#define LPCOMP_ANADETECT_ANADETECT_Pos (0UL) /*!< Position of ANADETECT field. */
+#define LPCOMP_ANADETECT_ANADETECT_Msk (0x3UL << LPCOMP_ANADETECT_ANADETECT_Pos) /*!< Bit mask of ANADETECT field. */
+#define LPCOMP_ANADETECT_ANADETECT_Cross (0UL) /*!< Generate ANADETEC on crossing, both upwards and downwards crossing. */
+#define LPCOMP_ANADETECT_ANADETECT_Up (1UL) /*!< Generate ANADETEC on upwards crossing only. */
+#define LPCOMP_ANADETECT_ANADETECT_Down (2UL) /*!< Generate ANADETEC on downwards crossing only. */
+
+/* Register: LPCOMP_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define LPCOMP_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define LPCOMP_POWER_POWER_Msk (0x1UL << LPCOMP_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define LPCOMP_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define LPCOMP_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: MPU */
+/* Description: Memory Protection Unit. */
+
+/* Register: MPU_PERR0 */
+/* Description: Configuration of peripherals in mpu regions. */
+
+/* Bit 31 : PPI region configuration. */
+#define MPU_PERR0_PPI_Pos (31UL) /*!< Position of PPI field. */
+#define MPU_PERR0_PPI_Msk (0x1UL << MPU_PERR0_PPI_Pos) /*!< Bit mask of PPI field. */
+#define MPU_PERR0_PPI_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_PPI_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 30 : NVMC region configuration. */
+#define MPU_PERR0_NVMC_Pos (30UL) /*!< Position of NVMC field. */
+#define MPU_PERR0_NVMC_Msk (0x1UL << MPU_PERR0_NVMC_Pos) /*!< Bit mask of NVMC field. */
+#define MPU_PERR0_NVMC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_NVMC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 19 : LPCOMP region configuration. */
+#define MPU_PERR0_LPCOMP_Pos (19UL) /*!< Position of LPCOMP field. */
+#define MPU_PERR0_LPCOMP_Msk (0x1UL << MPU_PERR0_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */
+#define MPU_PERR0_LPCOMP_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_LPCOMP_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 18 : QDEC region configuration. */
+#define MPU_PERR0_QDEC_Pos (18UL) /*!< Position of QDEC field. */
+#define MPU_PERR0_QDEC_Msk (0x1UL << MPU_PERR0_QDEC_Pos) /*!< Bit mask of QDEC field. */
+#define MPU_PERR0_QDEC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_QDEC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 17 : RTC1 region configuration. */
+#define MPU_PERR0_RTC1_Pos (17UL) /*!< Position of RTC1 field. */
+#define MPU_PERR0_RTC1_Msk (0x1UL << MPU_PERR0_RTC1_Pos) /*!< Bit mask of RTC1 field. */
+#define MPU_PERR0_RTC1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RTC1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 16 : WDT region configuration. */
+#define MPU_PERR0_WDT_Pos (16UL) /*!< Position of WDT field. */
+#define MPU_PERR0_WDT_Msk (0x1UL << MPU_PERR0_WDT_Pos) /*!< Bit mask of WDT field. */
+#define MPU_PERR0_WDT_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_WDT_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 15 : CCM and AAR region configuration. */
+#define MPU_PERR0_CCM_AAR_Pos (15UL) /*!< Position of CCM_AAR field. */
+#define MPU_PERR0_CCM_AAR_Msk (0x1UL << MPU_PERR0_CCM_AAR_Pos) /*!< Bit mask of CCM_AAR field. */
+#define MPU_PERR0_CCM_AAR_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_CCM_AAR_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 14 : ECB region configuration. */
+#define MPU_PERR0_ECB_Pos (14UL) /*!< Position of ECB field. */
+#define MPU_PERR0_ECB_Msk (0x1UL << MPU_PERR0_ECB_Pos) /*!< Bit mask of ECB field. */
+#define MPU_PERR0_ECB_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_ECB_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 13 : RNG region configuration. */
+#define MPU_PERR0_RNG_Pos (13UL) /*!< Position of RNG field. */
+#define MPU_PERR0_RNG_Msk (0x1UL << MPU_PERR0_RNG_Pos) /*!< Bit mask of RNG field. */
+#define MPU_PERR0_RNG_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RNG_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 12 : TEMP region configuration. */
+#define MPU_PERR0_TEMP_Pos (12UL) /*!< Position of TEMP field. */
+#define MPU_PERR0_TEMP_Msk (0x1UL << MPU_PERR0_TEMP_Pos) /*!< Bit mask of TEMP field. */
+#define MPU_PERR0_TEMP_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TEMP_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 11 : RTC0 region configuration. */
+#define MPU_PERR0_RTC0_Pos (11UL) /*!< Position of RTC0 field. */
+#define MPU_PERR0_RTC0_Msk (0x1UL << MPU_PERR0_RTC0_Pos) /*!< Bit mask of RTC0 field. */
+#define MPU_PERR0_RTC0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RTC0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 10 : TIMER2 region configuration. */
+#define MPU_PERR0_TIMER2_Pos (10UL) /*!< Position of TIMER2 field. */
+#define MPU_PERR0_TIMER2_Msk (0x1UL << MPU_PERR0_TIMER2_Pos) /*!< Bit mask of TIMER2 field. */
+#define MPU_PERR0_TIMER2_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER2_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 9 : TIMER1 region configuration. */
+#define MPU_PERR0_TIMER1_Pos (9UL) /*!< Position of TIMER1 field. */
+#define MPU_PERR0_TIMER1_Msk (0x1UL << MPU_PERR0_TIMER1_Pos) /*!< Bit mask of TIMER1 field. */
+#define MPU_PERR0_TIMER1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 8 : TIMER0 region configuration. */
+#define MPU_PERR0_TIMER0_Pos (8UL) /*!< Position of TIMER0 field. */
+#define MPU_PERR0_TIMER0_Msk (0x1UL << MPU_PERR0_TIMER0_Pos) /*!< Bit mask of TIMER0 field. */
+#define MPU_PERR0_TIMER0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_TIMER0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 7 : ADC region configuration. */
+#define MPU_PERR0_ADC_Pos (7UL) /*!< Position of ADC field. */
+#define MPU_PERR0_ADC_Msk (0x1UL << MPU_PERR0_ADC_Pos) /*!< Bit mask of ADC field. */
+#define MPU_PERR0_ADC_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_ADC_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 6 : GPIOTE region configuration. */
+#define MPU_PERR0_GPIOTE_Pos (6UL) /*!< Position of GPIOTE field. */
+#define MPU_PERR0_GPIOTE_Msk (0x1UL << MPU_PERR0_GPIOTE_Pos) /*!< Bit mask of GPIOTE field. */
+#define MPU_PERR0_GPIOTE_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_GPIOTE_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 4 : SPI1 and TWI1 region configuration. */
+#define MPU_PERR0_SPI1_TWI1_Pos (4UL) /*!< Position of SPI1_TWI1 field. */
+#define MPU_PERR0_SPI1_TWI1_Msk (0x1UL << MPU_PERR0_SPI1_TWI1_Pos) /*!< Bit mask of SPI1_TWI1 field. */
+#define MPU_PERR0_SPI1_TWI1_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_SPI1_TWI1_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 3 : SPI0 and TWI0 region configuration. */
+#define MPU_PERR0_SPI0_TWI0_Pos (3UL) /*!< Position of SPI0_TWI0 field. */
+#define MPU_PERR0_SPI0_TWI0_Msk (0x1UL << MPU_PERR0_SPI0_TWI0_Pos) /*!< Bit mask of SPI0_TWI0 field. */
+#define MPU_PERR0_SPI0_TWI0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_SPI0_TWI0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 2 : UART0 region configuration. */
+#define MPU_PERR0_UART0_Pos (2UL) /*!< Position of UART0 field. */
+#define MPU_PERR0_UART0_Msk (0x1UL << MPU_PERR0_UART0_Pos) /*!< Bit mask of UART0 field. */
+#define MPU_PERR0_UART0_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_UART0_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 1 : RADIO region configuration. */
+#define MPU_PERR0_RADIO_Pos (1UL) /*!< Position of RADIO field. */
+#define MPU_PERR0_RADIO_Msk (0x1UL << MPU_PERR0_RADIO_Pos) /*!< Bit mask of RADIO field. */
+#define MPU_PERR0_RADIO_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_RADIO_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Bit 0 : POWER_CLOCK region configuration. */
+#define MPU_PERR0_POWER_CLOCK_Pos (0UL) /*!< Position of POWER_CLOCK field. */
+#define MPU_PERR0_POWER_CLOCK_Msk (0x1UL << MPU_PERR0_POWER_CLOCK_Pos) /*!< Bit mask of POWER_CLOCK field. */
+#define MPU_PERR0_POWER_CLOCK_InRegion1 (0UL) /*!< Peripheral configured in region 1. */
+#define MPU_PERR0_POWER_CLOCK_InRegion0 (1UL) /*!< Peripheral configured in region 0. */
+
+/* Register: MPU_PROTENSET0 */
+/* Description: Erase and write protection bit enable set register. */
+
+/* Bit 31 : Protection enable for region 31. */
+#define MPU_PROTENSET0_PROTREG31_Pos (31UL) /*!< Position of PROTREG31 field. */
+#define MPU_PROTENSET0_PROTREG31_Msk (0x1UL << MPU_PROTENSET0_PROTREG31_Pos) /*!< Bit mask of PROTREG31 field. */
+#define MPU_PROTENSET0_PROTREG31_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG31_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG31_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 30 : Protection enable for region 30. */
+#define MPU_PROTENSET0_PROTREG30_Pos (30UL) /*!< Position of PROTREG30 field. */
+#define MPU_PROTENSET0_PROTREG30_Msk (0x1UL << MPU_PROTENSET0_PROTREG30_Pos) /*!< Bit mask of PROTREG30 field. */
+#define MPU_PROTENSET0_PROTREG30_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG30_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG30_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 29 : Protection enable for region 29. */
+#define MPU_PROTENSET0_PROTREG29_Pos (29UL) /*!< Position of PROTREG29 field. */
+#define MPU_PROTENSET0_PROTREG29_Msk (0x1UL << MPU_PROTENSET0_PROTREG29_Pos) /*!< Bit mask of PROTREG29 field. */
+#define MPU_PROTENSET0_PROTREG29_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG29_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG29_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 28 : Protection enable for region 28. */
+#define MPU_PROTENSET0_PROTREG28_Pos (28UL) /*!< Position of PROTREG28 field. */
+#define MPU_PROTENSET0_PROTREG28_Msk (0x1UL << MPU_PROTENSET0_PROTREG28_Pos) /*!< Bit mask of PROTREG28 field. */
+#define MPU_PROTENSET0_PROTREG28_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG28_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG28_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 27 : Protection enable for region 27. */
+#define MPU_PROTENSET0_PROTREG27_Pos (27UL) /*!< Position of PROTREG27 field. */
+#define MPU_PROTENSET0_PROTREG27_Msk (0x1UL << MPU_PROTENSET0_PROTREG27_Pos) /*!< Bit mask of PROTREG27 field. */
+#define MPU_PROTENSET0_PROTREG27_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG27_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG27_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 26 : Protection enable for region 26. */
+#define MPU_PROTENSET0_PROTREG26_Pos (26UL) /*!< Position of PROTREG26 field. */
+#define MPU_PROTENSET0_PROTREG26_Msk (0x1UL << MPU_PROTENSET0_PROTREG26_Pos) /*!< Bit mask of PROTREG26 field. */
+#define MPU_PROTENSET0_PROTREG26_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG26_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG26_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 25 : Protection enable for region 25. */
+#define MPU_PROTENSET0_PROTREG25_Pos (25UL) /*!< Position of PROTREG25 field. */
+#define MPU_PROTENSET0_PROTREG25_Msk (0x1UL << MPU_PROTENSET0_PROTREG25_Pos) /*!< Bit mask of PROTREG25 field. */
+#define MPU_PROTENSET0_PROTREG25_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG25_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG25_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 24 : Protection enable for region 24. */
+#define MPU_PROTENSET0_PROTREG24_Pos (24UL) /*!< Position of PROTREG24 field. */
+#define MPU_PROTENSET0_PROTREG24_Msk (0x1UL << MPU_PROTENSET0_PROTREG24_Pos) /*!< Bit mask of PROTREG24 field. */
+#define MPU_PROTENSET0_PROTREG24_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG24_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG24_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 23 : Protection enable for region 23. */
+#define MPU_PROTENSET0_PROTREG23_Pos (23UL) /*!< Position of PROTREG23 field. */
+#define MPU_PROTENSET0_PROTREG23_Msk (0x1UL << MPU_PROTENSET0_PROTREG23_Pos) /*!< Bit mask of PROTREG23 field. */
+#define MPU_PROTENSET0_PROTREG23_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG23_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG23_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 22 : Protection enable for region 22. */
+#define MPU_PROTENSET0_PROTREG22_Pos (22UL) /*!< Position of PROTREG22 field. */
+#define MPU_PROTENSET0_PROTREG22_Msk (0x1UL << MPU_PROTENSET0_PROTREG22_Pos) /*!< Bit mask of PROTREG22 field. */
+#define MPU_PROTENSET0_PROTREG22_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG22_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG22_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 21 : Protection enable for region 21. */
+#define MPU_PROTENSET0_PROTREG21_Pos (21UL) /*!< Position of PROTREG21 field. */
+#define MPU_PROTENSET0_PROTREG21_Msk (0x1UL << MPU_PROTENSET0_PROTREG21_Pos) /*!< Bit mask of PROTREG21 field. */
+#define MPU_PROTENSET0_PROTREG21_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG21_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG21_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 20 : Protection enable for region 20. */
+#define MPU_PROTENSET0_PROTREG20_Pos (20UL) /*!< Position of PROTREG20 field. */
+#define MPU_PROTENSET0_PROTREG20_Msk (0x1UL << MPU_PROTENSET0_PROTREG20_Pos) /*!< Bit mask of PROTREG20 field. */
+#define MPU_PROTENSET0_PROTREG20_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG20_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG20_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 19 : Protection enable for region 19. */
+#define MPU_PROTENSET0_PROTREG19_Pos (19UL) /*!< Position of PROTREG19 field. */
+#define MPU_PROTENSET0_PROTREG19_Msk (0x1UL << MPU_PROTENSET0_PROTREG19_Pos) /*!< Bit mask of PROTREG19 field. */
+#define MPU_PROTENSET0_PROTREG19_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG19_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG19_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 18 : Protection enable for region 18. */
+#define MPU_PROTENSET0_PROTREG18_Pos (18UL) /*!< Position of PROTREG18 field. */
+#define MPU_PROTENSET0_PROTREG18_Msk (0x1UL << MPU_PROTENSET0_PROTREG18_Pos) /*!< Bit mask of PROTREG18 field. */
+#define MPU_PROTENSET0_PROTREG18_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG18_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG18_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 17 : Protection enable for region 17. */
+#define MPU_PROTENSET0_PROTREG17_Pos (17UL) /*!< Position of PROTREG17 field. */
+#define MPU_PROTENSET0_PROTREG17_Msk (0x1UL << MPU_PROTENSET0_PROTREG17_Pos) /*!< Bit mask of PROTREG17 field. */
+#define MPU_PROTENSET0_PROTREG17_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG17_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG17_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 16 : Protection enable for region 16. */
+#define MPU_PROTENSET0_PROTREG16_Pos (16UL) /*!< Position of PROTREG16 field. */
+#define MPU_PROTENSET0_PROTREG16_Msk (0x1UL << MPU_PROTENSET0_PROTREG16_Pos) /*!< Bit mask of PROTREG16 field. */
+#define MPU_PROTENSET0_PROTREG16_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG16_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG16_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 15 : Protection enable for region 15. */
+#define MPU_PROTENSET0_PROTREG15_Pos (15UL) /*!< Position of PROTREG15 field. */
+#define MPU_PROTENSET0_PROTREG15_Msk (0x1UL << MPU_PROTENSET0_PROTREG15_Pos) /*!< Bit mask of PROTREG15 field. */
+#define MPU_PROTENSET0_PROTREG15_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG15_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG15_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 14 : Protection enable for region 14. */
+#define MPU_PROTENSET0_PROTREG14_Pos (14UL) /*!< Position of PROTREG14 field. */
+#define MPU_PROTENSET0_PROTREG14_Msk (0x1UL << MPU_PROTENSET0_PROTREG14_Pos) /*!< Bit mask of PROTREG14 field. */
+#define MPU_PROTENSET0_PROTREG14_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG14_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG14_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 13 : Protection enable for region 13. */
+#define MPU_PROTENSET0_PROTREG13_Pos (13UL) /*!< Position of PROTREG13 field. */
+#define MPU_PROTENSET0_PROTREG13_Msk (0x1UL << MPU_PROTENSET0_PROTREG13_Pos) /*!< Bit mask of PROTREG13 field. */
+#define MPU_PROTENSET0_PROTREG13_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG13_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG13_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 12 : Protection enable for region 12. */
+#define MPU_PROTENSET0_PROTREG12_Pos (12UL) /*!< Position of PROTREG12 field. */
+#define MPU_PROTENSET0_PROTREG12_Msk (0x1UL << MPU_PROTENSET0_PROTREG12_Pos) /*!< Bit mask of PROTREG12 field. */
+#define MPU_PROTENSET0_PROTREG12_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG12_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG12_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 11 : Protection enable for region 11. */
+#define MPU_PROTENSET0_PROTREG11_Pos (11UL) /*!< Position of PROTREG11 field. */
+#define MPU_PROTENSET0_PROTREG11_Msk (0x1UL << MPU_PROTENSET0_PROTREG11_Pos) /*!< Bit mask of PROTREG11 field. */
+#define MPU_PROTENSET0_PROTREG11_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG11_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG11_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 10 : Protection enable for region 10. */
+#define MPU_PROTENSET0_PROTREG10_Pos (10UL) /*!< Position of PROTREG10 field. */
+#define MPU_PROTENSET0_PROTREG10_Msk (0x1UL << MPU_PROTENSET0_PROTREG10_Pos) /*!< Bit mask of PROTREG10 field. */
+#define MPU_PROTENSET0_PROTREG10_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG10_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG10_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 9 : Protection enable for region 9. */
+#define MPU_PROTENSET0_PROTREG9_Pos (9UL) /*!< Position of PROTREG9 field. */
+#define MPU_PROTENSET0_PROTREG9_Msk (0x1UL << MPU_PROTENSET0_PROTREG9_Pos) /*!< Bit mask of PROTREG9 field. */
+#define MPU_PROTENSET0_PROTREG9_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG9_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG9_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 8 : Protection enable for region 8. */
+#define MPU_PROTENSET0_PROTREG8_Pos (8UL) /*!< Position of PROTREG8 field. */
+#define MPU_PROTENSET0_PROTREG8_Msk (0x1UL << MPU_PROTENSET0_PROTREG8_Pos) /*!< Bit mask of PROTREG8 field. */
+#define MPU_PROTENSET0_PROTREG8_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG8_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG8_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 7 : Protection enable for region 7. */
+#define MPU_PROTENSET0_PROTREG7_Pos (7UL) /*!< Position of PROTREG7 field. */
+#define MPU_PROTENSET0_PROTREG7_Msk (0x1UL << MPU_PROTENSET0_PROTREG7_Pos) /*!< Bit mask of PROTREG7 field. */
+#define MPU_PROTENSET0_PROTREG7_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG7_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG7_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 6 : Protection enable for region 6. */
+#define MPU_PROTENSET0_PROTREG6_Pos (6UL) /*!< Position of PROTREG6 field. */
+#define MPU_PROTENSET0_PROTREG6_Msk (0x1UL << MPU_PROTENSET0_PROTREG6_Pos) /*!< Bit mask of PROTREG6 field. */
+#define MPU_PROTENSET0_PROTREG6_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG6_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG6_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 5 : Protection enable for region 5. */
+#define MPU_PROTENSET0_PROTREG5_Pos (5UL) /*!< Position of PROTREG5 field. */
+#define MPU_PROTENSET0_PROTREG5_Msk (0x1UL << MPU_PROTENSET0_PROTREG5_Pos) /*!< Bit mask of PROTREG5 field. */
+#define MPU_PROTENSET0_PROTREG5_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG5_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG5_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 4 : Protection enable for region 4. */
+#define MPU_PROTENSET0_PROTREG4_Pos (4UL) /*!< Position of PROTREG4 field. */
+#define MPU_PROTENSET0_PROTREG4_Msk (0x1UL << MPU_PROTENSET0_PROTREG4_Pos) /*!< Bit mask of PROTREG4 field. */
+#define MPU_PROTENSET0_PROTREG4_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG4_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG4_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 3 : Protection enable for region 3. */
+#define MPU_PROTENSET0_PROTREG3_Pos (3UL) /*!< Position of PROTREG3 field. */
+#define MPU_PROTENSET0_PROTREG3_Msk (0x1UL << MPU_PROTENSET0_PROTREG3_Pos) /*!< Bit mask of PROTREG3 field. */
+#define MPU_PROTENSET0_PROTREG3_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG3_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG3_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 2 : Protection enable for region 2. */
+#define MPU_PROTENSET0_PROTREG2_Pos (2UL) /*!< Position of PROTREG2 field. */
+#define MPU_PROTENSET0_PROTREG2_Msk (0x1UL << MPU_PROTENSET0_PROTREG2_Pos) /*!< Bit mask of PROTREG2 field. */
+#define MPU_PROTENSET0_PROTREG2_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG2_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG2_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 1 : Protection enable for region 1. */
+#define MPU_PROTENSET0_PROTREG1_Pos (1UL) /*!< Position of PROTREG1 field. */
+#define MPU_PROTENSET0_PROTREG1_Msk (0x1UL << MPU_PROTENSET0_PROTREG1_Pos) /*!< Bit mask of PROTREG1 field. */
+#define MPU_PROTENSET0_PROTREG1_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG1_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG1_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 0 : Protection enable for region 0. */
+#define MPU_PROTENSET0_PROTREG0_Pos (0UL) /*!< Position of PROTREG0 field. */
+#define MPU_PROTENSET0_PROTREG0_Msk (0x1UL << MPU_PROTENSET0_PROTREG0_Pos) /*!< Bit mask of PROTREG0 field. */
+#define MPU_PROTENSET0_PROTREG0_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET0_PROTREG0_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET0_PROTREG0_Set (1UL) /*!< Enable protection on write. */
+
+/* Register: MPU_PROTENSET1 */
+/* Description: Erase and write protection bit enable set register. */
+
+/* Bit 31 : Protection enable for region 63. */
+#define MPU_PROTENSET1_PROTREG63_Pos (31UL) /*!< Position of PROTREG63 field. */
+#define MPU_PROTENSET1_PROTREG63_Msk (0x1UL << MPU_PROTENSET1_PROTREG63_Pos) /*!< Bit mask of PROTREG63 field. */
+#define MPU_PROTENSET1_PROTREG63_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG63_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG63_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 30 : Protection enable for region 62. */
+#define MPU_PROTENSET1_PROTREG62_Pos (30UL) /*!< Position of PROTREG62 field. */
+#define MPU_PROTENSET1_PROTREG62_Msk (0x1UL << MPU_PROTENSET1_PROTREG62_Pos) /*!< Bit mask of PROTREG62 field. */
+#define MPU_PROTENSET1_PROTREG62_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG62_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG62_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 29 : Protection enable for region 61. */
+#define MPU_PROTENSET1_PROTREG61_Pos (29UL) /*!< Position of PROTREG61 field. */
+#define MPU_PROTENSET1_PROTREG61_Msk (0x1UL << MPU_PROTENSET1_PROTREG61_Pos) /*!< Bit mask of PROTREG61 field. */
+#define MPU_PROTENSET1_PROTREG61_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG61_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG61_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 28 : Protection enable for region 60. */
+#define MPU_PROTENSET1_PROTREG60_Pos (28UL) /*!< Position of PROTREG60 field. */
+#define MPU_PROTENSET1_PROTREG60_Msk (0x1UL << MPU_PROTENSET1_PROTREG60_Pos) /*!< Bit mask of PROTREG60 field. */
+#define MPU_PROTENSET1_PROTREG60_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG60_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG60_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 27 : Protection enable for region 59. */
+#define MPU_PROTENSET1_PROTREG59_Pos (27UL) /*!< Position of PROTREG59 field. */
+#define MPU_PROTENSET1_PROTREG59_Msk (0x1UL << MPU_PROTENSET1_PROTREG59_Pos) /*!< Bit mask of PROTREG59 field. */
+#define MPU_PROTENSET1_PROTREG59_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG59_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG59_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 26 : Protection enable for region 58. */
+#define MPU_PROTENSET1_PROTREG58_Pos (26UL) /*!< Position of PROTREG58 field. */
+#define MPU_PROTENSET1_PROTREG58_Msk (0x1UL << MPU_PROTENSET1_PROTREG58_Pos) /*!< Bit mask of PROTREG58 field. */
+#define MPU_PROTENSET1_PROTREG58_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG58_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG58_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 25 : Protection enable for region 57. */
+#define MPU_PROTENSET1_PROTREG57_Pos (25UL) /*!< Position of PROTREG57 field. */
+#define MPU_PROTENSET1_PROTREG57_Msk (0x1UL << MPU_PROTENSET1_PROTREG57_Pos) /*!< Bit mask of PROTREG57 field. */
+#define MPU_PROTENSET1_PROTREG57_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG57_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG57_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 24 : Protection enable for region 56. */
+#define MPU_PROTENSET1_PROTREG56_Pos (24UL) /*!< Position of PROTREG56 field. */
+#define MPU_PROTENSET1_PROTREG56_Msk (0x1UL << MPU_PROTENSET1_PROTREG56_Pos) /*!< Bit mask of PROTREG56 field. */
+#define MPU_PROTENSET1_PROTREG56_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG56_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG56_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 23 : Protection enable for region 55. */
+#define MPU_PROTENSET1_PROTREG55_Pos (23UL) /*!< Position of PROTREG55 field. */
+#define MPU_PROTENSET1_PROTREG55_Msk (0x1UL << MPU_PROTENSET1_PROTREG55_Pos) /*!< Bit mask of PROTREG55 field. */
+#define MPU_PROTENSET1_PROTREG55_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG55_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG55_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 22 : Protection enable for region 54. */
+#define MPU_PROTENSET1_PROTREG54_Pos (22UL) /*!< Position of PROTREG54 field. */
+#define MPU_PROTENSET1_PROTREG54_Msk (0x1UL << MPU_PROTENSET1_PROTREG54_Pos) /*!< Bit mask of PROTREG54 field. */
+#define MPU_PROTENSET1_PROTREG54_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG54_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG54_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 21 : Protection enable for region 53. */
+#define MPU_PROTENSET1_PROTREG53_Pos (21UL) /*!< Position of PROTREG53 field. */
+#define MPU_PROTENSET1_PROTREG53_Msk (0x1UL << MPU_PROTENSET1_PROTREG53_Pos) /*!< Bit mask of PROTREG53 field. */
+#define MPU_PROTENSET1_PROTREG53_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG53_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG53_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 20 : Protection enable for region 52. */
+#define MPU_PROTENSET1_PROTREG52_Pos (20UL) /*!< Position of PROTREG52 field. */
+#define MPU_PROTENSET1_PROTREG52_Msk (0x1UL << MPU_PROTENSET1_PROTREG52_Pos) /*!< Bit mask of PROTREG52 field. */
+#define MPU_PROTENSET1_PROTREG52_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG52_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG52_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 19 : Protection enable for region 51. */
+#define MPU_PROTENSET1_PROTREG51_Pos (19UL) /*!< Position of PROTREG51 field. */
+#define MPU_PROTENSET1_PROTREG51_Msk (0x1UL << MPU_PROTENSET1_PROTREG51_Pos) /*!< Bit mask of PROTREG51 field. */
+#define MPU_PROTENSET1_PROTREG51_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG51_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG51_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 18 : Protection enable for region 50. */
+#define MPU_PROTENSET1_PROTREG50_Pos (18UL) /*!< Position of PROTREG50 field. */
+#define MPU_PROTENSET1_PROTREG50_Msk (0x1UL << MPU_PROTENSET1_PROTREG50_Pos) /*!< Bit mask of PROTREG50 field. */
+#define MPU_PROTENSET1_PROTREG50_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG50_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG50_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 17 : Protection enable for region 49. */
+#define MPU_PROTENSET1_PROTREG49_Pos (17UL) /*!< Position of PROTREG49 field. */
+#define MPU_PROTENSET1_PROTREG49_Msk (0x1UL << MPU_PROTENSET1_PROTREG49_Pos) /*!< Bit mask of PROTREG49 field. */
+#define MPU_PROTENSET1_PROTREG49_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG49_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG49_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 16 : Protection enable for region 48. */
+#define MPU_PROTENSET1_PROTREG48_Pos (16UL) /*!< Position of PROTREG48 field. */
+#define MPU_PROTENSET1_PROTREG48_Msk (0x1UL << MPU_PROTENSET1_PROTREG48_Pos) /*!< Bit mask of PROTREG48 field. */
+#define MPU_PROTENSET1_PROTREG48_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG48_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG48_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 15 : Protection enable for region 47. */
+#define MPU_PROTENSET1_PROTREG47_Pos (15UL) /*!< Position of PROTREG47 field. */
+#define MPU_PROTENSET1_PROTREG47_Msk (0x1UL << MPU_PROTENSET1_PROTREG47_Pos) /*!< Bit mask of PROTREG47 field. */
+#define MPU_PROTENSET1_PROTREG47_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG47_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG47_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 14 : Protection enable for region 46. */
+#define MPU_PROTENSET1_PROTREG46_Pos (14UL) /*!< Position of PROTREG46 field. */
+#define MPU_PROTENSET1_PROTREG46_Msk (0x1UL << MPU_PROTENSET1_PROTREG46_Pos) /*!< Bit mask of PROTREG46 field. */
+#define MPU_PROTENSET1_PROTREG46_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG46_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG46_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 13 : Protection enable for region 45. */
+#define MPU_PROTENSET1_PROTREG45_Pos (13UL) /*!< Position of PROTREG45 field. */
+#define MPU_PROTENSET1_PROTREG45_Msk (0x1UL << MPU_PROTENSET1_PROTREG45_Pos) /*!< Bit mask of PROTREG45 field. */
+#define MPU_PROTENSET1_PROTREG45_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG45_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG45_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 12 : Protection enable for region 44. */
+#define MPU_PROTENSET1_PROTREG44_Pos (12UL) /*!< Position of PROTREG44 field. */
+#define MPU_PROTENSET1_PROTREG44_Msk (0x1UL << MPU_PROTENSET1_PROTREG44_Pos) /*!< Bit mask of PROTREG44 field. */
+#define MPU_PROTENSET1_PROTREG44_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG44_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG44_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 11 : Protection enable for region 43. */
+#define MPU_PROTENSET1_PROTREG43_Pos (11UL) /*!< Position of PROTREG43 field. */
+#define MPU_PROTENSET1_PROTREG43_Msk (0x1UL << MPU_PROTENSET1_PROTREG43_Pos) /*!< Bit mask of PROTREG43 field. */
+#define MPU_PROTENSET1_PROTREG43_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG43_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG43_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 10 : Protection enable for region 42. */
+#define MPU_PROTENSET1_PROTREG42_Pos (10UL) /*!< Position of PROTREG42 field. */
+#define MPU_PROTENSET1_PROTREG42_Msk (0x1UL << MPU_PROTENSET1_PROTREG42_Pos) /*!< Bit mask of PROTREG42 field. */
+#define MPU_PROTENSET1_PROTREG42_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG42_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG42_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 9 : Protection enable for region 41. */
+#define MPU_PROTENSET1_PROTREG41_Pos (9UL) /*!< Position of PROTREG41 field. */
+#define MPU_PROTENSET1_PROTREG41_Msk (0x1UL << MPU_PROTENSET1_PROTREG41_Pos) /*!< Bit mask of PROTREG41 field. */
+#define MPU_PROTENSET1_PROTREG41_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG41_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG41_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 8 : Protection enable for region 40. */
+#define MPU_PROTENSET1_PROTREG40_Pos (8UL) /*!< Position of PROTREG40 field. */
+#define MPU_PROTENSET1_PROTREG40_Msk (0x1UL << MPU_PROTENSET1_PROTREG40_Pos) /*!< Bit mask of PROTREG40 field. */
+#define MPU_PROTENSET1_PROTREG40_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG40_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG40_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 7 : Protection enable for region 39. */
+#define MPU_PROTENSET1_PROTREG39_Pos (7UL) /*!< Position of PROTREG39 field. */
+#define MPU_PROTENSET1_PROTREG39_Msk (0x1UL << MPU_PROTENSET1_PROTREG39_Pos) /*!< Bit mask of PROTREG39 field. */
+#define MPU_PROTENSET1_PROTREG39_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG39_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG39_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 6 : Protection enable for region 38. */
+#define MPU_PROTENSET1_PROTREG38_Pos (6UL) /*!< Position of PROTREG38 field. */
+#define MPU_PROTENSET1_PROTREG38_Msk (0x1UL << MPU_PROTENSET1_PROTREG38_Pos) /*!< Bit mask of PROTREG38 field. */
+#define MPU_PROTENSET1_PROTREG38_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG38_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG38_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 5 : Protection enable for region 37. */
+#define MPU_PROTENSET1_PROTREG37_Pos (5UL) /*!< Position of PROTREG37 field. */
+#define MPU_PROTENSET1_PROTREG37_Msk (0x1UL << MPU_PROTENSET1_PROTREG37_Pos) /*!< Bit mask of PROTREG37 field. */
+#define MPU_PROTENSET1_PROTREG37_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG37_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG37_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 4 : Protection enable for region 36. */
+#define MPU_PROTENSET1_PROTREG36_Pos (4UL) /*!< Position of PROTREG36 field. */
+#define MPU_PROTENSET1_PROTREG36_Msk (0x1UL << MPU_PROTENSET1_PROTREG36_Pos) /*!< Bit mask of PROTREG36 field. */
+#define MPU_PROTENSET1_PROTREG36_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG36_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG36_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 3 : Protection enable for region 35. */
+#define MPU_PROTENSET1_PROTREG35_Pos (3UL) /*!< Position of PROTREG35 field. */
+#define MPU_PROTENSET1_PROTREG35_Msk (0x1UL << MPU_PROTENSET1_PROTREG35_Pos) /*!< Bit mask of PROTREG35 field. */
+#define MPU_PROTENSET1_PROTREG35_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG35_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG35_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 2 : Protection enable for region 34. */
+#define MPU_PROTENSET1_PROTREG34_Pos (2UL) /*!< Position of PROTREG34 field. */
+#define MPU_PROTENSET1_PROTREG34_Msk (0x1UL << MPU_PROTENSET1_PROTREG34_Pos) /*!< Bit mask of PROTREG34 field. */
+#define MPU_PROTENSET1_PROTREG34_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG34_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG34_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 1 : Protection enable for region 33. */
+#define MPU_PROTENSET1_PROTREG33_Pos (1UL) /*!< Position of PROTREG33 field. */
+#define MPU_PROTENSET1_PROTREG33_Msk (0x1UL << MPU_PROTENSET1_PROTREG33_Pos) /*!< Bit mask of PROTREG33 field. */
+#define MPU_PROTENSET1_PROTREG33_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG33_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG33_Set (1UL) /*!< Enable protection on write. */
+
+/* Bit 0 : Protection enable for region 32. */
+#define MPU_PROTENSET1_PROTREG32_Pos (0UL) /*!< Position of PROTREG32 field. */
+#define MPU_PROTENSET1_PROTREG32_Msk (0x1UL << MPU_PROTENSET1_PROTREG32_Pos) /*!< Bit mask of PROTREG32 field. */
+#define MPU_PROTENSET1_PROTREG32_Disabled (0UL) /*!< Protection disabled. */
+#define MPU_PROTENSET1_PROTREG32_Enabled (1UL) /*!< Protection enabled. */
+#define MPU_PROTENSET1_PROTREG32_Set (1UL) /*!< Enable protection on write. */
+
+/* Register: MPU_DISABLEINDEBUG */
+/* Description: Disable erase and write protection mechanism in debug mode. */
+
+/* Bit 0 : Disable protection mechanism in debug mode. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos (0UL) /*!< Position of DISABLEINDEBUG field. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Msk (0x1UL << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos) /*!< Bit mask of DISABLEINDEBUG field. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Enabled (0UL) /*!< Protection enabled. */
+#define MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled (1UL) /*!< Protection disabled. */
+
+/* Register: MPU_PROTBLOCKSIZE */
+/* Description: Erase and write protection block size. */
+
+/* Bits 1..0 : Erase and write protection block size. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Pos (0UL) /*!< Position of PROTBLOCKSIZE field. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Msk (0x3UL << MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_Pos) /*!< Bit mask of PROTBLOCKSIZE field. */
+#define MPU_PROTBLOCKSIZE_PROTBLOCKSIZE_4k (0UL) /*!< Erase and write protection block size is 4k. */
+
+
+/* Peripheral: NVMC */
+/* Description: Non Volatile Memory Controller. */
+
+/* Register: NVMC_READY */
+/* Description: Ready flag. */
+
+/* Bit 0 : NVMC ready. */
+#define NVMC_READY_READY_Pos (0UL) /*!< Position of READY field. */
+#define NVMC_READY_READY_Msk (0x1UL << NVMC_READY_READY_Pos) /*!< Bit mask of READY field. */
+#define NVMC_READY_READY_Busy (0UL) /*!< NVMC is busy (on-going write or erase operation). */
+#define NVMC_READY_READY_Ready (1UL) /*!< NVMC is ready. */
+
+/* Register: NVMC_CONFIG */
+/* Description: Configuration register. */
+
+/* Bits 1..0 : Program write enable. */
+#define NVMC_CONFIG_WEN_Pos (0UL) /*!< Position of WEN field. */
+#define NVMC_CONFIG_WEN_Msk (0x3UL << NVMC_CONFIG_WEN_Pos) /*!< Bit mask of WEN field. */
+#define NVMC_CONFIG_WEN_Ren (0x00UL) /*!< Read only access. */
+#define NVMC_CONFIG_WEN_Wen (0x01UL) /*!< Write enabled. */
+#define NVMC_CONFIG_WEN_Een (0x02UL) /*!< Erase enabled. */
+
+/* Register: NVMC_ERASEALL */
+/* Description: Register for erasing all non-volatile user memory. */
+
+/* Bit 0 : Starts the erasing of all user NVM (code region 0/1 and UICR registers). */
+#define NVMC_ERASEALL_ERASEALL_Pos (0UL) /*!< Position of ERASEALL field. */
+#define NVMC_ERASEALL_ERASEALL_Msk (0x1UL << NVMC_ERASEALL_ERASEALL_Pos) /*!< Bit mask of ERASEALL field. */
+#define NVMC_ERASEALL_ERASEALL_NoOperation (0UL) /*!< No operation. */
+#define NVMC_ERASEALL_ERASEALL_Erase (1UL) /*!< Start chip erase. */
+
+/* Register: NVMC_ERASEUICR */
+/* Description: Register for start erasing User Information Congfiguration Registers. */
+
+/* Bit 0 : It can only be used when all contents of code region 1 are erased. */
+#define NVMC_ERASEUICR_ERASEUICR_Pos (0UL) /*!< Position of ERASEUICR field. */
+#define NVMC_ERASEUICR_ERASEUICR_Msk (0x1UL << NVMC_ERASEUICR_ERASEUICR_Pos) /*!< Bit mask of ERASEUICR field. */
+#define NVMC_ERASEUICR_ERASEUICR_NoOperation (0UL) /*!< No operation. */
+#define NVMC_ERASEUICR_ERASEUICR_Erase (1UL) /*!< Start UICR erase. */
+
+
+/* Peripheral: POWER */
+/* Description: Power Control. */
+
+/* Register: POWER_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on POFWARN event. */
+#define POWER_INTENSET_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */
+#define POWER_INTENSET_POFWARN_Msk (0x1UL << POWER_INTENSET_POFWARN_Pos) /*!< Bit mask of POFWARN field. */
+#define POWER_INTENSET_POFWARN_Disabled (0UL) /*!< Interrupt disabled. */
+#define POWER_INTENSET_POFWARN_Enabled (1UL) /*!< Interrupt enabled. */
+#define POWER_INTENSET_POFWARN_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: POWER_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on POFWARN event. */
+#define POWER_INTENCLR_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */
+#define POWER_INTENCLR_POFWARN_Msk (0x1UL << POWER_INTENCLR_POFWARN_Pos) /*!< Bit mask of POFWARN field. */
+#define POWER_INTENCLR_POFWARN_Disabled (0UL) /*!< Interrupt disabled. */
+#define POWER_INTENCLR_POFWARN_Enabled (1UL) /*!< Interrupt enabled. */
+#define POWER_INTENCLR_POFWARN_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: POWER_RESETREAS */
+/* Description: Reset reason. */
+
+/* Bit 18 : Reset from wake-up from OFF mode detected by entering into debug interface mode. */
+#define POWER_RESETREAS_DIF_Pos (18UL) /*!< Position of DIF field. */
+#define POWER_RESETREAS_DIF_Msk (0x1UL << POWER_RESETREAS_DIF_Pos) /*!< Bit mask of DIF field. */
+#define POWER_RESETREAS_DIF_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_DIF_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 17 : Reset from wake-up from OFF mode detected by the use of ANADETECT signal from LPCOMP. */
+#define POWER_RESETREAS_LPCOMP_Pos (17UL) /*!< Position of LPCOMP field. */
+#define POWER_RESETREAS_LPCOMP_Msk (0x1UL << POWER_RESETREAS_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */
+#define POWER_RESETREAS_LPCOMP_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_LPCOMP_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 16 : Reset from wake-up from OFF mode detected by the use of DETECT signal from GPIO. */
+#define POWER_RESETREAS_OFF_Pos (16UL) /*!< Position of OFF field. */
+#define POWER_RESETREAS_OFF_Msk (0x1UL << POWER_RESETREAS_OFF_Pos) /*!< Bit mask of OFF field. */
+#define POWER_RESETREAS_OFF_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_OFF_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 3 : Reset from CPU lock-up detected. */
+#define POWER_RESETREAS_LOCKUP_Pos (3UL) /*!< Position of LOCKUP field. */
+#define POWER_RESETREAS_LOCKUP_Msk (0x1UL << POWER_RESETREAS_LOCKUP_Pos) /*!< Bit mask of LOCKUP field. */
+#define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 2 : Reset from AIRCR.SYSRESETREQ detected. */
+#define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */
+#define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */
+#define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_SREQ_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 1 : Reset from watchdog detected. */
+#define POWER_RESETREAS_DOG_Pos (1UL) /*!< Position of DOG field. */
+#define POWER_RESETREAS_DOG_Msk (0x1UL << POWER_RESETREAS_DOG_Pos) /*!< Bit mask of DOG field. */
+#define POWER_RESETREAS_DOG_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_DOG_Detected (1UL) /*!< Reset detected. */
+
+/* Bit 0 : Reset from pin-reset detected. */
+#define POWER_RESETREAS_RESETPIN_Pos (0UL) /*!< Position of RESETPIN field. */
+#define POWER_RESETREAS_RESETPIN_Msk (0x1UL << POWER_RESETREAS_RESETPIN_Pos) /*!< Bit mask of RESETPIN field. */
+#define POWER_RESETREAS_RESETPIN_NotDetected (0UL) /*!< Reset not detected. */
+#define POWER_RESETREAS_RESETPIN_Detected (1UL) /*!< Reset detected. */
+
+/* Register: POWER_RAMSTATUS */
+/* Description: Ram status register. */
+
+/* Bit 3 : RAM block 3 status. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Pos (3UL) /*!< Position of RAMBLOCK3 field. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK3_Pos) /*!< Bit mask of RAMBLOCK3 field. */
+#define POWER_RAMSTATUS_RAMBLOCK3_Off (0UL) /*!< RAM block 3 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK3_On (1UL) /*!< RAM block 3 is on. */
+
+/* Bit 2 : RAM block 2 status. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Pos (2UL) /*!< Position of RAMBLOCK2 field. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK2_Pos) /*!< Bit mask of RAMBLOCK2 field. */
+#define POWER_RAMSTATUS_RAMBLOCK2_Off (0UL) /*!< RAM block 2 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK2_On (1UL) /*!< RAM block 2 is on. */
+
+/* Bit 1 : RAM block 1 status. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Pos (1UL) /*!< Position of RAMBLOCK1 field. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK1_Pos) /*!< Bit mask of RAMBLOCK1 field. */
+#define POWER_RAMSTATUS_RAMBLOCK1_Off (0UL) /*!< RAM block 1 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK1_On (1UL) /*!< RAM block 1 is on. */
+
+/* Bit 0 : RAM block 0 status. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Pos (0UL) /*!< Position of RAMBLOCK0 field. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK0_Pos) /*!< Bit mask of RAMBLOCK0 field. */
+#define POWER_RAMSTATUS_RAMBLOCK0_Off (0UL) /*!< RAM block 0 is off or powering up. */
+#define POWER_RAMSTATUS_RAMBLOCK0_On (1UL) /*!< RAM block 0 is on. */
+
+/* Register: POWER_SYSTEMOFF */
+/* Description: System off register. */
+
+/* Bit 0 : Enter system off mode. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Pos (0UL) /*!< Position of SYSTEMOFF field. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Msk (0x1UL << POWER_SYSTEMOFF_SYSTEMOFF_Pos) /*!< Bit mask of SYSTEMOFF field. */
+#define POWER_SYSTEMOFF_SYSTEMOFF_Enter (1UL) /*!< Enter system off mode. */
+
+/* Register: POWER_POFCON */
+/* Description: Power failure configuration. */
+
+/* Bits 2..1 : Set threshold level. */
+#define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */
+#define POWER_POFCON_THRESHOLD_Msk (0x3UL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */
+#define POWER_POFCON_THRESHOLD_V21 (0x00UL) /*!< Set threshold to 2.1Volts. */
+#define POWER_POFCON_THRESHOLD_V23 (0x01UL) /*!< Set threshold to 2.3Volts. */
+#define POWER_POFCON_THRESHOLD_V25 (0x02UL) /*!< Set threshold to 2.5Volts. */
+#define POWER_POFCON_THRESHOLD_V27 (0x03UL) /*!< Set threshold to 2.7Volts. */
+
+/* Bit 0 : Power failure comparator enable. */
+#define POWER_POFCON_POF_Pos (0UL) /*!< Position of POF field. */
+#define POWER_POFCON_POF_Msk (0x1UL << POWER_POFCON_POF_Pos) /*!< Bit mask of POF field. */
+#define POWER_POFCON_POF_Disabled (0UL) /*!< Disabled. */
+#define POWER_POFCON_POF_Enabled (1UL) /*!< Enabled. */
+
+/* Register: POWER_GPREGRET */
+/* Description: General purpose retention register. This register is a retained register. */
+
+/* Bits 7..0 : General purpose retention register. */
+#define POWER_GPREGRET_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */
+#define POWER_GPREGRET_GPREGRET_Msk (0xFFUL << POWER_GPREGRET_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */
+
+/* Register: POWER_RAMON */
+/* Description: Ram on/off. */
+
+/* Bit 17 : RAM block 1 behaviour in OFF mode. */
+#define POWER_RAMON_OFFRAM1_Pos (17UL) /*!< Position of OFFRAM1 field. */
+#define POWER_RAMON_OFFRAM1_Msk (0x1UL << POWER_RAMON_OFFRAM1_Pos) /*!< Bit mask of OFFRAM1 field. */
+#define POWER_RAMON_OFFRAM1_RAM1Off (0UL) /*!< RAM block 1 OFF in OFF mode. */
+#define POWER_RAMON_OFFRAM1_RAM1On (1UL) /*!< RAM block 1 ON in OFF mode. */
+
+/* Bit 16 : RAM block 0 behaviour in OFF mode. */
+#define POWER_RAMON_OFFRAM0_Pos (16UL) /*!< Position of OFFRAM0 field. */
+#define POWER_RAMON_OFFRAM0_Msk (0x1UL << POWER_RAMON_OFFRAM0_Pos) /*!< Bit mask of OFFRAM0 field. */
+#define POWER_RAMON_OFFRAM0_RAM0Off (0UL) /*!< RAM block 0 OFF in OFF mode. */
+#define POWER_RAMON_OFFRAM0_RAM0On (1UL) /*!< RAM block 0 ON in OFF mode. */
+
+/* Bit 1 : RAM block 1 behaviour in ON mode. */
+#define POWER_RAMON_ONRAM1_Pos (1UL) /*!< Position of ONRAM1 field. */
+#define POWER_RAMON_ONRAM1_Msk (0x1UL << POWER_RAMON_ONRAM1_Pos) /*!< Bit mask of ONRAM1 field. */
+#define POWER_RAMON_ONRAM1_RAM1Off (0UL) /*!< RAM block 1 OFF in ON mode. */
+#define POWER_RAMON_ONRAM1_RAM1On (1UL) /*!< RAM block 1 ON in ON mode. */
+
+/* Bit 0 : RAM block 0 behaviour in ON mode. */
+#define POWER_RAMON_ONRAM0_Pos (0UL) /*!< Position of ONRAM0 field. */
+#define POWER_RAMON_ONRAM0_Msk (0x1UL << POWER_RAMON_ONRAM0_Pos) /*!< Bit mask of ONRAM0 field. */
+#define POWER_RAMON_ONRAM0_RAM0Off (0UL) /*!< RAM block 0 OFF in ON mode. */
+#define POWER_RAMON_ONRAM0_RAM0On (1UL) /*!< RAM block 0 ON in ON mode. */
+
+/* Register: POWER_RESET */
+/* Description: Pin reset functionality configuration register. This register is a retained register. */
+
+/* Bit 0 : Enable or disable pin reset in debug interface mode. */
+#define POWER_RESET_RESET_Pos (0UL) /*!< Position of RESET field. */
+#define POWER_RESET_RESET_Msk (0x1UL << POWER_RESET_RESET_Pos) /*!< Bit mask of RESET field. */
+#define POWER_RESET_RESET_Disabled (0UL) /*!< Pin reset in debug interface mode disabled. */
+#define POWER_RESET_RESET_Enabled (1UL) /*!< Pin reset in debug interface mode enabled. */
+
+/* Register: POWER_RAMONB */
+/* Description: Ram on/off. */
+
+/* Bit 17 : RAM block 3 behaviour in OFF mode. */
+#define POWER_RAMONB_OFFRAM3_Pos (17UL) /*!< Position of OFFRAM3 field. */
+#define POWER_RAMONB_OFFRAM3_Msk (0x1UL << POWER_RAMONB_OFFRAM3_Pos) /*!< Bit mask of OFFRAM3 field. */
+#define POWER_RAMONB_OFFRAM3_RAM3Off (0UL) /*!< RAM block 3 OFF in OFF mode. */
+#define POWER_RAMONB_OFFRAM3_RAM3On (1UL) /*!< RAM block 3 ON in OFF mode. */
+
+/* Bit 16 : RAM block 2 behaviour in OFF mode. */
+#define POWER_RAMONB_OFFRAM2_Pos (16UL) /*!< Position of OFFRAM2 field. */
+#define POWER_RAMONB_OFFRAM2_Msk (0x1UL << POWER_RAMONB_OFFRAM2_Pos) /*!< Bit mask of OFFRAM2 field. */
+#define POWER_RAMONB_OFFRAM2_RAM2Off (0UL) /*!< RAM block 2 OFF in OFF mode. */
+#define POWER_RAMONB_OFFRAM2_RAM2On (1UL) /*!< RAM block 2 ON in OFF mode. */
+
+/* Bit 1 : RAM block 3 behaviour in ON mode. */
+#define POWER_RAMONB_ONRAM3_Pos (1UL) /*!< Position of ONRAM3 field. */
+#define POWER_RAMONB_ONRAM3_Msk (0x1UL << POWER_RAMONB_ONRAM3_Pos) /*!< Bit mask of ONRAM3 field. */
+#define POWER_RAMONB_ONRAM3_RAM3Off (0UL) /*!< RAM block 33 OFF in ON mode. */
+#define POWER_RAMONB_ONRAM3_RAM3On (1UL) /*!< RAM block 3 ON in ON mode. */
+
+/* Bit 0 : RAM block 2 behaviour in ON mode. */
+#define POWER_RAMONB_ONRAM2_Pos (0UL) /*!< Position of ONRAM2 field. */
+#define POWER_RAMONB_ONRAM2_Msk (0x1UL << POWER_RAMONB_ONRAM2_Pos) /*!< Bit mask of ONRAM2 field. */
+#define POWER_RAMONB_ONRAM2_RAM2Off (0UL) /*!< RAM block 2 OFF in ON mode. */
+#define POWER_RAMONB_ONRAM2_RAM2On (1UL) /*!< RAM block 2 ON in ON mode. */
+
+/* Register: POWER_DCDCEN */
+/* Description: DCDC converter enable configuration register. */
+
+/* Bit 0 : Enable DCDC converter. */
+#define POWER_DCDCEN_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */
+#define POWER_DCDCEN_DCDCEN_Msk (0x1UL << POWER_DCDCEN_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */
+#define POWER_DCDCEN_DCDCEN_Disabled (0UL) /*!< DCDC converter disabled. */
+#define POWER_DCDCEN_DCDCEN_Enabled (1UL) /*!< DCDC converter enabled. */
+
+/* Register: POWER_DCDCFORCE */
+/* Description: DCDC power-up force register. */
+
+/* Bit 1 : DCDC power-up force on. */
+#define POWER_DCDCFORCE_FORCEON_Pos (1UL) /*!< Position of FORCEON field. */
+#define POWER_DCDCFORCE_FORCEON_Msk (0x1UL << POWER_DCDCFORCE_FORCEON_Pos) /*!< Bit mask of FORCEON field. */
+#define POWER_DCDCFORCE_FORCEON_NoForce (0UL) /*!< No force. */
+#define POWER_DCDCFORCE_FORCEON_Force (1UL) /*!< Force. */
+
+/* Bit 0 : DCDC power-up force off. */
+#define POWER_DCDCFORCE_FORCEOFF_Pos (0UL) /*!< Position of FORCEOFF field. */
+#define POWER_DCDCFORCE_FORCEOFF_Msk (0x1UL << POWER_DCDCFORCE_FORCEOFF_Pos) /*!< Bit mask of FORCEOFF field. */
+#define POWER_DCDCFORCE_FORCEOFF_NoForce (0UL) /*!< No force. */
+#define POWER_DCDCFORCE_FORCEOFF_Force (1UL) /*!< Force. */
+
+
+/* Peripheral: PPI */
+/* Description: PPI controller. */
+
+/* Register: PPI_CHEN */
+/* Description: Channel enable. */
+
+/* Bit 31 : Enable PPI channel 31. */
+#define PPI_CHEN_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHEN_CH31_Msk (0x1UL << PPI_CHEN_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHEN_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH31_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 30 : Enable PPI channel 30. */
+#define PPI_CHEN_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHEN_CH30_Msk (0x1UL << PPI_CHEN_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHEN_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH30_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 29 : Enable PPI channel 29. */
+#define PPI_CHEN_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHEN_CH29_Msk (0x1UL << PPI_CHEN_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHEN_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH29_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 28 : Enable PPI channel 28. */
+#define PPI_CHEN_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHEN_CH28_Msk (0x1UL << PPI_CHEN_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHEN_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH28_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 27 : Enable PPI channel 27. */
+#define PPI_CHEN_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHEN_CH27_Msk (0x1UL << PPI_CHEN_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHEN_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH27_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 26 : Enable PPI channel 26. */
+#define PPI_CHEN_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHEN_CH26_Msk (0x1UL << PPI_CHEN_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHEN_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH26_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 25 : Enable PPI channel 25. */
+#define PPI_CHEN_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHEN_CH25_Msk (0x1UL << PPI_CHEN_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHEN_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH25_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 24 : Enable PPI channel 24. */
+#define PPI_CHEN_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHEN_CH24_Msk (0x1UL << PPI_CHEN_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHEN_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH24_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 23 : Enable PPI channel 23. */
+#define PPI_CHEN_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHEN_CH23_Msk (0x1UL << PPI_CHEN_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHEN_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH23_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 22 : Enable PPI channel 22. */
+#define PPI_CHEN_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHEN_CH22_Msk (0x1UL << PPI_CHEN_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHEN_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH22_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 21 : Enable PPI channel 21. */
+#define PPI_CHEN_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHEN_CH21_Msk (0x1UL << PPI_CHEN_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHEN_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH21_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 20 : Enable PPI channel 20. */
+#define PPI_CHEN_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHEN_CH20_Msk (0x1UL << PPI_CHEN_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHEN_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH20_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 15 : Enable PPI channel 15. */
+#define PPI_CHEN_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHEN_CH15_Msk (0x1UL << PPI_CHEN_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHEN_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH15_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 14 : Enable PPI channel 14. */
+#define PPI_CHEN_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHEN_CH14_Msk (0x1UL << PPI_CHEN_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHEN_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH14_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 13 : Enable PPI channel 13. */
+#define PPI_CHEN_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHEN_CH13_Msk (0x1UL << PPI_CHEN_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHEN_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH13_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 12 : Enable PPI channel 12. */
+#define PPI_CHEN_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHEN_CH12_Msk (0x1UL << PPI_CHEN_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHEN_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH12_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 11 : Enable PPI channel 11. */
+#define PPI_CHEN_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHEN_CH11_Msk (0x1UL << PPI_CHEN_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHEN_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH11_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 10 : Enable PPI channel 10. */
+#define PPI_CHEN_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHEN_CH10_Msk (0x1UL << PPI_CHEN_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHEN_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH10_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 9 : Enable PPI channel 9. */
+#define PPI_CHEN_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHEN_CH9_Msk (0x1UL << PPI_CHEN_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHEN_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH9_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 8 : Enable PPI channel 8. */
+#define PPI_CHEN_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHEN_CH8_Msk (0x1UL << PPI_CHEN_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHEN_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH8_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 7 : Enable PPI channel 7. */
+#define PPI_CHEN_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHEN_CH7_Msk (0x1UL << PPI_CHEN_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHEN_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH7_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 6 : Enable PPI channel 6. */
+#define PPI_CHEN_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHEN_CH6_Msk (0x1UL << PPI_CHEN_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHEN_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH6_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 5 : Enable PPI channel 5. */
+#define PPI_CHEN_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHEN_CH5_Msk (0x1UL << PPI_CHEN_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHEN_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH5_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 4 : Enable PPI channel 4. */
+#define PPI_CHEN_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHEN_CH4_Msk (0x1UL << PPI_CHEN_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHEN_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH4_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 3 : Enable PPI channel 3. */
+#define PPI_CHEN_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHEN_CH3_Msk (0x1UL << PPI_CHEN_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHEN_CH3_Disabled (0UL) /*!< Channel disabled */
+#define PPI_CHEN_CH3_Enabled (1UL) /*!< Channel enabled */
+
+/* Bit 2 : Enable PPI channel 2. */
+#define PPI_CHEN_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHEN_CH2_Msk (0x1UL << PPI_CHEN_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHEN_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH2_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 1 : Enable PPI channel 1. */
+#define PPI_CHEN_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHEN_CH1_Msk (0x1UL << PPI_CHEN_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHEN_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH1_Enabled (1UL) /*!< Channel enabled. */
+
+/* Bit 0 : Enable PPI channel 0. */
+#define PPI_CHEN_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHEN_CH0_Msk (0x1UL << PPI_CHEN_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHEN_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHEN_CH0_Enabled (1UL) /*!< Channel enabled. */
+
+/* Register: PPI_CHENSET */
+/* Description: Channel enable set. */
+
+/* Bit 31 : Enable PPI channel 31. */
+#define PPI_CHENSET_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHENSET_CH31_Msk (0x1UL << PPI_CHENSET_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHENSET_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH31_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH31_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 30 : Enable PPI channel 30. */
+#define PPI_CHENSET_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHENSET_CH30_Msk (0x1UL << PPI_CHENSET_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHENSET_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH30_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH30_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 29 : Enable PPI channel 29. */
+#define PPI_CHENSET_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHENSET_CH29_Msk (0x1UL << PPI_CHENSET_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHENSET_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH29_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH29_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 28 : Enable PPI channel 28. */
+#define PPI_CHENSET_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHENSET_CH28_Msk (0x1UL << PPI_CHENSET_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHENSET_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH28_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH28_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 27 : Enable PPI channel 27. */
+#define PPI_CHENSET_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHENSET_CH27_Msk (0x1UL << PPI_CHENSET_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHENSET_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH27_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH27_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 26 : Enable PPI channel 26. */
+#define PPI_CHENSET_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHENSET_CH26_Msk (0x1UL << PPI_CHENSET_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHENSET_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH26_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH26_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 25 : Enable PPI channel 25. */
+#define PPI_CHENSET_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHENSET_CH25_Msk (0x1UL << PPI_CHENSET_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHENSET_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH25_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH25_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 24 : Enable PPI channel 24. */
+#define PPI_CHENSET_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHENSET_CH24_Msk (0x1UL << PPI_CHENSET_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHENSET_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH24_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH24_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 23 : Enable PPI channel 23. */
+#define PPI_CHENSET_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHENSET_CH23_Msk (0x1UL << PPI_CHENSET_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHENSET_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH23_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH23_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 22 : Enable PPI channel 22. */
+#define PPI_CHENSET_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHENSET_CH22_Msk (0x1UL << PPI_CHENSET_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHENSET_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH22_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH22_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 21 : Enable PPI channel 21. */
+#define PPI_CHENSET_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHENSET_CH21_Msk (0x1UL << PPI_CHENSET_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHENSET_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH21_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH21_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 20 : Enable PPI channel 20. */
+#define PPI_CHENSET_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHENSET_CH20_Msk (0x1UL << PPI_CHENSET_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHENSET_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH20_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH20_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 15 : Enable PPI channel 15. */
+#define PPI_CHENSET_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHENSET_CH15_Msk (0x1UL << PPI_CHENSET_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHENSET_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH15_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH15_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 14 : Enable PPI channel 14. */
+#define PPI_CHENSET_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHENSET_CH14_Msk (0x1UL << PPI_CHENSET_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHENSET_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH14_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH14_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 13 : Enable PPI channel 13. */
+#define PPI_CHENSET_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHENSET_CH13_Msk (0x1UL << PPI_CHENSET_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHENSET_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH13_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH13_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 12 : Enable PPI channel 12. */
+#define PPI_CHENSET_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHENSET_CH12_Msk (0x1UL << PPI_CHENSET_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHENSET_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH12_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH12_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 11 : Enable PPI channel 11. */
+#define PPI_CHENSET_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHENSET_CH11_Msk (0x1UL << PPI_CHENSET_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHENSET_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH11_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH11_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 10 : Enable PPI channel 10. */
+#define PPI_CHENSET_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHENSET_CH10_Msk (0x1UL << PPI_CHENSET_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHENSET_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH10_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH10_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 9 : Enable PPI channel 9. */
+#define PPI_CHENSET_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHENSET_CH9_Msk (0x1UL << PPI_CHENSET_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHENSET_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH9_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH9_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 8 : Enable PPI channel 8. */
+#define PPI_CHENSET_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHENSET_CH8_Msk (0x1UL << PPI_CHENSET_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHENSET_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH8_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH8_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 7 : Enable PPI channel 7. */
+#define PPI_CHENSET_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHENSET_CH7_Msk (0x1UL << PPI_CHENSET_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHENSET_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH7_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH7_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 6 : Enable PPI channel 6. */
+#define PPI_CHENSET_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHENSET_CH6_Msk (0x1UL << PPI_CHENSET_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHENSET_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH6_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH6_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 5 : Enable PPI channel 5. */
+#define PPI_CHENSET_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHENSET_CH5_Msk (0x1UL << PPI_CHENSET_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHENSET_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH5_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH5_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 4 : Enable PPI channel 4. */
+#define PPI_CHENSET_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHENSET_CH4_Msk (0x1UL << PPI_CHENSET_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHENSET_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH4_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH4_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 3 : Enable PPI channel 3. */
+#define PPI_CHENSET_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHENSET_CH3_Msk (0x1UL << PPI_CHENSET_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHENSET_CH3_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH3_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH3_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 2 : Enable PPI channel 2. */
+#define PPI_CHENSET_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHENSET_CH2_Msk (0x1UL << PPI_CHENSET_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHENSET_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH2_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH2_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 1 : Enable PPI channel 1. */
+#define PPI_CHENSET_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHENSET_CH1_Msk (0x1UL << PPI_CHENSET_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHENSET_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH1_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH1_Set (1UL) /*!< Enable channel on write. */
+
+/* Bit 0 : Enable PPI channel 0. */
+#define PPI_CHENSET_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHENSET_CH0_Msk (0x1UL << PPI_CHENSET_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHENSET_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENSET_CH0_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENSET_CH0_Set (1UL) /*!< Enable channel on write. */
+
+/* Register: PPI_CHENCLR */
+/* Description: Channel enable clear. */
+
+/* Bit 31 : Disable PPI channel 31. */
+#define PPI_CHENCLR_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHENCLR_CH31_Msk (0x1UL << PPI_CHENCLR_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHENCLR_CH31_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH31_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH31_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 30 : Disable PPI channel 30. */
+#define PPI_CHENCLR_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHENCLR_CH30_Msk (0x1UL << PPI_CHENCLR_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHENCLR_CH30_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH30_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH30_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 29 : Disable PPI channel 29. */
+#define PPI_CHENCLR_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHENCLR_CH29_Msk (0x1UL << PPI_CHENCLR_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHENCLR_CH29_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH29_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH29_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 28 : Disable PPI channel 28. */
+#define PPI_CHENCLR_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHENCLR_CH28_Msk (0x1UL << PPI_CHENCLR_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHENCLR_CH28_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH28_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH28_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 27 : Disable PPI channel 27. */
+#define PPI_CHENCLR_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHENCLR_CH27_Msk (0x1UL << PPI_CHENCLR_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHENCLR_CH27_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH27_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH27_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 26 : Disable PPI channel 26. */
+#define PPI_CHENCLR_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHENCLR_CH26_Msk (0x1UL << PPI_CHENCLR_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHENCLR_CH26_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH26_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH26_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 25 : Disable PPI channel 25. */
+#define PPI_CHENCLR_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHENCLR_CH25_Msk (0x1UL << PPI_CHENCLR_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHENCLR_CH25_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH25_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH25_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 24 : Disable PPI channel 24. */
+#define PPI_CHENCLR_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHENCLR_CH24_Msk (0x1UL << PPI_CHENCLR_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHENCLR_CH24_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH24_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH24_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 23 : Disable PPI channel 23. */
+#define PPI_CHENCLR_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHENCLR_CH23_Msk (0x1UL << PPI_CHENCLR_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHENCLR_CH23_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH23_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH23_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 22 : Disable PPI channel 22. */
+#define PPI_CHENCLR_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHENCLR_CH22_Msk (0x1UL << PPI_CHENCLR_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHENCLR_CH22_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH22_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH22_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 21 : Disable PPI channel 21. */
+#define PPI_CHENCLR_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHENCLR_CH21_Msk (0x1UL << PPI_CHENCLR_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHENCLR_CH21_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH21_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH21_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 20 : Disable PPI channel 20. */
+#define PPI_CHENCLR_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHENCLR_CH20_Msk (0x1UL << PPI_CHENCLR_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHENCLR_CH20_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH20_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH20_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 15 : Disable PPI channel 15. */
+#define PPI_CHENCLR_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHENCLR_CH15_Msk (0x1UL << PPI_CHENCLR_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHENCLR_CH15_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH15_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH15_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 14 : Disable PPI channel 14. */
+#define PPI_CHENCLR_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHENCLR_CH14_Msk (0x1UL << PPI_CHENCLR_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHENCLR_CH14_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH14_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH14_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 13 : Disable PPI channel 13. */
+#define PPI_CHENCLR_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHENCLR_CH13_Msk (0x1UL << PPI_CHENCLR_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHENCLR_CH13_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH13_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH13_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 12 : Disable PPI channel 12. */
+#define PPI_CHENCLR_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHENCLR_CH12_Msk (0x1UL << PPI_CHENCLR_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHENCLR_CH12_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH12_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH12_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 11 : Disable PPI channel 11. */
+#define PPI_CHENCLR_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHENCLR_CH11_Msk (0x1UL << PPI_CHENCLR_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHENCLR_CH11_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH11_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH11_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 10 : Disable PPI channel 10. */
+#define PPI_CHENCLR_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHENCLR_CH10_Msk (0x1UL << PPI_CHENCLR_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHENCLR_CH10_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH10_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH10_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 9 : Disable PPI channel 9. */
+#define PPI_CHENCLR_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHENCLR_CH9_Msk (0x1UL << PPI_CHENCLR_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHENCLR_CH9_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH9_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH9_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 8 : Disable PPI channel 8. */
+#define PPI_CHENCLR_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHENCLR_CH8_Msk (0x1UL << PPI_CHENCLR_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHENCLR_CH8_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH8_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH8_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 7 : Disable PPI channel 7. */
+#define PPI_CHENCLR_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHENCLR_CH7_Msk (0x1UL << PPI_CHENCLR_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHENCLR_CH7_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH7_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH7_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 6 : Disable PPI channel 6. */
+#define PPI_CHENCLR_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHENCLR_CH6_Msk (0x1UL << PPI_CHENCLR_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHENCLR_CH6_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH6_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH6_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 5 : Disable PPI channel 5. */
+#define PPI_CHENCLR_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHENCLR_CH5_Msk (0x1UL << PPI_CHENCLR_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHENCLR_CH5_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH5_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH5_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 4 : Disable PPI channel 4. */
+#define PPI_CHENCLR_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHENCLR_CH4_Msk (0x1UL << PPI_CHENCLR_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHENCLR_CH4_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH4_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH4_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 3 : Disable PPI channel 3. */
+#define PPI_CHENCLR_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHENCLR_CH3_Msk (0x1UL << PPI_CHENCLR_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHENCLR_CH3_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH3_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH3_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 2 : Disable PPI channel 2. */
+#define PPI_CHENCLR_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHENCLR_CH2_Msk (0x1UL << PPI_CHENCLR_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHENCLR_CH2_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH2_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH2_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 1 : Disable PPI channel 1. */
+#define PPI_CHENCLR_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHENCLR_CH1_Msk (0x1UL << PPI_CHENCLR_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHENCLR_CH1_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH1_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH1_Clear (1UL) /*!< Disable channel on write. */
+
+/* Bit 0 : Disable PPI channel 0. */
+#define PPI_CHENCLR_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHENCLR_CH0_Msk (0x1UL << PPI_CHENCLR_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHENCLR_CH0_Disabled (0UL) /*!< Channel disabled. */
+#define PPI_CHENCLR_CH0_Enabled (1UL) /*!< Channel enabled. */
+#define PPI_CHENCLR_CH0_Clear (1UL) /*!< Disable channel on write. */
+
+/* Register: PPI_CHG */
+/* Description: Channel group configuration. */
+
+/* Bit 31 : Include CH31 in channel group. */
+#define PPI_CHG_CH31_Pos (31UL) /*!< Position of CH31 field. */
+#define PPI_CHG_CH31_Msk (0x1UL << PPI_CHG_CH31_Pos) /*!< Bit mask of CH31 field. */
+#define PPI_CHG_CH31_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH31_Included (1UL) /*!< Channel included. */
+
+/* Bit 30 : Include CH30 in channel group. */
+#define PPI_CHG_CH30_Pos (30UL) /*!< Position of CH30 field. */
+#define PPI_CHG_CH30_Msk (0x1UL << PPI_CHG_CH30_Pos) /*!< Bit mask of CH30 field. */
+#define PPI_CHG_CH30_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH30_Included (1UL) /*!< Channel included. */
+
+/* Bit 29 : Include CH29 in channel group. */
+#define PPI_CHG_CH29_Pos (29UL) /*!< Position of CH29 field. */
+#define PPI_CHG_CH29_Msk (0x1UL << PPI_CHG_CH29_Pos) /*!< Bit mask of CH29 field. */
+#define PPI_CHG_CH29_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH29_Included (1UL) /*!< Channel included. */
+
+/* Bit 28 : Include CH28 in channel group. */
+#define PPI_CHG_CH28_Pos (28UL) /*!< Position of CH28 field. */
+#define PPI_CHG_CH28_Msk (0x1UL << PPI_CHG_CH28_Pos) /*!< Bit mask of CH28 field. */
+#define PPI_CHG_CH28_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH28_Included (1UL) /*!< Channel included. */
+
+/* Bit 27 : Include CH27 in channel group. */
+#define PPI_CHG_CH27_Pos (27UL) /*!< Position of CH27 field. */
+#define PPI_CHG_CH27_Msk (0x1UL << PPI_CHG_CH27_Pos) /*!< Bit mask of CH27 field. */
+#define PPI_CHG_CH27_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH27_Included (1UL) /*!< Channel included. */
+
+/* Bit 26 : Include CH26 in channel group. */
+#define PPI_CHG_CH26_Pos (26UL) /*!< Position of CH26 field. */
+#define PPI_CHG_CH26_Msk (0x1UL << PPI_CHG_CH26_Pos) /*!< Bit mask of CH26 field. */
+#define PPI_CHG_CH26_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH26_Included (1UL) /*!< Channel included. */
+
+/* Bit 25 : Include CH25 in channel group. */
+#define PPI_CHG_CH25_Pos (25UL) /*!< Position of CH25 field. */
+#define PPI_CHG_CH25_Msk (0x1UL << PPI_CHG_CH25_Pos) /*!< Bit mask of CH25 field. */
+#define PPI_CHG_CH25_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH25_Included (1UL) /*!< Channel included. */
+
+/* Bit 24 : Include CH24 in channel group. */
+#define PPI_CHG_CH24_Pos (24UL) /*!< Position of CH24 field. */
+#define PPI_CHG_CH24_Msk (0x1UL << PPI_CHG_CH24_Pos) /*!< Bit mask of CH24 field. */
+#define PPI_CHG_CH24_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH24_Included (1UL) /*!< Channel included. */
+
+/* Bit 23 : Include CH23 in channel group. */
+#define PPI_CHG_CH23_Pos (23UL) /*!< Position of CH23 field. */
+#define PPI_CHG_CH23_Msk (0x1UL << PPI_CHG_CH23_Pos) /*!< Bit mask of CH23 field. */
+#define PPI_CHG_CH23_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH23_Included (1UL) /*!< Channel included. */
+
+/* Bit 22 : Include CH22 in channel group. */
+#define PPI_CHG_CH22_Pos (22UL) /*!< Position of CH22 field. */
+#define PPI_CHG_CH22_Msk (0x1UL << PPI_CHG_CH22_Pos) /*!< Bit mask of CH22 field. */
+#define PPI_CHG_CH22_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH22_Included (1UL) /*!< Channel included. */
+
+/* Bit 21 : Include CH21 in channel group. */
+#define PPI_CHG_CH21_Pos (21UL) /*!< Position of CH21 field. */
+#define PPI_CHG_CH21_Msk (0x1UL << PPI_CHG_CH21_Pos) /*!< Bit mask of CH21 field. */
+#define PPI_CHG_CH21_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH21_Included (1UL) /*!< Channel included. */
+
+/* Bit 20 : Include CH20 in channel group. */
+#define PPI_CHG_CH20_Pos (20UL) /*!< Position of CH20 field. */
+#define PPI_CHG_CH20_Msk (0x1UL << PPI_CHG_CH20_Pos) /*!< Bit mask of CH20 field. */
+#define PPI_CHG_CH20_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH20_Included (1UL) /*!< Channel included. */
+
+/* Bit 15 : Include CH15 in channel group. */
+#define PPI_CHG_CH15_Pos (15UL) /*!< Position of CH15 field. */
+#define PPI_CHG_CH15_Msk (0x1UL << PPI_CHG_CH15_Pos) /*!< Bit mask of CH15 field. */
+#define PPI_CHG_CH15_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH15_Included (1UL) /*!< Channel included. */
+
+/* Bit 14 : Include CH14 in channel group. */
+#define PPI_CHG_CH14_Pos (14UL) /*!< Position of CH14 field. */
+#define PPI_CHG_CH14_Msk (0x1UL << PPI_CHG_CH14_Pos) /*!< Bit mask of CH14 field. */
+#define PPI_CHG_CH14_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH14_Included (1UL) /*!< Channel included. */
+
+/* Bit 13 : Include CH13 in channel group. */
+#define PPI_CHG_CH13_Pos (13UL) /*!< Position of CH13 field. */
+#define PPI_CHG_CH13_Msk (0x1UL << PPI_CHG_CH13_Pos) /*!< Bit mask of CH13 field. */
+#define PPI_CHG_CH13_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH13_Included (1UL) /*!< Channel included. */
+
+/* Bit 12 : Include CH12 in channel group. */
+#define PPI_CHG_CH12_Pos (12UL) /*!< Position of CH12 field. */
+#define PPI_CHG_CH12_Msk (0x1UL << PPI_CHG_CH12_Pos) /*!< Bit mask of CH12 field. */
+#define PPI_CHG_CH12_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH12_Included (1UL) /*!< Channel included. */
+
+/* Bit 11 : Include CH11 in channel group. */
+#define PPI_CHG_CH11_Pos (11UL) /*!< Position of CH11 field. */
+#define PPI_CHG_CH11_Msk (0x1UL << PPI_CHG_CH11_Pos) /*!< Bit mask of CH11 field. */
+#define PPI_CHG_CH11_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH11_Included (1UL) /*!< Channel included. */
+
+/* Bit 10 : Include CH10 in channel group. */
+#define PPI_CHG_CH10_Pos (10UL) /*!< Position of CH10 field. */
+#define PPI_CHG_CH10_Msk (0x1UL << PPI_CHG_CH10_Pos) /*!< Bit mask of CH10 field. */
+#define PPI_CHG_CH10_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH10_Included (1UL) /*!< Channel included. */
+
+/* Bit 9 : Include CH9 in channel group. */
+#define PPI_CHG_CH9_Pos (9UL) /*!< Position of CH9 field. */
+#define PPI_CHG_CH9_Msk (0x1UL << PPI_CHG_CH9_Pos) /*!< Bit mask of CH9 field. */
+#define PPI_CHG_CH9_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH9_Included (1UL) /*!< Channel included. */
+
+/* Bit 8 : Include CH8 in channel group. */
+#define PPI_CHG_CH8_Pos (8UL) /*!< Position of CH8 field. */
+#define PPI_CHG_CH8_Msk (0x1UL << PPI_CHG_CH8_Pos) /*!< Bit mask of CH8 field. */
+#define PPI_CHG_CH8_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH8_Included (1UL) /*!< Channel included. */
+
+/* Bit 7 : Include CH7 in channel group. */
+#define PPI_CHG_CH7_Pos (7UL) /*!< Position of CH7 field. */
+#define PPI_CHG_CH7_Msk (0x1UL << PPI_CHG_CH7_Pos) /*!< Bit mask of CH7 field. */
+#define PPI_CHG_CH7_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH7_Included (1UL) /*!< Channel included. */
+
+/* Bit 6 : Include CH6 in channel group. */
+#define PPI_CHG_CH6_Pos (6UL) /*!< Position of CH6 field. */
+#define PPI_CHG_CH6_Msk (0x1UL << PPI_CHG_CH6_Pos) /*!< Bit mask of CH6 field. */
+#define PPI_CHG_CH6_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH6_Included (1UL) /*!< Channel included. */
+
+/* Bit 5 : Include CH5 in channel group. */
+#define PPI_CHG_CH5_Pos (5UL) /*!< Position of CH5 field. */
+#define PPI_CHG_CH5_Msk (0x1UL << PPI_CHG_CH5_Pos) /*!< Bit mask of CH5 field. */
+#define PPI_CHG_CH5_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH5_Included (1UL) /*!< Channel included. */
+
+/* Bit 4 : Include CH4 in channel group. */
+#define PPI_CHG_CH4_Pos (4UL) /*!< Position of CH4 field. */
+#define PPI_CHG_CH4_Msk (0x1UL << PPI_CHG_CH4_Pos) /*!< Bit mask of CH4 field. */
+#define PPI_CHG_CH4_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH4_Included (1UL) /*!< Channel included. */
+
+/* Bit 3 : Include CH3 in channel group. */
+#define PPI_CHG_CH3_Pos (3UL) /*!< Position of CH3 field. */
+#define PPI_CHG_CH3_Msk (0x1UL << PPI_CHG_CH3_Pos) /*!< Bit mask of CH3 field. */
+#define PPI_CHG_CH3_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH3_Included (1UL) /*!< Channel included. */
+
+/* Bit 2 : Include CH2 in channel group. */
+#define PPI_CHG_CH2_Pos (2UL) /*!< Position of CH2 field. */
+#define PPI_CHG_CH2_Msk (0x1UL << PPI_CHG_CH2_Pos) /*!< Bit mask of CH2 field. */
+#define PPI_CHG_CH2_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH2_Included (1UL) /*!< Channel included. */
+
+/* Bit 1 : Include CH1 in channel group. */
+#define PPI_CHG_CH1_Pos (1UL) /*!< Position of CH1 field. */
+#define PPI_CHG_CH1_Msk (0x1UL << PPI_CHG_CH1_Pos) /*!< Bit mask of CH1 field. */
+#define PPI_CHG_CH1_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH1_Included (1UL) /*!< Channel included. */
+
+/* Bit 0 : Include CH0 in channel group. */
+#define PPI_CHG_CH0_Pos (0UL) /*!< Position of CH0 field. */
+#define PPI_CHG_CH0_Msk (0x1UL << PPI_CHG_CH0_Pos) /*!< Bit mask of CH0 field. */
+#define PPI_CHG_CH0_Excluded (0UL) /*!< Channel excluded. */
+#define PPI_CHG_CH0_Included (1UL) /*!< Channel included. */
+
+
+/* Peripheral: QDEC */
+/* Description: Rotary decoder. */
+
+/* Register: QDEC_SHORTS */
+/* Description: Shortcuts for the QDEC. */
+
+/* Bit 1 : Shortcut between SAMPLERDY event and STOP task. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Pos (1UL) /*!< Position of SAMPLERDY_STOP field. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_STOP_Pos) /*!< Bit mask of SAMPLERDY_STOP field. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define QDEC_SHORTS_SAMPLERDY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between REPORTRDY event and READCLRACC task. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Pos (0UL) /*!< Position of REPORTRDY_READCLRACC field. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_READCLRACC_Pos) /*!< Bit mask of REPORTRDY_READCLRACC field. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Disabled (0UL) /*!< Shortcut disabled. */
+#define QDEC_SHORTS_REPORTRDY_READCLRACC_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: QDEC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on ACCOF event. */
+#define QDEC_INTENSET_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */
+#define QDEC_INTENSET_ACCOF_Msk (0x1UL << QDEC_INTENSET_ACCOF_Pos) /*!< Bit mask of ACCOF field. */
+#define QDEC_INTENSET_ACCOF_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_ACCOF_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_ACCOF_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on REPORTRDY event. */
+#define QDEC_INTENSET_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */
+#define QDEC_INTENSET_REPORTRDY_Msk (0x1UL << QDEC_INTENSET_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */
+#define QDEC_INTENSET_REPORTRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_REPORTRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_REPORTRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on SAMPLERDY event. */
+#define QDEC_INTENSET_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */
+#define QDEC_INTENSET_SAMPLERDY_Msk (0x1UL << QDEC_INTENSET_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */
+#define QDEC_INTENSET_SAMPLERDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENSET_SAMPLERDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENSET_SAMPLERDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: QDEC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on ACCOF event. */
+#define QDEC_INTENCLR_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */
+#define QDEC_INTENCLR_ACCOF_Msk (0x1UL << QDEC_INTENCLR_ACCOF_Pos) /*!< Bit mask of ACCOF field. */
+#define QDEC_INTENCLR_ACCOF_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_ACCOF_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_ACCOF_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on REPORTRDY event. */
+#define QDEC_INTENCLR_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */
+#define QDEC_INTENCLR_REPORTRDY_Msk (0x1UL << QDEC_INTENCLR_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */
+#define QDEC_INTENCLR_REPORTRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_REPORTRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_REPORTRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on SAMPLERDY event. */
+#define QDEC_INTENCLR_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */
+#define QDEC_INTENCLR_SAMPLERDY_Msk (0x1UL << QDEC_INTENCLR_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */
+#define QDEC_INTENCLR_SAMPLERDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define QDEC_INTENCLR_SAMPLERDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define QDEC_INTENCLR_SAMPLERDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: QDEC_ENABLE */
+/* Description: Enable the QDEC. */
+
+/* Bit 0 : Enable or disable QDEC. */
+#define QDEC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define QDEC_ENABLE_ENABLE_Msk (0x1UL << QDEC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define QDEC_ENABLE_ENABLE_Disabled (0UL) /*!< Disabled QDEC. */
+#define QDEC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable QDEC. */
+
+/* Register: QDEC_LEDPOL */
+/* Description: LED output pin polarity. */
+
+/* Bit 0 : LED output pin polarity. */
+#define QDEC_LEDPOL_LEDPOL_Pos (0UL) /*!< Position of LEDPOL field. */
+#define QDEC_LEDPOL_LEDPOL_Msk (0x1UL << QDEC_LEDPOL_LEDPOL_Pos) /*!< Bit mask of LEDPOL field. */
+#define QDEC_LEDPOL_LEDPOL_ActiveLow (0UL) /*!< LED output is active low. */
+#define QDEC_LEDPOL_LEDPOL_ActiveHigh (1UL) /*!< LED output is active high. */
+
+/* Register: QDEC_SAMPLEPER */
+/* Description: Sample period. */
+
+/* Bits 2..0 : Sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_Pos (0UL) /*!< Position of SAMPLEPER field. */
+#define QDEC_SAMPLEPER_SAMPLEPER_Msk (0x7UL << QDEC_SAMPLEPER_SAMPLEPER_Pos) /*!< Bit mask of SAMPLEPER field. */
+#define QDEC_SAMPLEPER_SAMPLEPER_128us (0x00UL) /*!< 128us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_256us (0x01UL) /*!< 256us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_512us (0x02UL) /*!< 512us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_1024us (0x03UL) /*!< 1024us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_2048us (0x04UL) /*!< 2048us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_4096us (0x05UL) /*!< 4096us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_8192us (0x06UL) /*!< 8192us sample period. */
+#define QDEC_SAMPLEPER_SAMPLEPER_16384us (0x07UL) /*!< 16384us sample period. */
+
+/* Register: QDEC_SAMPLE */
+/* Description: Motion sample value. */
+
+/* Bits 31..0 : Last sample taken in compliment to 2. */
+#define QDEC_SAMPLE_SAMPLE_Pos (0UL) /*!< Position of SAMPLE field. */
+#define QDEC_SAMPLE_SAMPLE_Msk (0xFFFFFFFFUL << QDEC_SAMPLE_SAMPLE_Pos) /*!< Bit mask of SAMPLE field. */
+
+/* Register: QDEC_REPORTPER */
+/* Description: Number of samples to generate an EVENT_REPORTRDY. */
+
+/* Bits 2..0 : Number of samples to generate an EVENT_REPORTRDY. */
+#define QDEC_REPORTPER_REPORTPER_Pos (0UL) /*!< Position of REPORTPER field. */
+#define QDEC_REPORTPER_REPORTPER_Msk (0x7UL << QDEC_REPORTPER_REPORTPER_Pos) /*!< Bit mask of REPORTPER field. */
+#define QDEC_REPORTPER_REPORTPER_10Smpl (0x00UL) /*!< 10 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_40Smpl (0x01UL) /*!< 40 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_80Smpl (0x02UL) /*!< 80 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_120Smpl (0x03UL) /*!< 120 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_160Smpl (0x04UL) /*!< 160 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_200Smpl (0x05UL) /*!< 200 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_240Smpl (0x06UL) /*!< 240 samples per report. */
+#define QDEC_REPORTPER_REPORTPER_280Smpl (0x07UL) /*!< 280 samples per report. */
+
+/* Register: QDEC_DBFEN */
+/* Description: Enable debouncer input filters. */
+
+/* Bit 0 : Enable debounce input filters. */
+#define QDEC_DBFEN_DBFEN_Pos (0UL) /*!< Position of DBFEN field. */
+#define QDEC_DBFEN_DBFEN_Msk (0x1UL << QDEC_DBFEN_DBFEN_Pos) /*!< Bit mask of DBFEN field. */
+#define QDEC_DBFEN_DBFEN_Disabled (0UL) /*!< Debounce input filters disabled. */
+#define QDEC_DBFEN_DBFEN_Enabled (1UL) /*!< Debounce input filters enabled. */
+
+/* Register: QDEC_LEDPRE */
+/* Description: Time LED is switched ON before the sample. */
+
+/* Bits 8..0 : Period in us the LED in switched on prior to sampling. */
+#define QDEC_LEDPRE_LEDPRE_Pos (0UL) /*!< Position of LEDPRE field. */
+#define QDEC_LEDPRE_LEDPRE_Msk (0x1FFUL << QDEC_LEDPRE_LEDPRE_Pos) /*!< Bit mask of LEDPRE field. */
+
+/* Register: QDEC_ACCDBL */
+/* Description: Accumulated double (error) transitions register. */
+
+/* Bits 3..0 : Accumulated double (error) transitions. */
+#define QDEC_ACCDBL_ACCDBL_Pos (0UL) /*!< Position of ACCDBL field. */
+#define QDEC_ACCDBL_ACCDBL_Msk (0xFUL << QDEC_ACCDBL_ACCDBL_Pos) /*!< Bit mask of ACCDBL field. */
+
+/* Register: QDEC_ACCDBLREAD */
+/* Description: Snapshot of ACCDBL register. Value generated by the TASKS_READCLEACC task. */
+
+/* Bits 3..0 : Snapshot of accumulated double (error) transitions. */
+#define QDEC_ACCDBLREAD_ACCDBLREAD_Pos (0UL) /*!< Position of ACCDBLREAD field. */
+#define QDEC_ACCDBLREAD_ACCDBLREAD_Msk (0xFUL << QDEC_ACCDBLREAD_ACCDBLREAD_Pos) /*!< Bit mask of ACCDBLREAD field. */
+
+/* Register: QDEC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define QDEC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define QDEC_POWER_POWER_Msk (0x1UL << QDEC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define QDEC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define QDEC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RADIO */
+/* Description: The radio. */
+
+/* Register: RADIO_SHORTS */
+/* Description: Shortcuts for the radio. */
+
+/* Bit 8 : Shortcut between DISABLED event and RSSISTOP task. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Pos (8UL) /*!< Position of DISABLED_RSSISTOP field. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Msk (0x1UL << RADIO_SHORTS_DISABLED_RSSISTOP_Pos) /*!< Bit mask of DISABLED_RSSISTOP field. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_RSSISTOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 6 : Shortcut between ADDRESS event and BCSTART task. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Pos (6UL) /*!< Position of ADDRESS_BCSTART field. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_BCSTART_Pos) /*!< Bit mask of ADDRESS_BCSTART field. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_ADDRESS_BCSTART_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 5 : Shortcut between END event and START task. */
+#define RADIO_SHORTS_END_START_Pos (5UL) /*!< Position of END_START field. */
+#define RADIO_SHORTS_END_START_Msk (0x1UL << RADIO_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */
+#define RADIO_SHORTS_END_START_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_END_START_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 4 : Shortcut between ADDRESS event and RSSISTART task. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Pos (4UL) /*!< Position of ADDRESS_RSSISTART field. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_RSSISTART_Pos) /*!< Bit mask of ADDRESS_RSSISTART field. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_ADDRESS_RSSISTART_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between DISABLED event and RXEN task. */
+#define RADIO_SHORTS_DISABLED_RXEN_Pos (3UL) /*!< Position of DISABLED_RXEN field. */
+#define RADIO_SHORTS_DISABLED_RXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_RXEN_Pos) /*!< Bit mask of DISABLED_RXEN field. */
+#define RADIO_SHORTS_DISABLED_RXEN_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_RXEN_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between DISABLED event and TXEN task.  */
+#define RADIO_SHORTS_DISABLED_TXEN_Pos (2UL) /*!< Position of DISABLED_TXEN field. */
+#define RADIO_SHORTS_DISABLED_TXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_TXEN_Pos) /*!< Bit mask of DISABLED_TXEN field. */
+#define RADIO_SHORTS_DISABLED_TXEN_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_DISABLED_TXEN_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between END event and DISABLE task. */
+#define RADIO_SHORTS_END_DISABLE_Pos (1UL) /*!< Position of END_DISABLE field. */
+#define RADIO_SHORTS_END_DISABLE_Msk (0x1UL << RADIO_SHORTS_END_DISABLE_Pos) /*!< Bit mask of END_DISABLE field. */
+#define RADIO_SHORTS_END_DISABLE_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_END_DISABLE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between READY event and START task. */
+#define RADIO_SHORTS_READY_START_Pos (0UL) /*!< Position of READY_START field. */
+#define RADIO_SHORTS_READY_START_Msk (0x1UL << RADIO_SHORTS_READY_START_Pos) /*!< Bit mask of READY_START field. */
+#define RADIO_SHORTS_READY_START_Disabled (0UL) /*!< Shortcut disabled. */
+#define RADIO_SHORTS_READY_START_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: RADIO_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 10 : Enable interrupt on BCMATCH event. */
+#define RADIO_INTENSET_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */
+#define RADIO_INTENSET_BCMATCH_Msk (0x1UL << RADIO_INTENSET_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */
+#define RADIO_INTENSET_BCMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_BCMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_BCMATCH_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on RSSIEND event. */
+#define RADIO_INTENSET_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */
+#define RADIO_INTENSET_RSSIEND_Msk (0x1UL << RADIO_INTENSET_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */
+#define RADIO_INTENSET_RSSIEND_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_RSSIEND_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_RSSIEND_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 6 : Enable interrupt on DEVMISS event. */
+#define RADIO_INTENSET_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */
+#define RADIO_INTENSET_DEVMISS_Msk (0x1UL << RADIO_INTENSET_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */
+#define RADIO_INTENSET_DEVMISS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DEVMISS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DEVMISS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 5 : Enable interrupt on DEVMATCH event. */
+#define RADIO_INTENSET_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */
+#define RADIO_INTENSET_DEVMATCH_Msk (0x1UL << RADIO_INTENSET_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */
+#define RADIO_INTENSET_DEVMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DEVMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DEVMATCH_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 4 : Enable interrupt on DISABLED event. */
+#define RADIO_INTENSET_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */
+#define RADIO_INTENSET_DISABLED_Msk (0x1UL << RADIO_INTENSET_DISABLED_Pos) /*!< Bit mask of DISABLED field. */
+#define RADIO_INTENSET_DISABLED_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_DISABLED_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_DISABLED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 3 : Enable interrupt on END event. */
+#define RADIO_INTENSET_END_Pos (3UL) /*!< Position of END field. */
+#define RADIO_INTENSET_END_Msk (0x1UL << RADIO_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define RADIO_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on PAYLOAD event. */
+#define RADIO_INTENSET_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */
+#define RADIO_INTENSET_PAYLOAD_Msk (0x1UL << RADIO_INTENSET_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */
+#define RADIO_INTENSET_PAYLOAD_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_PAYLOAD_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_PAYLOAD_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on ADDRESS event. */
+#define RADIO_INTENSET_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */
+#define RADIO_INTENSET_ADDRESS_Msk (0x1UL << RADIO_INTENSET_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+#define RADIO_INTENSET_ADDRESS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_ADDRESS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_ADDRESS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on READY event. */
+#define RADIO_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */
+#define RADIO_INTENSET_READY_Msk (0x1UL << RADIO_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define RADIO_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RADIO_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 10 : Disable interrupt on BCMATCH event. */
+#define RADIO_INTENCLR_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */
+#define RADIO_INTENCLR_BCMATCH_Msk (0x1UL << RADIO_INTENCLR_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */
+#define RADIO_INTENCLR_BCMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_BCMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_BCMATCH_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on RSSIEND event. */
+#define RADIO_INTENCLR_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */
+#define RADIO_INTENCLR_RSSIEND_Msk (0x1UL << RADIO_INTENCLR_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */
+#define RADIO_INTENCLR_RSSIEND_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_RSSIEND_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_RSSIEND_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 6 : Disable interrupt on DEVMISS event. */
+#define RADIO_INTENCLR_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */
+#define RADIO_INTENCLR_DEVMISS_Msk (0x1UL << RADIO_INTENCLR_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */
+#define RADIO_INTENCLR_DEVMISS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DEVMISS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DEVMISS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 5 : Disable interrupt on DEVMATCH event. */
+#define RADIO_INTENCLR_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */
+#define RADIO_INTENCLR_DEVMATCH_Msk (0x1UL << RADIO_INTENCLR_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */
+#define RADIO_INTENCLR_DEVMATCH_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DEVMATCH_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DEVMATCH_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 4 : Disable interrupt on DISABLED event. */
+#define RADIO_INTENCLR_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */
+#define RADIO_INTENCLR_DISABLED_Msk (0x1UL << RADIO_INTENCLR_DISABLED_Pos) /*!< Bit mask of DISABLED field. */
+#define RADIO_INTENCLR_DISABLED_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_DISABLED_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_DISABLED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 3 : Disable interrupt on END event. */
+#define RADIO_INTENCLR_END_Pos (3UL) /*!< Position of END field. */
+#define RADIO_INTENCLR_END_Msk (0x1UL << RADIO_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define RADIO_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on PAYLOAD event. */
+#define RADIO_INTENCLR_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */
+#define RADIO_INTENCLR_PAYLOAD_Msk (0x1UL << RADIO_INTENCLR_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */
+#define RADIO_INTENCLR_PAYLOAD_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_PAYLOAD_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_PAYLOAD_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on ADDRESS event. */
+#define RADIO_INTENCLR_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */
+#define RADIO_INTENCLR_ADDRESS_Msk (0x1UL << RADIO_INTENCLR_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+#define RADIO_INTENCLR_ADDRESS_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_ADDRESS_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_ADDRESS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on READY event. */
+#define RADIO_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */
+#define RADIO_INTENCLR_READY_Msk (0x1UL << RADIO_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define RADIO_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RADIO_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RADIO_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RADIO_CRCSTATUS */
+/* Description: CRC status of received packet. */
+
+/* Bit 0 : CRC status of received packet. */
+#define RADIO_CRCSTATUS_CRCSTATUS_Pos (0UL) /*!< Position of CRCSTATUS field. */
+#define RADIO_CRCSTATUS_CRCSTATUS_Msk (0x1UL << RADIO_CRCSTATUS_CRCSTATUS_Pos) /*!< Bit mask of CRCSTATUS field. */
+#define RADIO_CRCSTATUS_CRCSTATUS_CRCError (0UL) /*!< Packet received with CRC error. */
+#define RADIO_CRCSTATUS_CRCSTATUS_CRCOk (1UL) /*!< Packet received with CRC ok. */
+
+/* Register: RADIO_RXMATCH */
+/* Description: Received address. */
+
+/* Bits 2..0 : Logical address in which previous packet was received. */
+#define RADIO_RXMATCH_RXMATCH_Pos (0UL) /*!< Position of RXMATCH field. */
+#define RADIO_RXMATCH_RXMATCH_Msk (0x7UL << RADIO_RXMATCH_RXMATCH_Pos) /*!< Bit mask of RXMATCH field. */
+
+/* Register: RADIO_RXCRC */
+/* Description: Received CRC. */
+
+/* Bits 23..0 : CRC field of previously received packet. */
+#define RADIO_RXCRC_RXCRC_Pos (0UL) /*!< Position of RXCRC field. */
+#define RADIO_RXCRC_RXCRC_Msk (0xFFFFFFUL << RADIO_RXCRC_RXCRC_Pos) /*!< Bit mask of RXCRC field. */
+
+/* Register: RADIO_DAI */
+/* Description: Device address match index. */
+
+/* Bits 2..0 : Index (n) of device address (see DAB[n] and DAP[n]) that obtained an address match. */
+#define RADIO_DAI_DAI_Pos (0UL) /*!< Position of DAI field. */
+#define RADIO_DAI_DAI_Msk (0x7UL << RADIO_DAI_DAI_Pos) /*!< Bit mask of DAI field. */
+
+/* Register: RADIO_FREQUENCY */
+/* Description: Frequency. */
+
+/* Bits 6..0 : Radio channel frequency offset in MHz: RF Frequency = 2400 + FREQUENCY (MHz). Decision point: TXEN or RXEN task.  */
+#define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+
+/* Register: RADIO_TXPOWER */
+/* Description: Output power. */
+
+/* Bits 7..0 : Radio output power. Decision point: TXEN task. */
+#define RADIO_TXPOWER_TXPOWER_Pos (0UL) /*!< Position of TXPOWER field. */
+#define RADIO_TXPOWER_TXPOWER_Msk (0xFFUL << RADIO_TXPOWER_TXPOWER_Pos) /*!< Bit mask of TXPOWER field. */
+#define RADIO_TXPOWER_TXPOWER_0dBm (0x00UL) /*!< 0dBm. */
+#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x04UL) /*!< +4dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg30dBm (0xD8UL) /*!< -30dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8dBm. */
+#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4dBm. */
+
+/* Register: RADIO_MODE */
+/* Description: Data rate and modulation. */
+
+/* Bits 1..0 : Radio data rate and modulation setting. Decision point: TXEN or RXEN task. */
+#define RADIO_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define RADIO_MODE_MODE_Msk (0x3UL << RADIO_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define RADIO_MODE_MODE_Nrf_1Mbit (0x00UL) /*!< 1Mbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Nrf_2Mbit (0x01UL) /*!< 2Mbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Nrf_250Kbit (0x02UL) /*!< 250kbit/s Nordic propietary radio mode. */
+#define RADIO_MODE_MODE_Ble_1Mbit (0x03UL) /*!< 1Mbit/s Bluetooth Low Energy */
+
+/* Register: RADIO_PCNF0 */
+/* Description: Packet configuration 0. */
+
+/* Bits 19..16 : Length of S1 field in number of bits. Decision point: START task. */
+#define RADIO_PCNF0_S1LEN_Pos (16UL) /*!< Position of S1LEN field. */
+#define RADIO_PCNF0_S1LEN_Msk (0xFUL << RADIO_PCNF0_S1LEN_Pos) /*!< Bit mask of S1LEN field. */
+
+/* Bit 8 : Length of S0 field in number of bytes. Decision point: START task. */
+#define RADIO_PCNF0_S0LEN_Pos (8UL) /*!< Position of S0LEN field. */
+#define RADIO_PCNF0_S0LEN_Msk (0x1UL << RADIO_PCNF0_S0LEN_Pos) /*!< Bit mask of S0LEN field. */
+
+/* Bits 3..0 : Length of length field in number of bits. Decision point: START task. */
+#define RADIO_PCNF0_LFLEN_Pos (0UL) /*!< Position of LFLEN field. */
+#define RADIO_PCNF0_LFLEN_Msk (0xFUL << RADIO_PCNF0_LFLEN_Pos) /*!< Bit mask of LFLEN field. */
+
+/* Register: RADIO_PCNF1 */
+/* Description: Packet configuration 1. */
+
+/* Bit 25 : Packet whitening enable. */
+#define RADIO_PCNF1_WHITEEN_Pos (25UL) /*!< Position of WHITEEN field. */
+#define RADIO_PCNF1_WHITEEN_Msk (0x1UL << RADIO_PCNF1_WHITEEN_Pos) /*!< Bit mask of WHITEEN field. */
+#define RADIO_PCNF1_WHITEEN_Disabled (0UL) /*!< Whitening disabled. */
+#define RADIO_PCNF1_WHITEEN_Enabled (1UL) /*!< Whitening enabled. */
+
+/* Bit 24 : On air endianness of packet length field. Decision point: START task. */
+#define RADIO_PCNF1_ENDIAN_Pos (24UL) /*!< Position of ENDIAN field. */
+#define RADIO_PCNF1_ENDIAN_Msk (0x1UL << RADIO_PCNF1_ENDIAN_Pos) /*!< Bit mask of ENDIAN field. */
+#define RADIO_PCNF1_ENDIAN_Little (0UL) /*!< Least significant bit on air first */
+#define RADIO_PCNF1_ENDIAN_Big (1UL) /*!< Most significant bit on air first */
+
+/* Bits 18..16 : Base address length in number of bytes. Decision point: START task. */
+#define RADIO_PCNF1_BALEN_Pos (16UL) /*!< Position of BALEN field. */
+#define RADIO_PCNF1_BALEN_Msk (0x7UL << RADIO_PCNF1_BALEN_Pos) /*!< Bit mask of BALEN field. */
+
+/* Bits 15..8 : Static length in number of bytes. Decision point: START task. */
+#define RADIO_PCNF1_STATLEN_Pos (8UL) /*!< Position of STATLEN field. */
+#define RADIO_PCNF1_STATLEN_Msk (0xFFUL << RADIO_PCNF1_STATLEN_Pos) /*!< Bit mask of STATLEN field. */
+
+/* Bits 7..0 : Maximum length of packet payload in number of bytes. */
+#define RADIO_PCNF1_MAXLEN_Pos (0UL) /*!< Position of MAXLEN field. */
+#define RADIO_PCNF1_MAXLEN_Msk (0xFFUL << RADIO_PCNF1_MAXLEN_Pos) /*!< Bit mask of MAXLEN field. */
+
+/* Register: RADIO_PREFIX0 */
+/* Description: Prefixes bytes for logical addresses 0 to 3. */
+
+/* Bits 31..24 : Address prefix 3. Decision point: START task. */
+#define RADIO_PREFIX0_AP3_Pos (24UL) /*!< Position of AP3 field. */
+#define RADIO_PREFIX0_AP3_Msk (0xFFUL << RADIO_PREFIX0_AP3_Pos) /*!< Bit mask of AP3 field. */
+
+/* Bits 23..16 : Address prefix 2. Decision point: START task. */
+#define RADIO_PREFIX0_AP2_Pos (16UL) /*!< Position of AP2 field. */
+#define RADIO_PREFIX0_AP2_Msk (0xFFUL << RADIO_PREFIX0_AP2_Pos) /*!< Bit mask of AP2 field. */
+
+/* Bits 15..8 : Address prefix 1. Decision point: START task. */
+#define RADIO_PREFIX0_AP1_Pos (8UL) /*!< Position of AP1 field. */
+#define RADIO_PREFIX0_AP1_Msk (0xFFUL << RADIO_PREFIX0_AP1_Pos) /*!< Bit mask of AP1 field. */
+
+/* Bits 7..0 : Address prefix 0. Decision point: START task. */
+#define RADIO_PREFIX0_AP0_Pos (0UL) /*!< Position of AP0 field. */
+#define RADIO_PREFIX0_AP0_Msk (0xFFUL << RADIO_PREFIX0_AP0_Pos) /*!< Bit mask of AP0 field. */
+
+/* Register: RADIO_PREFIX1 */
+/* Description: Prefixes bytes for logical addresses 4 to 7. */
+
+/* Bits 31..24 : Address prefix 7. Decision point: START task. */
+#define RADIO_PREFIX1_AP7_Pos (24UL) /*!< Position of AP7 field. */
+#define RADIO_PREFIX1_AP7_Msk (0xFFUL << RADIO_PREFIX1_AP7_Pos) /*!< Bit mask of AP7 field. */
+
+/* Bits 23..16 : Address prefix 6. Decision point: START task. */
+#define RADIO_PREFIX1_AP6_Pos (16UL) /*!< Position of AP6 field. */
+#define RADIO_PREFIX1_AP6_Msk (0xFFUL << RADIO_PREFIX1_AP6_Pos) /*!< Bit mask of AP6 field. */
+
+/* Bits 15..8 : Address prefix 5. Decision point: START task. */
+#define RADIO_PREFIX1_AP5_Pos (8UL) /*!< Position of AP5 field. */
+#define RADIO_PREFIX1_AP5_Msk (0xFFUL << RADIO_PREFIX1_AP5_Pos) /*!< Bit mask of AP5 field. */
+
+/* Bits 7..0 : Address prefix 4. Decision point: START task. */
+#define RADIO_PREFIX1_AP4_Pos (0UL) /*!< Position of AP4 field. */
+#define RADIO_PREFIX1_AP4_Msk (0xFFUL << RADIO_PREFIX1_AP4_Pos) /*!< Bit mask of AP4 field. */
+
+/* Register: RADIO_TXADDRESS */
+/* Description: Transmit address select. */
+
+/* Bits 2..0 : Logical address to be used when transmitting a packet. Decision point: START task. */
+#define RADIO_TXADDRESS_TXADDRESS_Pos (0UL) /*!< Position of TXADDRESS field. */
+#define RADIO_TXADDRESS_TXADDRESS_Msk (0x7UL << RADIO_TXADDRESS_TXADDRESS_Pos) /*!< Bit mask of TXADDRESS field. */
+
+/* Register: RADIO_RXADDRESSES */
+/* Description: Receive address select. */
+
+/* Bit 7 : Enable reception on logical address 7. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR7_Pos (7UL) /*!< Position of ADDR7 field. */
+#define RADIO_RXADDRESSES_ADDR7_Msk (0x1UL << RADIO_RXADDRESSES_ADDR7_Pos) /*!< Bit mask of ADDR7 field. */
+#define RADIO_RXADDRESSES_ADDR7_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR7_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 6 : Enable reception on logical address 6. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR6_Pos (6UL) /*!< Position of ADDR6 field. */
+#define RADIO_RXADDRESSES_ADDR6_Msk (0x1UL << RADIO_RXADDRESSES_ADDR6_Pos) /*!< Bit mask of ADDR6 field. */
+#define RADIO_RXADDRESSES_ADDR6_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR6_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 5 : Enable reception on logical address 5. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR5_Pos (5UL) /*!< Position of ADDR5 field. */
+#define RADIO_RXADDRESSES_ADDR5_Msk (0x1UL << RADIO_RXADDRESSES_ADDR5_Pos) /*!< Bit mask of ADDR5 field. */
+#define RADIO_RXADDRESSES_ADDR5_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR5_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 4 : Enable reception on logical address 4. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR4_Pos (4UL) /*!< Position of ADDR4 field. */
+#define RADIO_RXADDRESSES_ADDR4_Msk (0x1UL << RADIO_RXADDRESSES_ADDR4_Pos) /*!< Bit mask of ADDR4 field. */
+#define RADIO_RXADDRESSES_ADDR4_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR4_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 3 : Enable reception on logical address 3. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR3_Pos (3UL) /*!< Position of ADDR3 field. */
+#define RADIO_RXADDRESSES_ADDR3_Msk (0x1UL << RADIO_RXADDRESSES_ADDR3_Pos) /*!< Bit mask of ADDR3 field. */
+#define RADIO_RXADDRESSES_ADDR3_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR3_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 2 : Enable reception on logical address 2. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR2_Pos (2UL) /*!< Position of ADDR2 field. */
+#define RADIO_RXADDRESSES_ADDR2_Msk (0x1UL << RADIO_RXADDRESSES_ADDR2_Pos) /*!< Bit mask of ADDR2 field. */
+#define RADIO_RXADDRESSES_ADDR2_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR2_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 1 : Enable reception on logical address 1. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR1_Pos (1UL) /*!< Position of ADDR1 field. */
+#define RADIO_RXADDRESSES_ADDR1_Msk (0x1UL << RADIO_RXADDRESSES_ADDR1_Pos) /*!< Bit mask of ADDR1 field. */
+#define RADIO_RXADDRESSES_ADDR1_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR1_Enabled (1UL) /*!< Reception enabled. */
+
+/* Bit 0 : Enable reception on logical address 0. Decision point: START task. */
+#define RADIO_RXADDRESSES_ADDR0_Pos (0UL) /*!< Position of ADDR0 field. */
+#define RADIO_RXADDRESSES_ADDR0_Msk (0x1UL << RADIO_RXADDRESSES_ADDR0_Pos) /*!< Bit mask of ADDR0 field. */
+#define RADIO_RXADDRESSES_ADDR0_Disabled (0UL) /*!< Reception disabled. */
+#define RADIO_RXADDRESSES_ADDR0_Enabled (1UL) /*!< Reception enabled. */
+
+/* Register: RADIO_CRCCNF */
+/* Description: CRC configuration. */
+
+/* Bit 8 : Leave packet address field out of the CRC calculation. Decision point: START task. */
+#define RADIO_CRCCNF_SKIPADDR_Pos (8UL) /*!< Position of SKIPADDR field. */
+#define RADIO_CRCCNF_SKIPADDR_Msk (0x1UL << RADIO_CRCCNF_SKIPADDR_Pos) /*!< Bit mask of SKIPADDR field. */
+#define RADIO_CRCCNF_SKIPADDR_Include (0UL) /*!< Include packet address in CRC calculation. */
+#define RADIO_CRCCNF_SKIPADDR_Skip (1UL) /*!< Packet address is skipped in CRC calculation. The CRC calculation will start at the first byte after the address. */
+
+/* Bits 1..0 : CRC length. Decision point: START task. */
+#define RADIO_CRCCNF_LEN_Pos (0UL) /*!< Position of LEN field. */
+#define RADIO_CRCCNF_LEN_Msk (0x3UL << RADIO_CRCCNF_LEN_Pos) /*!< Bit mask of LEN field. */
+#define RADIO_CRCCNF_LEN_Disabled (0UL) /*!< CRC calculation disabled. */
+#define RADIO_CRCCNF_LEN_One (1UL) /*!< One byte long CRC. */
+#define RADIO_CRCCNF_LEN_Two (2UL) /*!< Two bytes long CRC. */
+#define RADIO_CRCCNF_LEN_Three (3UL) /*!< Three bytes long CRC. */
+
+/* Register: RADIO_CRCPOLY */
+/* Description: CRC polynomial. */
+
+/* Bits 23..0 : CRC polynomial. Decision point: START task. */
+#define RADIO_CRCPOLY_CRCPOLY_Pos (0UL) /*!< Position of CRCPOLY field. */
+#define RADIO_CRCPOLY_CRCPOLY_Msk (0xFFFFFFUL << RADIO_CRCPOLY_CRCPOLY_Pos) /*!< Bit mask of CRCPOLY field. */
+
+/* Register: RADIO_CRCINIT */
+/* Description: CRC initial value. */
+
+/* Bits 23..0 : Initial value for CRC calculation. Decision point: START task. */
+#define RADIO_CRCINIT_CRCINIT_Pos (0UL) /*!< Position of CRCINIT field. */
+#define RADIO_CRCINIT_CRCINIT_Msk (0xFFFFFFUL << RADIO_CRCINIT_CRCINIT_Pos) /*!< Bit mask of CRCINIT field. */
+
+/* Register: RADIO_TEST */
+/* Description: Test features enable register. */
+
+/* Bit 1 : PLL lock. Decision point: TXEN or RXEN task. */
+#define RADIO_TEST_PLLLOCK_Pos (1UL) /*!< Position of PLLLOCK field. */
+#define RADIO_TEST_PLLLOCK_Msk (0x1UL << RADIO_TEST_PLLLOCK_Pos) /*!< Bit mask of PLLLOCK field. */
+#define RADIO_TEST_PLLLOCK_Disabled (0UL) /*!< PLL lock disabled. */
+#define RADIO_TEST_PLLLOCK_Enabled (1UL) /*!< PLL lock enabled. */
+
+/* Bit 0 : Constant carrier. Decision point: TXEN task. */
+#define RADIO_TEST_CONSTCARRIER_Pos (0UL) /*!< Position of CONSTCARRIER field. */
+#define RADIO_TEST_CONSTCARRIER_Msk (0x1UL << RADIO_TEST_CONSTCARRIER_Pos) /*!< Bit mask of CONSTCARRIER field. */
+#define RADIO_TEST_CONSTCARRIER_Disabled (0UL) /*!< Constant carrier disabled. */
+#define RADIO_TEST_CONSTCARRIER_Enabled (1UL) /*!< Constant carrier enabled. */
+
+/* Register: RADIO_TIFS */
+/* Description: Inter Frame Spacing in microseconds. */
+
+/* Bits 7..0 : Inter frame spacing in microseconds. Decision point: START rask */
+#define RADIO_TIFS_TIFS_Pos (0UL) /*!< Position of TIFS field. */
+#define RADIO_TIFS_TIFS_Msk (0xFFUL << RADIO_TIFS_TIFS_Pos) /*!< Bit mask of TIFS field. */
+
+/* Register: RADIO_RSSISAMPLE */
+/* Description: RSSI sample. */
+
+/* Bits 6..0 : RSSI sample result. The result is read as a positive value so that ReceivedSignalStrength = -RSSISAMPLE dBm */
+#define RADIO_RSSISAMPLE_RSSISAMPLE_Pos (0UL) /*!< Position of RSSISAMPLE field. */
+#define RADIO_RSSISAMPLE_RSSISAMPLE_Msk (0x7FUL << RADIO_RSSISAMPLE_RSSISAMPLE_Pos) /*!< Bit mask of RSSISAMPLE field. */
+
+/* Register: RADIO_STATE */
+/* Description: Current radio state. */
+
+/* Bits 3..0 : Current radio state. */
+#define RADIO_STATE_STATE_Pos (0UL) /*!< Position of STATE field. */
+#define RADIO_STATE_STATE_Msk (0xFUL << RADIO_STATE_STATE_Pos) /*!< Bit mask of STATE field. */
+#define RADIO_STATE_STATE_Disabled (0x00UL) /*!< Radio is in the Disabled state. */
+#define RADIO_STATE_STATE_RxRu (0x01UL) /*!< Radio is in the Rx Ramp Up state. */
+#define RADIO_STATE_STATE_RxIdle (0x02UL) /*!< Radio is in the Rx Idle state. */
+#define RADIO_STATE_STATE_Rx (0x03UL) /*!< Radio is in the Rx state. */
+#define RADIO_STATE_STATE_RxDisable (0x04UL) /*!< Radio is in the Rx Disable state. */
+#define RADIO_STATE_STATE_TxRu (0x09UL) /*!< Radio is in the Tx Ramp Up state. */
+#define RADIO_STATE_STATE_TxIdle (0x0AUL) /*!< Radio is in the Tx Idle state. */
+#define RADIO_STATE_STATE_Tx (0x0BUL) /*!< Radio is in the Tx state. */
+#define RADIO_STATE_STATE_TxDisable (0x0CUL) /*!< Radio is in the Tx Disable state. */
+
+/* Register: RADIO_DATAWHITEIV */
+/* Description: Data whitening initial value. */
+
+/* Bits 6..0 : Data whitening initial value. Bit 0 corresponds to Position 0 of the LSFR, Bit 1 to position 5... Decision point: TXEN or RXEN task. */
+#define RADIO_DATAWHITEIV_DATAWHITEIV_Pos (0UL) /*!< Position of DATAWHITEIV field. */
+#define RADIO_DATAWHITEIV_DATAWHITEIV_Msk (0x7FUL << RADIO_DATAWHITEIV_DATAWHITEIV_Pos) /*!< Bit mask of DATAWHITEIV field. */
+
+/* Register: RADIO_DAP */
+/* Description: Device address prefix. */
+
+/* Bits 15..0 : Device address prefix. */
+#define RADIO_DAP_DAP_Pos (0UL) /*!< Position of DAP field. */
+#define RADIO_DAP_DAP_Msk (0xFFFFUL << RADIO_DAP_DAP_Pos) /*!< Bit mask of DAP field. */
+
+/* Register: RADIO_DACNF */
+/* Description: Device address match configuration. */
+
+/* Bit 15 : TxAdd for device address 7. */
+#define RADIO_DACNF_TXADD7_Pos (15UL) /*!< Position of TXADD7 field. */
+#define RADIO_DACNF_TXADD7_Msk (0x1UL << RADIO_DACNF_TXADD7_Pos) /*!< Bit mask of TXADD7 field. */
+
+/* Bit 14 : TxAdd for device address 6. */
+#define RADIO_DACNF_TXADD6_Pos (14UL) /*!< Position of TXADD6 field. */
+#define RADIO_DACNF_TXADD6_Msk (0x1UL << RADIO_DACNF_TXADD6_Pos) /*!< Bit mask of TXADD6 field. */
+
+/* Bit 13 : TxAdd for device address 5. */
+#define RADIO_DACNF_TXADD5_Pos (13UL) /*!< Position of TXADD5 field. */
+#define RADIO_DACNF_TXADD5_Msk (0x1UL << RADIO_DACNF_TXADD5_Pos) /*!< Bit mask of TXADD5 field. */
+
+/* Bit 12 : TxAdd for device address 4. */
+#define RADIO_DACNF_TXADD4_Pos (12UL) /*!< Position of TXADD4 field. */
+#define RADIO_DACNF_TXADD4_Msk (0x1UL << RADIO_DACNF_TXADD4_Pos) /*!< Bit mask of TXADD4 field. */
+
+/* Bit 11 : TxAdd for device address 3. */
+#define RADIO_DACNF_TXADD3_Pos (11UL) /*!< Position of TXADD3 field. */
+#define RADIO_DACNF_TXADD3_Msk (0x1UL << RADIO_DACNF_TXADD3_Pos) /*!< Bit mask of TXADD3 field. */
+
+/* Bit 10 : TxAdd for device address 2. */
+#define RADIO_DACNF_TXADD2_Pos (10UL) /*!< Position of TXADD2 field. */
+#define RADIO_DACNF_TXADD2_Msk (0x1UL << RADIO_DACNF_TXADD2_Pos) /*!< Bit mask of TXADD2 field. */
+
+/* Bit 9 : TxAdd for device address 1. */
+#define RADIO_DACNF_TXADD1_Pos (9UL) /*!< Position of TXADD1 field. */
+#define RADIO_DACNF_TXADD1_Msk (0x1UL << RADIO_DACNF_TXADD1_Pos) /*!< Bit mask of TXADD1 field. */
+
+/* Bit 8 : TxAdd for device address 0. */
+#define RADIO_DACNF_TXADD0_Pos (8UL) /*!< Position of TXADD0 field. */
+#define RADIO_DACNF_TXADD0_Msk (0x1UL << RADIO_DACNF_TXADD0_Pos) /*!< Bit mask of TXADD0 field. */
+
+/* Bit 7 : Enable or disable device address matching using device address 7. */
+#define RADIO_DACNF_ENA7_Pos (7UL) /*!< Position of ENA7 field. */
+#define RADIO_DACNF_ENA7_Msk (0x1UL << RADIO_DACNF_ENA7_Pos) /*!< Bit mask of ENA7 field. */
+#define RADIO_DACNF_ENA7_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA7_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 6 : Enable or disable device address matching using device address 6. */
+#define RADIO_DACNF_ENA6_Pos (6UL) /*!< Position of ENA6 field. */
+#define RADIO_DACNF_ENA6_Msk (0x1UL << RADIO_DACNF_ENA6_Pos) /*!< Bit mask of ENA6 field. */
+#define RADIO_DACNF_ENA6_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA6_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 5 : Enable or disable device address matching using device address 5. */
+#define RADIO_DACNF_ENA5_Pos (5UL) /*!< Position of ENA5 field. */
+#define RADIO_DACNF_ENA5_Msk (0x1UL << RADIO_DACNF_ENA5_Pos) /*!< Bit mask of ENA5 field. */
+#define RADIO_DACNF_ENA5_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA5_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 4 : Enable or disable device address matching using device address 4. */
+#define RADIO_DACNF_ENA4_Pos (4UL) /*!< Position of ENA4 field. */
+#define RADIO_DACNF_ENA4_Msk (0x1UL << RADIO_DACNF_ENA4_Pos) /*!< Bit mask of ENA4 field. */
+#define RADIO_DACNF_ENA4_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA4_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 3 : Enable or disable device address matching using device address 3. */
+#define RADIO_DACNF_ENA3_Pos (3UL) /*!< Position of ENA3 field. */
+#define RADIO_DACNF_ENA3_Msk (0x1UL << RADIO_DACNF_ENA3_Pos) /*!< Bit mask of ENA3 field. */
+#define RADIO_DACNF_ENA3_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA3_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 2 : Enable or disable device address matching using device address 2. */
+#define RADIO_DACNF_ENA2_Pos (2UL) /*!< Position of ENA2 field. */
+#define RADIO_DACNF_ENA2_Msk (0x1UL << RADIO_DACNF_ENA2_Pos) /*!< Bit mask of ENA2 field. */
+#define RADIO_DACNF_ENA2_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA2_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 1 : Enable or disable device address matching using device address 1. */
+#define RADIO_DACNF_ENA1_Pos (1UL) /*!< Position of ENA1 field. */
+#define RADIO_DACNF_ENA1_Msk (0x1UL << RADIO_DACNF_ENA1_Pos) /*!< Bit mask of ENA1 field. */
+#define RADIO_DACNF_ENA1_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA1_Enabled (1UL) /*!< Enabled. */
+
+/* Bit 0 : Enable or disable device address matching using device address 0. */
+#define RADIO_DACNF_ENA0_Pos (0UL) /*!< Position of ENA0 field. */
+#define RADIO_DACNF_ENA0_Msk (0x1UL << RADIO_DACNF_ENA0_Pos) /*!< Bit mask of ENA0 field. */
+#define RADIO_DACNF_ENA0_Disabled (0UL) /*!< Disabled. */
+#define RADIO_DACNF_ENA0_Enabled (1UL) /*!< Enabled. */
+
+/* Register: RADIO_OVERRIDE0 */
+/* Description: Trim value override register 0. */
+
+/* Bits 31..0 : Trim value override 0. */
+#define RADIO_OVERRIDE0_OVERRIDE0_Pos (0UL) /*!< Position of OVERRIDE0 field. */
+#define RADIO_OVERRIDE0_OVERRIDE0_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE0_OVERRIDE0_Pos) /*!< Bit mask of OVERRIDE0 field. */
+
+/* Register: RADIO_OVERRIDE1 */
+/* Description: Trim value override register 1. */
+
+/* Bits 31..0 : Trim value override 1. */
+#define RADIO_OVERRIDE1_OVERRIDE1_Pos (0UL) /*!< Position of OVERRIDE1 field. */
+#define RADIO_OVERRIDE1_OVERRIDE1_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE1_OVERRIDE1_Pos) /*!< Bit mask of OVERRIDE1 field. */
+
+/* Register: RADIO_OVERRIDE2 */
+/* Description: Trim value override register 2. */
+
+/* Bits 31..0 : Trim value override 2. */
+#define RADIO_OVERRIDE2_OVERRIDE2_Pos (0UL) /*!< Position of OVERRIDE2 field. */
+#define RADIO_OVERRIDE2_OVERRIDE2_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE2_OVERRIDE2_Pos) /*!< Bit mask of OVERRIDE2 field. */
+
+/* Register: RADIO_OVERRIDE3 */
+/* Description: Trim value override register 3. */
+
+/* Bits 31..0 : Trim value override 3. */
+#define RADIO_OVERRIDE3_OVERRIDE3_Pos (0UL) /*!< Position of OVERRIDE3 field. */
+#define RADIO_OVERRIDE3_OVERRIDE3_Msk (0xFFFFFFFFUL << RADIO_OVERRIDE3_OVERRIDE3_Pos) /*!< Bit mask of OVERRIDE3 field. */
+
+/* Register: RADIO_OVERRIDE4 */
+/* Description: Trim value override register 4. */
+
+/* Bit 31 : Enable or disable override of default trim values. */
+#define RADIO_OVERRIDE4_ENABLE_Pos (31UL) /*!< Position of ENABLE field. */
+#define RADIO_OVERRIDE4_ENABLE_Msk (0x1UL << RADIO_OVERRIDE4_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define RADIO_OVERRIDE4_ENABLE_Disabled (0UL) /*!< Override trim values disabled. */
+#define RADIO_OVERRIDE4_ENABLE_Enabled (1UL) /*!< Override trim values enabled. */
+
+/* Bits 27..0 : Trim value override 4. */
+#define RADIO_OVERRIDE4_OVERRIDE4_Pos (0UL) /*!< Position of OVERRIDE4 field. */
+#define RADIO_OVERRIDE4_OVERRIDE4_Msk (0xFFFFFFFUL << RADIO_OVERRIDE4_OVERRIDE4_Pos) /*!< Bit mask of OVERRIDE4 field. */
+
+/* Register: RADIO_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RADIO_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RADIO_POWER_POWER_Msk (0x1UL << RADIO_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RADIO_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RADIO_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RNG */
+/* Description: Random Number Generator. */
+
+/* Register: RNG_SHORTS */
+/* Description: Shortcuts for the RNG. */
+
+/* Bit 0 : Shortcut between VALRDY event and STOP task. */
+#define RNG_SHORTS_VALRDY_STOP_Pos (0UL) /*!< Position of VALRDY_STOP field. */
+#define RNG_SHORTS_VALRDY_STOP_Msk (0x1UL << RNG_SHORTS_VALRDY_STOP_Pos) /*!< Bit mask of VALRDY_STOP field. */
+#define RNG_SHORTS_VALRDY_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define RNG_SHORTS_VALRDY_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: RNG_INTENSET */
+/* Description: Interrupt enable set register */
+
+/* Bit 0 : Enable interrupt on VALRDY event. */
+#define RNG_INTENSET_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */
+#define RNG_INTENSET_VALRDY_Msk (0x1UL << RNG_INTENSET_VALRDY_Pos) /*!< Bit mask of VALRDY field. */
+#define RNG_INTENSET_VALRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RNG_INTENSET_VALRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RNG_INTENSET_VALRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RNG_INTENCLR */
+/* Description: Interrupt enable clear register */
+
+/* Bit 0 : Disable interrupt on VALRDY event. */
+#define RNG_INTENCLR_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */
+#define RNG_INTENCLR_VALRDY_Msk (0x1UL << RNG_INTENCLR_VALRDY_Pos) /*!< Bit mask of VALRDY field. */
+#define RNG_INTENCLR_VALRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define RNG_INTENCLR_VALRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define RNG_INTENCLR_VALRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RNG_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 0 : Digital error correction enable. */
+#define RNG_CONFIG_DERCEN_Pos (0UL) /*!< Position of DERCEN field. */
+#define RNG_CONFIG_DERCEN_Msk (0x1UL << RNG_CONFIG_DERCEN_Pos) /*!< Bit mask of DERCEN field. */
+#define RNG_CONFIG_DERCEN_Disabled (0UL) /*!< Digital error correction disabled. */
+#define RNG_CONFIG_DERCEN_Enabled (1UL) /*!< Digital error correction enabled. */
+
+/* Register: RNG_VALUE */
+/* Description: RNG random number. */
+
+/* Bits 7..0 : Generated random number. */
+#define RNG_VALUE_VALUE_Pos (0UL) /*!< Position of VALUE field. */
+#define RNG_VALUE_VALUE_Msk (0xFFUL << RNG_VALUE_VALUE_Pos) /*!< Bit mask of VALUE field. */
+
+/* Register: RNG_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RNG_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RNG_POWER_POWER_Msk (0x1UL << RNG_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RNG_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RNG_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: RTC */
+/* Description: Real time counter 0. */
+
+/* Register: RTC_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on COMPARE[3] event. */
+#define RTC_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_INTENSET_COMPARE3_Msk (0x1UL << RTC_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_INTENSET_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 18 : Enable interrupt on COMPARE[2] event. */
+#define RTC_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_INTENSET_COMPARE2_Msk (0x1UL << RTC_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_INTENSET_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 17 : Enable interrupt on COMPARE[1] event. */
+#define RTC_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_INTENSET_COMPARE1_Msk (0x1UL << RTC_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_INTENSET_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 16 : Enable interrupt on COMPARE[0] event. */
+#define RTC_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_INTENSET_COMPARE0_Msk (0x1UL << RTC_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_INTENSET_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_COMPARE0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on OVRFLW event. */
+#define RTC_INTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_INTENSET_OVRFLW_Msk (0x1UL << RTC_INTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_INTENSET_OVRFLW_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_OVRFLW_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_OVRFLW_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on TICK event. */
+#define RTC_INTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_INTENSET_TICK_Msk (0x1UL << RTC_INTENSET_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_INTENSET_TICK_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENSET_TICK_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENSET_TICK_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: RTC_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on COMPARE[3] event. */
+#define RTC_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_INTENCLR_COMPARE3_Msk (0x1UL << RTC_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_INTENCLR_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 18 : Disable interrupt on COMPARE[2] event. */
+#define RTC_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_INTENCLR_COMPARE2_Msk (0x1UL << RTC_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_INTENCLR_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 17 : Disable interrupt on COMPARE[1] event. */
+#define RTC_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_INTENCLR_COMPARE1_Msk (0x1UL << RTC_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_INTENCLR_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 16 : Disable interrupt on COMPARE[0] event. */
+#define RTC_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_INTENCLR_COMPARE0_Msk (0x1UL << RTC_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_INTENCLR_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on OVRFLW event. */
+#define RTC_INTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_INTENCLR_OVRFLW_Msk (0x1UL << RTC_INTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_INTENCLR_OVRFLW_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_OVRFLW_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_OVRFLW_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on TICK event. */
+#define RTC_INTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_INTENCLR_TICK_Msk (0x1UL << RTC_INTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_INTENCLR_TICK_Disabled (0UL) /*!< Interrupt disabled. */
+#define RTC_INTENCLR_TICK_Enabled (1UL) /*!< Interrupt enabled. */
+#define RTC_INTENCLR_TICK_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: RTC_EVTEN */
+/* Description: Configures event enable routing to PPI for each RTC event. */
+
+/* Bit 19 : COMPARE[3] event enable. */
+#define RTC_EVTEN_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTEN_COMPARE3_Msk (0x1UL << RTC_EVTEN_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTEN_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 18 : COMPARE[2] event enable. */
+#define RTC_EVTEN_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTEN_COMPARE2_Msk (0x1UL << RTC_EVTEN_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTEN_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 17 : COMPARE[1] event enable. */
+#define RTC_EVTEN_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTEN_COMPARE1_Msk (0x1UL << RTC_EVTEN_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTEN_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 16 : COMPARE[0] event enable. */
+#define RTC_EVTEN_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTEN_COMPARE0_Msk (0x1UL << RTC_EVTEN_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTEN_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 1 : OVRFLW event enable. */
+#define RTC_EVTEN_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTEN_OVRFLW_Msk (0x1UL << RTC_EVTEN_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTEN_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+
+/* Bit 0 : TICK event enable. */
+#define RTC_EVTEN_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTEN_TICK_Msk (0x1UL << RTC_EVTEN_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTEN_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTEN_TICK_Enabled (1UL) /*!< Event enabled. */
+
+/* Register: RTC_EVTENSET */
+/* Description: Enable events routing to PPI. The reading of this register gives the value of EVTEN. */
+
+/* Bit 19 : Enable routing to PPI of COMPARE[3] event. */
+#define RTC_EVTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTENSET_COMPARE3_Msk (0x1UL << RTC_EVTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTENSET_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE3_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 18 : Enable routing to PPI of COMPARE[2] event. */
+#define RTC_EVTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTENSET_COMPARE2_Msk (0x1UL << RTC_EVTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTENSET_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE2_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 17 : Enable routing to PPI of COMPARE[1] event. */
+#define RTC_EVTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTENSET_COMPARE1_Msk (0x1UL << RTC_EVTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTENSET_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE1_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 16 : Enable routing to PPI of COMPARE[0] event. */
+#define RTC_EVTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTENSET_COMPARE0_Msk (0x1UL << RTC_EVTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTENSET_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_COMPARE0_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 1 : Enable routing to PPI of OVRFLW event. */
+#define RTC_EVTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTENSET_OVRFLW_Msk (0x1UL << RTC_EVTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTENSET_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_OVRFLW_Set (1UL) /*!< Enable event on write. */
+
+/* Bit 0 : Enable routing to PPI of TICK event. */
+#define RTC_EVTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTENSET_TICK_Msk (0x1UL << RTC_EVTENSET_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTENSET_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENSET_TICK_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENSET_TICK_Set (1UL) /*!< Enable event on write. */
+
+/* Register: RTC_EVTENCLR */
+/* Description: Disable events routing to PPI. The reading of this register gives the value of EVTEN. */
+
+/* Bit 19 : Disable routing to PPI of COMPARE[3] event. */
+#define RTC_EVTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define RTC_EVTENCLR_COMPARE3_Msk (0x1UL << RTC_EVTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define RTC_EVTENCLR_COMPARE3_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE3_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE3_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 18 : Disable routing to PPI of COMPARE[2] event. */
+#define RTC_EVTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define RTC_EVTENCLR_COMPARE2_Msk (0x1UL << RTC_EVTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define RTC_EVTENCLR_COMPARE2_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE2_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE2_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 17 : Disable routing to PPI of COMPARE[1] event. */
+#define RTC_EVTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define RTC_EVTENCLR_COMPARE1_Msk (0x1UL << RTC_EVTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define RTC_EVTENCLR_COMPARE1_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE1_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE1_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 16 : Disable routing to PPI of COMPARE[0] event. */
+#define RTC_EVTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define RTC_EVTENCLR_COMPARE0_Msk (0x1UL << RTC_EVTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define RTC_EVTENCLR_COMPARE0_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_COMPARE0_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_COMPARE0_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 1 : Disable routing to PPI of OVRFLW event. */
+#define RTC_EVTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */
+#define RTC_EVTENCLR_OVRFLW_Msk (0x1UL << RTC_EVTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */
+#define RTC_EVTENCLR_OVRFLW_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_OVRFLW_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_OVRFLW_Clear (1UL) /*!< Disable event on write. */
+
+/* Bit 0 : Disable routing to PPI of TICK event. */
+#define RTC_EVTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */
+#define RTC_EVTENCLR_TICK_Msk (0x1UL << RTC_EVTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */
+#define RTC_EVTENCLR_TICK_Disabled (0UL) /*!< Event disabled. */
+#define RTC_EVTENCLR_TICK_Enabled (1UL) /*!< Event enabled. */
+#define RTC_EVTENCLR_TICK_Clear (1UL) /*!< Disable event on write. */
+
+/* Register: RTC_COUNTER */
+/* Description: Current COUNTER value. */
+
+/* Bits 23..0 : Counter value. */
+#define RTC_COUNTER_COUNTER_Pos (0UL) /*!< Position of COUNTER field. */
+#define RTC_COUNTER_COUNTER_Msk (0xFFFFFFUL << RTC_COUNTER_COUNTER_Pos) /*!< Bit mask of COUNTER field. */
+
+/* Register: RTC_PRESCALER */
+/* Description: 12-bit prescaler for COUNTER frequency (32768/(PRESCALER+1)). Must be written when RTC is STOPed. */
+
+/* Bits 11..0 : RTC PRESCALER value. */
+#define RTC_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */
+#define RTC_PRESCALER_PRESCALER_Msk (0xFFFUL << RTC_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */
+
+/* Register: RTC_CC */
+/* Description: Capture/compare registers. */
+
+/* Bits 23..0 : Compare value. */
+#define RTC_CC_COMPARE_Pos (0UL) /*!< Position of COMPARE field. */
+#define RTC_CC_COMPARE_Msk (0xFFFFFFUL << RTC_CC_COMPARE_Pos) /*!< Bit mask of COMPARE field. */
+
+/* Register: RTC_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define RTC_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define RTC_POWER_POWER_Msk (0x1UL << RTC_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define RTC_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define RTC_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: SPI */
+/* Description: SPI master 0. */
+
+/* Register: SPI_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 2 : Enable interrupt on READY event. */
+#define SPI_INTENSET_READY_Pos (2UL) /*!< Position of READY field. */
+#define SPI_INTENSET_READY_Msk (0x1UL << SPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */
+#define SPI_INTENSET_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPI_INTENSET_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPI_INTENSET_READY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPI_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 2 : Disable interrupt on READY event. */
+#define SPI_INTENCLR_READY_Pos (2UL) /*!< Position of READY field. */
+#define SPI_INTENCLR_READY_Msk (0x1UL << SPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */
+#define SPI_INTENCLR_READY_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPI_INTENCLR_READY_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPI_INTENCLR_READY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPI_ENABLE */
+/* Description: Enable SPI. */
+
+/* Bits 2..0 : Enable or disable SPI. */
+#define SPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPI_ENABLE_ENABLE_Msk (0x7UL << SPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPI_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPI. */
+#define SPI_ENABLE_ENABLE_Enabled (0x01UL) /*!< Enable SPI. */
+
+/* Register: SPI_RXD */
+/* Description: RX data. */
+
+/* Bits 7..0 : RX data from last transfer. */
+#define SPI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define SPI_RXD_RXD_Msk (0xFFUL << SPI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: SPI_TXD */
+/* Description: TX data. */
+
+/* Bits 7..0 : TX data for next transfer. */
+#define SPI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define SPI_TXD_TXD_Msk (0xFFUL << SPI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: SPI_FREQUENCY */
+/* Description: SPI frequency */
+
+/* Bits 31..0 : SPI data rate. */
+#define SPI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define SPI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define SPI_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125kbps. */
+#define SPI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250kbps. */
+#define SPI_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500kbps. */
+#define SPI_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4Mbps. */
+#define SPI_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8Mbps. */
+
+/* Register: SPI_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPI_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPI_CONFIG_CPOL_Msk (0x1UL << SPI_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPI_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPI_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPI_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPI_CONFIG_CPHA_Msk (0x1UL << SPI_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPI_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPI_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPI_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPI_CONFIG_ORDER_Msk (0x1UL << SPI_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPI_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPI_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPI_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPI_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPI_POWER_POWER_Msk (0x1UL << SPI_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPI_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPI_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: SPIM */
+/* Description: SPI master with easyDMA 1. */
+
+/* Register: SPIM_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on STARTED event. */
+#define SPIM_INTENSET_STARTED_Pos (19UL) /*!< Position of STARTED field. */
+#define SPIM_INTENSET_STARTED_Msk (0x1UL << SPIM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */
+#define SPIM_INTENSET_STARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_STARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_STARTED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 8 : Enable interrupt on ENDTX event. */
+#define SPIM_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */
+#define SPIM_INTENSET_ENDTX_Msk (0x1UL << SPIM_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */
+#define SPIM_INTENSET_ENDTX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 4 : Enable interrupt on ENDRX event. */
+#define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIM_INTENSET_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_ENDRX_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on STOPPED event. */
+#define SPIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define SPIM_INTENSET_STOPPED_Msk (0x1UL << SPIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define SPIM_INTENSET_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENSET_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENSET_STOPPED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPIM_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on STARTED event. */
+#define SPIM_INTENCLR_STARTED_Pos (19UL) /*!< Position of STARTED field. */
+#define SPIM_INTENCLR_STARTED_Msk (0x1UL << SPIM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */
+#define SPIM_INTENCLR_STARTED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_STARTED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_STARTED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 8 : Disable interrupt on ENDTX event. */
+#define SPIM_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */
+#define SPIM_INTENCLR_ENDTX_Msk (0x1UL << SPIM_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */
+#define SPIM_INTENCLR_ENDTX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 4 : Disable interrupt on ENDRX event. */
+#define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIM_INTENCLR_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_ENDRX_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on STOPPED event. */
+#define SPIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define SPIM_INTENCLR_STOPPED_Msk (0x1UL << SPIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define SPIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPIM_ENABLE */
+/* Description: Enable SPIM. */
+
+/* Bits 3..0 : Enable or disable SPIM. */
+#define SPIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPIM_ENABLE_ENABLE_Msk (0xFUL << SPIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPIM_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPIM. */
+#define SPIM_ENABLE_ENABLE_Enabled (0x07UL) /*!< Enable SPIM. */
+
+/* Register: SPIM_FREQUENCY */
+/* Description: SPI frequency. */
+
+/* Bits 31..0 : SPI master data rate. */
+#define SPIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define SPIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define SPIM_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps. */
+#define SPIM_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps. */
+
+/* Register: SPIM_RXD_PTR */
+/* Description: Data pointer. */
+
+/* Bits 31..0 : Data pointer. */
+#define SPIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
+#define SPIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
+
+/* Register: SPIM_RXD_MAXCNT */
+/* Description: Maximum number of buffer bytes to receive. */
+
+/* Bits 7..0 : Maximum number of buffer bytes to receive. */
+#define SPIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
+#define SPIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
+
+/* Register: SPIM_RXD_AMOUNT */
+/* Description: Number of bytes received in the last transaction. */
+
+/* Bits 7..0 : Number of bytes received in the last transaction. */
+#define SPIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
+#define SPIM_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
+
+/* Register: SPIM_TXD_PTR */
+/* Description: Data pointer. */
+
+/* Bits 31..0 : Data pointer. */
+#define SPIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */
+#define SPIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */
+
+/* Register: SPIM_TXD_MAXCNT */
+/* Description: Maximum number of buffer bytes to send. */
+
+/* Bits 7..0 : Maximum number of buffer bytes to send. */
+#define SPIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */
+#define SPIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */
+
+/* Register: SPIM_TXD_AMOUNT */
+/* Description: Number of bytes sent in the last transaction. */
+
+/* Bits 7..0 : Number of bytes sent in the last transaction. */
+#define SPIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */
+#define SPIM_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */
+
+/* Register: SPIM_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPIM_ORC */
+/* Description: Over-read character. */
+
+/* Bits 7..0 : Over-read character. */
+#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
+#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
+
+/* Register: SPIM_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPIM_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPIM_POWER_POWER_Msk (0x1UL << SPIM_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPIM_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPIM_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: SPIS */
+/* Description: SPI slave 1. */
+
+/* Register: SPIS_SHORTS */
+/* Description: Shortcuts for SPIS. */
+
+/* Bit 2 : Shortcut between END event and the ACQUIRE task. */
+#define SPIS_SHORTS_END_ACQUIRE_Pos (2UL) /*!< Position of END_ACQUIRE field. */
+#define SPIS_SHORTS_END_ACQUIRE_Msk (0x1UL << SPIS_SHORTS_END_ACQUIRE_Pos) /*!< Bit mask of END_ACQUIRE field. */
+#define SPIS_SHORTS_END_ACQUIRE_Disabled (0UL) /*!< Shortcut disabled. */
+#define SPIS_SHORTS_END_ACQUIRE_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: SPIS_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 10 : Enable interrupt on ACQUIRED event. */
+#define SPIS_INTENSET_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */
+#define SPIS_INTENSET_ACQUIRED_Msk (0x1UL << SPIS_INTENSET_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */
+#define SPIS_INTENSET_ACQUIRED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 4 : enable interrupt on ENDRX event. */
+#define SPIS_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIS_INTENSET_ENDRX_Msk (0x1UL << SPIS_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIS_INTENSET_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENSET_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENSET_ENDRX_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on END event. */
+#define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */
+#define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */
+#define SPIS_INTENSET_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENSET_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENSET_END_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: SPIS_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 10 : Disable interrupt on ACQUIRED event. */
+#define SPIS_INTENCLR_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */
+#define SPIS_INTENCLR_ACQUIRED_Msk (0x1UL << SPIS_INTENCLR_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */
+#define SPIS_INTENCLR_ACQUIRED_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 4 : Disable interrupt on ENDRX event. */
+#define SPIS_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */
+#define SPIS_INTENCLR_ENDRX_Msk (0x1UL << SPIS_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */
+#define SPIS_INTENCLR_ENDRX_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENCLR_ENDRX_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENCLR_ENDRX_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on END event. */
+#define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */
+#define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */
+#define SPIS_INTENCLR_END_Disabled (0UL) /*!< Interrupt disabled. */
+#define SPIS_INTENCLR_END_Enabled (1UL) /*!< Interrupt enabled. */
+#define SPIS_INTENCLR_END_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: SPIS_SEMSTAT */
+/* Description: Semaphore status. */
+
+/* Bits 1..0 : Semaphore status. */
+#define SPIS_SEMSTAT_SEMSTAT_Pos (0UL) /*!< Position of SEMSTAT field. */
+#define SPIS_SEMSTAT_SEMSTAT_Msk (0x3UL << SPIS_SEMSTAT_SEMSTAT_Pos) /*!< Bit mask of SEMSTAT field. */
+#define SPIS_SEMSTAT_SEMSTAT_Free (0x00UL) /*!< Semaphore is free. */
+#define SPIS_SEMSTAT_SEMSTAT_CPU (0x01UL) /*!< Semaphore is assigned to the CPU. */
+#define SPIS_SEMSTAT_SEMSTAT_SPIS (0x02UL) /*!< Semaphore is assigned to the SPIS. */
+#define SPIS_SEMSTAT_SEMSTAT_CPUPending (0x03UL) /*!< Semaphore is assigned to the SPIS, but a handover to the CPU is pending. */
+
+/* Register: SPIS_STATUS */
+/* Description: Status from last transaction. */
+
+/* Bit 1 : RX buffer overflow detected, and prevented. */
+#define SPIS_STATUS_OVERFLOW_Pos (1UL) /*!< Position of OVERFLOW field. */
+#define SPIS_STATUS_OVERFLOW_Msk (0x1UL << SPIS_STATUS_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */
+#define SPIS_STATUS_OVERFLOW_NotPresent (0UL) /*!< Error not present. */
+#define SPIS_STATUS_OVERFLOW_Present (1UL) /*!< Error present. */
+#define SPIS_STATUS_OVERFLOW_Clear (1UL) /*!< Clear on write. */
+
+/* Bit 0 : TX buffer overread detected, and prevented. */
+#define SPIS_STATUS_OVERREAD_Pos (0UL) /*!< Position of OVERREAD field. */
+#define SPIS_STATUS_OVERREAD_Msk (0x1UL << SPIS_STATUS_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */
+#define SPIS_STATUS_OVERREAD_NotPresent (0UL) /*!< Error not present. */
+#define SPIS_STATUS_OVERREAD_Present (1UL) /*!< Error present. */
+#define SPIS_STATUS_OVERREAD_Clear (1UL) /*!< Clear on write. */
+
+/* Register: SPIS_ENABLE */
+/* Description: Enable SPIS. */
+
+/* Bits 2..0 : Enable or disable SPIS. */
+#define SPIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define SPIS_ENABLE_ENABLE_Msk (0x7UL << SPIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define SPIS_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled SPIS. */
+#define SPIS_ENABLE_ENABLE_Enabled (0x02UL) /*!< Enable SPIS. */
+
+/* Register: SPIS_MAXRX */
+/* Description: Maximum number of bytes in the receive buffer. */
+
+/* Bits 7..0 : Maximum number of bytes in the receive buffer. */
+#define SPIS_MAXRX_MAXRX_Pos (0UL) /*!< Position of MAXRX field. */
+#define SPIS_MAXRX_MAXRX_Msk (0xFFUL << SPIS_MAXRX_MAXRX_Pos) /*!< Bit mask of MAXRX field. */
+
+/* Register: SPIS_AMOUNTRX */
+/* Description: Number of bytes received in last granted transaction. */
+
+/* Bits 7..0 : Number of bytes received in last granted transaction. */
+#define SPIS_AMOUNTRX_AMOUNTRX_Pos (0UL) /*!< Position of AMOUNTRX field. */
+#define SPIS_AMOUNTRX_AMOUNTRX_Msk (0xFFUL << SPIS_AMOUNTRX_AMOUNTRX_Pos) /*!< Bit mask of AMOUNTRX field. */
+
+/* Register: SPIS_MAXTX */
+/* Description: Maximum number of bytes in the transmit buffer. */
+
+/* Bits 7..0 : Maximum number of bytes in the transmit buffer. */
+#define SPIS_MAXTX_MAXTX_Pos (0UL) /*!< Position of MAXTX field. */
+#define SPIS_MAXTX_MAXTX_Msk (0xFFUL << SPIS_MAXTX_MAXTX_Pos) /*!< Bit mask of MAXTX field. */
+
+/* Register: SPIS_AMOUNTTX */
+/* Description: Number of bytes transmitted in last granted transaction. */
+
+/* Bits 7..0 : Number of bytes transmitted in last granted transaction. */
+#define SPIS_AMOUNTTX_AMOUNTTX_Pos (0UL) /*!< Position of AMOUNTTX field. */
+#define SPIS_AMOUNTTX_AMOUNTTX_Msk (0xFFUL << SPIS_AMOUNTTX_AMOUNTTX_Pos) /*!< Bit mask of AMOUNTTX field. */
+
+/* Register: SPIS_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 2 : Serial clock (SCK) polarity. */
+#define SPIS_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */
+#define SPIS_CONFIG_CPOL_Msk (0x1UL << SPIS_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */
+#define SPIS_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high. */
+#define SPIS_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low. */
+
+/* Bit 1 : Serial clock (SCK) phase. */
+#define SPIS_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */
+#define SPIS_CONFIG_CPHA_Msk (0x1UL << SPIS_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */
+#define SPIS_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of the clock. Shift serial data on trailing edge. */
+#define SPIS_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of the clock. Shift serial data on leading edge. */
+
+/* Bit 0 : Bit order. */
+#define SPIS_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */
+#define SPIS_CONFIG_ORDER_Msk (0x1UL << SPIS_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */
+#define SPIS_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit transmitted out first. */
+#define SPIS_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit transmitted out first. */
+
+/* Register: SPIS_DEF */
+/* Description: Default character. */
+
+/* Bits 7..0 : Default character. */
+#define SPIS_DEF_DEF_Pos (0UL) /*!< Position of DEF field. */
+#define SPIS_DEF_DEF_Msk (0xFFUL << SPIS_DEF_DEF_Pos) /*!< Bit mask of DEF field. */
+
+/* Register: SPIS_ORC */
+/* Description: Over-read character. */
+
+/* Bits 7..0 : Over-read character. */
+#define SPIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */
+#define SPIS_ORC_ORC_Msk (0xFFUL << SPIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */
+
+/* Register: SPIS_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define SPIS_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define SPIS_POWER_POWER_Msk (0x1UL << SPIS_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define SPIS_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define SPIS_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TEMP */
+/* Description: Temperature Sensor. */
+
+/* Register: TEMP_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on DATARDY event. */
+#define TEMP_INTENSET_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */
+#define TEMP_INTENSET_DATARDY_Msk (0x1UL << TEMP_INTENSET_DATARDY_Pos) /*!< Bit mask of DATARDY field. */
+#define TEMP_INTENSET_DATARDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TEMP_INTENSET_DATARDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TEMP_INTENSET_DATARDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TEMP_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on DATARDY event. */
+#define TEMP_INTENCLR_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */
+#define TEMP_INTENCLR_DATARDY_Msk (0x1UL << TEMP_INTENCLR_DATARDY_Pos) /*!< Bit mask of DATARDY field. */
+#define TEMP_INTENCLR_DATARDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TEMP_INTENCLR_DATARDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TEMP_INTENCLR_DATARDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TEMP_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TEMP_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TEMP_POWER_POWER_Msk (0x1UL << TEMP_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TEMP_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TEMP_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TIMER */
+/* Description: Timer 0. */
+
+/* Register: TIMER_SHORTS */
+/* Description: Shortcuts for Timer. */
+
+/* Bit 11 : Shortcut between CC[3] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE3_STOP_Pos (11UL) /*!< Position of COMPARE3_STOP field. */
+#define TIMER_SHORTS_COMPARE3_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE3_STOP_Pos) /*!< Bit mask of COMPARE3_STOP field. */
+#define TIMER_SHORTS_COMPARE3_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE3_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 10 : Shortcut between CC[2] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE2_STOP_Pos (10UL) /*!< Position of COMPARE2_STOP field. */
+#define TIMER_SHORTS_COMPARE2_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE2_STOP_Pos) /*!< Bit mask of COMPARE2_STOP field. */
+#define TIMER_SHORTS_COMPARE2_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE2_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 9 : Shortcut between CC[1] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE1_STOP_Pos (9UL) /*!< Position of COMPARE1_STOP field. */
+#define TIMER_SHORTS_COMPARE1_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE1_STOP_Pos) /*!< Bit mask of COMPARE1_STOP field. */
+#define TIMER_SHORTS_COMPARE1_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE1_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 8 : Shortcut between CC[0] event and the STOP task. */
+#define TIMER_SHORTS_COMPARE0_STOP_Pos (8UL) /*!< Position of COMPARE0_STOP field. */
+#define TIMER_SHORTS_COMPARE0_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE0_STOP_Pos) /*!< Bit mask of COMPARE0_STOP field. */
+#define TIMER_SHORTS_COMPARE0_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE0_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between CC[3] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Pos (3UL) /*!< Position of COMPARE3_CLEAR field. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE3_CLEAR_Pos) /*!< Bit mask of COMPARE3_CLEAR field. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE3_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 2 : Shortcut between CC[2] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Pos (2UL) /*!< Position of COMPARE2_CLEAR field. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE2_CLEAR_Pos) /*!< Bit mask of COMPARE2_CLEAR field. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE2_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 1 : Shortcut between CC[1] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Pos (1UL) /*!< Position of COMPARE1_CLEAR field. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE1_CLEAR_Pos) /*!< Bit mask of COMPARE1_CLEAR field. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE1_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between CC[0] event and the CLEAR task. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Pos (0UL) /*!< Position of COMPARE0_CLEAR field. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE0_CLEAR_Pos) /*!< Bit mask of COMPARE0_CLEAR field. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Disabled (0UL) /*!< Shortcut disabled. */
+#define TIMER_SHORTS_COMPARE0_CLEAR_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: TIMER_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 19 : Enable interrupt on COMPARE[3] */
+#define TIMER_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define TIMER_INTENSET_COMPARE3_Msk (0x1UL << TIMER_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define TIMER_INTENSET_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE3_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 18 : Enable interrupt on COMPARE[2] */
+#define TIMER_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define TIMER_INTENSET_COMPARE2_Msk (0x1UL << TIMER_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define TIMER_INTENSET_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE2_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 17 : Enable interrupt on COMPARE[1] */
+#define TIMER_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define TIMER_INTENSET_COMPARE1_Msk (0x1UL << TIMER_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define TIMER_INTENSET_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE1_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 16 : Enable interrupt on COMPARE[0] */
+#define TIMER_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define TIMER_INTENSET_COMPARE0_Msk (0x1UL << TIMER_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define TIMER_INTENSET_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENSET_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENSET_COMPARE0_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TIMER_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 19 : Disable interrupt on COMPARE[3] */
+#define TIMER_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */
+#define TIMER_INTENCLR_COMPARE3_Msk (0x1UL << TIMER_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */
+#define TIMER_INTENCLR_COMPARE3_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE3_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 18 : Disable interrupt on COMPARE[2] */
+#define TIMER_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */
+#define TIMER_INTENCLR_COMPARE2_Msk (0x1UL << TIMER_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */
+#define TIMER_INTENCLR_COMPARE2_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE2_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 17 : Disable interrupt on COMPARE[1] */
+#define TIMER_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */
+#define TIMER_INTENCLR_COMPARE1_Msk (0x1UL << TIMER_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */
+#define TIMER_INTENCLR_COMPARE1_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE1_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 16 : Disable interrupt on COMPARE[0] */
+#define TIMER_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */
+#define TIMER_INTENCLR_COMPARE0_Msk (0x1UL << TIMER_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */
+#define TIMER_INTENCLR_COMPARE0_Disabled (0UL) /*!< Interrupt disabled. */
+#define TIMER_INTENCLR_COMPARE0_Enabled (1UL) /*!< Interrupt enabled. */
+#define TIMER_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TIMER_MODE */
+/* Description: Timer Mode selection. */
+
+/* Bit 0 : Select Normal or Counter mode. */
+#define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */
+#define TIMER_MODE_MODE_Msk (0x1UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */
+#define TIMER_MODE_MODE_Timer (0UL) /*!< Timer in Normal mode. */
+#define TIMER_MODE_MODE_Counter (1UL) /*!< Timer in Counter mode. */
+
+/* Register: TIMER_BITMODE */
+/* Description: Sets timer behaviour. */
+
+/* Bits 1..0 : Sets timer behaviour ro be like the implementation of a timer with width as indicated. */
+#define TIMER_BITMODE_BITMODE_Pos (0UL) /*!< Position of BITMODE field. */
+#define TIMER_BITMODE_BITMODE_Msk (0x3UL << TIMER_BITMODE_BITMODE_Pos) /*!< Bit mask of BITMODE field. */
+#define TIMER_BITMODE_BITMODE_16Bit (0x00UL) /*!< 16-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_08Bit (0x01UL) /*!< 8-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_24Bit (0x02UL) /*!< 24-bit timer behaviour. */
+#define TIMER_BITMODE_BITMODE_32Bit (0x03UL) /*!< 32-bit timer behaviour. */
+
+/* Register: TIMER_PRESCALER */
+/* Description: 4-bit prescaler to source clock frequency (max value 9). Source clock frequency is divided by 2^SCALE. */
+
+/* Bits 3..0 : Timer PRESCALER value. Max value is 9. */
+#define TIMER_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */
+#define TIMER_PRESCALER_PRESCALER_Msk (0xFUL << TIMER_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */
+
+/* Register: TIMER_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TIMER_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TIMER_POWER_POWER_Msk (0x1UL << TIMER_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TIMER_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TIMER_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: TWI */
+/* Description: Two-wire interface master 0. */
+
+/* Register: TWI_SHORTS */
+/* Description: Shortcuts for TWI. */
+
+/* Bit 1 : Shortcut between BB event and the STOP task. */
+#define TWI_SHORTS_BB_STOP_Pos (1UL) /*!< Position of BB_STOP field. */
+#define TWI_SHORTS_BB_STOP_Msk (0x1UL << TWI_SHORTS_BB_STOP_Pos) /*!< Bit mask of BB_STOP field. */
+#define TWI_SHORTS_BB_STOP_Disabled (0UL) /*!< Shortcut disabled. */
+#define TWI_SHORTS_BB_STOP_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 0 : Shortcut between BB event and the SUSPEND task. */
+#define TWI_SHORTS_BB_SUSPEND_Pos (0UL) /*!< Position of BB_SUSPEND field. */
+#define TWI_SHORTS_BB_SUSPEND_Msk (0x1UL << TWI_SHORTS_BB_SUSPEND_Pos) /*!< Bit mask of BB_SUSPEND field. */
+#define TWI_SHORTS_BB_SUSPEND_Disabled (0UL) /*!< Shortcut disabled. */
+#define TWI_SHORTS_BB_SUSPEND_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: TWI_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 18 : Enable interrupt on SUSPENDED event. */
+#define TWI_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */
+#define TWI_INTENSET_SUSPENDED_Msk (0x1UL << TWI_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */
+#define TWI_INTENSET_SUSPENDED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_SUSPENDED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_SUSPENDED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 14 : Enable interrupt on BB event. */
+#define TWI_INTENSET_BB_Pos (14UL) /*!< Position of BB field. */
+#define TWI_INTENSET_BB_Msk (0x1UL << TWI_INTENSET_BB_Pos) /*!< Bit mask of BB field. */
+#define TWI_INTENSET_BB_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_BB_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_BB_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 9 : Enable interrupt on ERROR event. */
+#define TWI_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define TWI_INTENSET_ERROR_Msk (0x1UL << TWI_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define TWI_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on TXDSENT event. */
+#define TWI_INTENSET_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */
+#define TWI_INTENSET_TXDSENT_Msk (0x1UL << TWI_INTENSET_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */
+#define TWI_INTENSET_TXDSENT_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_TXDSENT_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_TXDSENT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on READY event. */
+#define TWI_INTENSET_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */
+#define TWI_INTENSET_RXDREADY_Msk (0x1UL << TWI_INTENSET_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */
+#define TWI_INTENSET_RXDREADY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_RXDREADY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_RXDREADY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on STOPPED event. */
+#define TWI_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define TWI_INTENSET_STOPPED_Msk (0x1UL << TWI_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define TWI_INTENSET_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENSET_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENSET_STOPPED_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: TWI_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 18 : Disable interrupt on SUSPENDED event. */
+#define TWI_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */
+#define TWI_INTENCLR_SUSPENDED_Msk (0x1UL << TWI_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */
+#define TWI_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 14 : Disable interrupt on BB event. */
+#define TWI_INTENCLR_BB_Pos (14UL) /*!< Position of BB field. */
+#define TWI_INTENCLR_BB_Msk (0x1UL << TWI_INTENCLR_BB_Pos) /*!< Bit mask of BB field. */
+#define TWI_INTENCLR_BB_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_BB_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_BB_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 9 : Disable interrupt on ERROR event. */
+#define TWI_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define TWI_INTENCLR_ERROR_Msk (0x1UL << TWI_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define TWI_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on TXDSENT event. */
+#define TWI_INTENCLR_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */
+#define TWI_INTENCLR_TXDSENT_Msk (0x1UL << TWI_INTENCLR_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */
+#define TWI_INTENCLR_TXDSENT_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_TXDSENT_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_TXDSENT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on RXDREADY event. */
+#define TWI_INTENCLR_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */
+#define TWI_INTENCLR_RXDREADY_Msk (0x1UL << TWI_INTENCLR_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */
+#define TWI_INTENCLR_RXDREADY_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_RXDREADY_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_RXDREADY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on STOPPED event. */
+#define TWI_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */
+#define TWI_INTENCLR_STOPPED_Msk (0x1UL << TWI_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */
+#define TWI_INTENCLR_STOPPED_Disabled (0UL) /*!< Interrupt disabled. */
+#define TWI_INTENCLR_STOPPED_Enabled (1UL) /*!< Interrupt enabled. */
+#define TWI_INTENCLR_STOPPED_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: TWI_ERRORSRC */
+/* Description: Two-wire error source. Write error field to 1 to clear error. */
+
+/* Bit 2 : NACK received after sending a data byte. */
+#define TWI_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */
+#define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */
+#define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Error not present. */
+#define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Error present. */
+#define TWI_ERRORSRC_DNACK_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 1 : NACK received after sending the address. */
+#define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */
+#define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */
+#define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Error not present. */
+#define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Error present. */
+#define TWI_ERRORSRC_ANACK_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 0 : Byte received in RXD register before read of the last received byte (data loss). */
+#define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
+#define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
+#define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Error not present. */
+#define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Error present. */
+#define TWI_ERRORSRC_OVERRUN_Clear (1UL) /*!< Clear error on write. */
+
+/* Register: TWI_ENABLE */
+/* Description: Enable two-wire master. */
+
+/* Bits 2..0 : Enable or disable W2M */
+#define TWI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define TWI_ENABLE_ENABLE_Msk (0x7UL << TWI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define TWI_ENABLE_ENABLE_Disabled (0x00UL) /*!< Disabled. */
+#define TWI_ENABLE_ENABLE_Enabled (0x05UL) /*!< Enabled. */
+
+/* Register: TWI_RXD */
+/* Description: RX data register. */
+
+/* Bits 7..0 : RX data from last transfer. */
+#define TWI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define TWI_RXD_RXD_Msk (0xFFUL << TWI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: TWI_TXD */
+/* Description: TX data register. */
+
+/* Bits 7..0 : TX data for next transfer. */
+#define TWI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define TWI_TXD_TXD_Msk (0xFFUL << TWI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: TWI_FREQUENCY */
+/* Description: Two-wire frequency. */
+
+/* Bits 31..0 : Two-wire master clock frequency. */
+#define TWI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */
+#define TWI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */
+#define TWI_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps. */
+#define TWI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps. */
+#define TWI_FREQUENCY_FREQUENCY_K400 (0x06680000UL) /*!< 400 kbps. */
+
+/* Register: TWI_ADDRESS */
+/* Description: Address used in the two-wire transfer. */
+
+/* Bits 6..0 : Two-wire address. */
+#define TWI_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */
+#define TWI_ADDRESS_ADDRESS_Msk (0x7FUL << TWI_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */
+
+/* Register: TWI_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define TWI_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define TWI_POWER_POWER_Msk (0x1UL << TWI_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define TWI_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define TWI_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: UART */
+/* Description: Universal Asynchronous Receiver/Transmitter. */
+
+/* Register: UART_SHORTS */
+/* Description: Shortcuts for UART. */
+
+/* Bit 4 : Shortcut between NCTS event and STOPRX task. */
+#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */
+#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */
+#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Shortcut disabled. */
+#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Bit 3 : Shortcut between CTS event and STARTRX task. */
+#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */
+#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */
+#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Shortcut disabled. */
+#define UART_SHORTS_CTS_STARTRX_Enabled (1UL) /*!< Shortcut enabled. */
+
+/* Register: UART_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 17 : Enable interrupt on RXTO event. */
+#define UART_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */
+#define UART_INTENSET_RXTO_Msk (0x1UL << UART_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */
+#define UART_INTENSET_RXTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_RXTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_RXTO_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 9 : Enable interrupt on ERROR event. */
+#define UART_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define UART_INTENSET_ERROR_Msk (0x1UL << UART_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define UART_INTENSET_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_ERROR_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 7 : Enable interrupt on TXRDY event. */
+#define UART_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */
+#define UART_INTENSET_TXDRDY_Msk (0x1UL << UART_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */
+#define UART_INTENSET_TXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_TXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_TXDRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 2 : Enable interrupt on RXRDY event. */
+#define UART_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */
+#define UART_INTENSET_RXDRDY_Msk (0x1UL << UART_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */
+#define UART_INTENSET_RXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_RXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_RXDRDY_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 1 : Enable interrupt on NCTS event. */
+#define UART_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */
+#define UART_INTENSET_NCTS_Msk (0x1UL << UART_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */
+#define UART_INTENSET_NCTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_NCTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_NCTS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Bit 0 : Enable interrupt on CTS event. */
+#define UART_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */
+#define UART_INTENSET_CTS_Msk (0x1UL << UART_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */
+#define UART_INTENSET_CTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENSET_CTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENSET_CTS_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: UART_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 17 : Disable interrupt on RXTO event. */
+#define UART_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */
+#define UART_INTENCLR_RXTO_Msk (0x1UL << UART_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */
+#define UART_INTENCLR_RXTO_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_RXTO_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_RXTO_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 9 : Disable interrupt on ERROR event. */
+#define UART_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */
+#define UART_INTENCLR_ERROR_Msk (0x1UL << UART_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */
+#define UART_INTENCLR_ERROR_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_ERROR_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_ERROR_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 7 : Disable interrupt on TXRDY event. */
+#define UART_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */
+#define UART_INTENCLR_TXDRDY_Msk (0x1UL << UART_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */
+#define UART_INTENCLR_TXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_TXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 2 : Disable interrupt on RXRDY event. */
+#define UART_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */
+#define UART_INTENCLR_RXDRDY_Msk (0x1UL << UART_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */
+#define UART_INTENCLR_RXDRDY_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_RXDRDY_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 1 : Disable interrupt on NCTS event. */
+#define UART_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */
+#define UART_INTENCLR_NCTS_Msk (0x1UL << UART_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */
+#define UART_INTENCLR_NCTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_NCTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_NCTS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Bit 0 : Disable interrupt on CTS event. */
+#define UART_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */
+#define UART_INTENCLR_CTS_Msk (0x1UL << UART_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */
+#define UART_INTENCLR_CTS_Disabled (0UL) /*!< Interrupt disabled. */
+#define UART_INTENCLR_CTS_Enabled (1UL) /*!< Interrupt enabled. */
+#define UART_INTENCLR_CTS_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: UART_ERRORSRC */
+/* Description: Error source. Write error field to 1 to clear error. */
+
+/* Bit 3 : The serial data input is '0' for longer than the length of a data frame. */
+#define UART_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */
+#define UART_ERRORSRC_BREAK_Msk (0x1UL << UART_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */
+#define UART_ERRORSRC_BREAK_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_BREAK_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_BREAK_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 2 : A valid stop bit is not detected on the serial data input after all bits in a character have been received. */
+#define UART_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */
+#define UART_ERRORSRC_FRAMING_Msk (0x1UL << UART_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */
+#define UART_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_FRAMING_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_FRAMING_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 1 : A character with bad parity is received. Only checked if HW parity control is enabled. */
+#define UART_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */
+#define UART_ERRORSRC_PARITY_Msk (0x1UL << UART_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */
+#define UART_ERRORSRC_PARITY_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_PARITY_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_PARITY_Clear (1UL) /*!< Clear error on write. */
+
+/* Bit 0 : A start bit is received while the previous data still lies in RXD. (Data loss). */
+#define UART_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */
+#define UART_ERRORSRC_OVERRUN_Msk (0x1UL << UART_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */
+#define UART_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Error not present. */
+#define UART_ERRORSRC_OVERRUN_Present (1UL) /*!< Error present. */
+#define UART_ERRORSRC_OVERRUN_Clear (1UL) /*!< Clear error on write. */
+
+/* Register: UART_ENABLE */
+/* Description: Enable UART and acquire IOs. */
+
+/* Bits 2..0 : Enable or disable UART and acquire IOs. */
+#define UART_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */
+#define UART_ENABLE_ENABLE_Msk (0x7UL << UART_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */
+#define UART_ENABLE_ENABLE_Disabled (0x00UL) /*!< UART disabled. */
+#define UART_ENABLE_ENABLE_Enabled (0x04UL) /*!< UART enabled. */
+
+/* Register: UART_RXD */
+/* Description: RXD register. On read action the buffer pointer is displaced. Once read the character is consumed. If read when no character available, the UART will stop working. */
+
+/* Bits 7..0 : RX data from previous transfer. Double buffered. */
+#define UART_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */
+#define UART_RXD_RXD_Msk (0xFFUL << UART_RXD_RXD_Pos) /*!< Bit mask of RXD field. */
+
+/* Register: UART_TXD */
+/* Description: TXD register. */
+
+/* Bits 7..0 : TX data for transfer. */
+#define UART_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */
+#define UART_TXD_TXD_Msk (0xFFUL << UART_TXD_TXD_Pos) /*!< Bit mask of TXD field. */
+
+/* Register: UART_BAUDRATE */
+/* Description: UART Baudrate. */
+
+/* Bits 31..0 : UART baudrate. */
+#define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */
+#define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */
+#define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBED000UL) /*!< 921600 baud. */
+#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1M baud. */
+
+/* Register: UART_CONFIG */
+/* Description: Configuration of parity and hardware flow control register. */
+
+/* Bits 3..1 : Include parity bit. */
+#define UART_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */
+#define UART_CONFIG_PARITY_Msk (0x7UL << UART_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */
+#define UART_CONFIG_PARITY_Excluded (0UL) /*!< Parity bit excluded. */
+#define UART_CONFIG_PARITY_Included (7UL) /*!< Parity bit included. */
+
+/* Bit 0 : Hardware flow control. */
+#define UART_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */
+#define UART_CONFIG_HWFC_Msk (0x1UL << UART_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */
+#define UART_CONFIG_HWFC_Disabled (0UL) /*!< Hardware flow control disabled. */
+#define UART_CONFIG_HWFC_Enabled (1UL) /*!< Hardware flow control enabled. */
+
+/* Register: UART_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define UART_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define UART_POWER_POWER_Msk (0x1UL << UART_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define UART_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define UART_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/* Peripheral: UICR */
+/* Description: User Information Configuration. */
+
+/* Register: UICR_RBPCONF */
+/* Description: Readback protection configuration. */
+
+/* Bits 15..8 : Readback protect all code in the device. */
+#define UICR_RBPCONF_PALL_Pos (8UL) /*!< Position of PALL field. */
+#define UICR_RBPCONF_PALL_Msk (0xFFUL << UICR_RBPCONF_PALL_Pos) /*!< Bit mask of PALL field. */
+#define UICR_RBPCONF_PALL_Enabled (0x00UL) /*!< Enabled. */
+#define UICR_RBPCONF_PALL_Disabled (0xFFUL) /*!< Disabled. */
+
+/* Bits 7..0 : Readback protect region 0. Will be ignored if pre-programmed factory code is present on the chip. */
+#define UICR_RBPCONF_PR0_Pos (0UL) /*!< Position of PR0 field. */
+#define UICR_RBPCONF_PR0_Msk (0xFFUL << UICR_RBPCONF_PR0_Pos) /*!< Bit mask of PR0 field. */
+#define UICR_RBPCONF_PR0_Enabled (0x00UL) /*!< Enabled. */
+#define UICR_RBPCONF_PR0_Disabled (0xFFUL) /*!< Disabled. */
+
+/* Register: UICR_XTALFREQ */
+/* Description: Reset value for CLOCK XTALFREQ register. */
+
+/* Bits 7..0 : Reset value for CLOCK XTALFREQ register. */
+#define UICR_XTALFREQ_XTALFREQ_Pos (0UL) /*!< Position of XTALFREQ field. */
+#define UICR_XTALFREQ_XTALFREQ_Msk (0xFFUL << UICR_XTALFREQ_XTALFREQ_Pos) /*!< Bit mask of XTALFREQ field. */
+#define UICR_XTALFREQ_XTALFREQ_32MHz (0x00UL) /*!< 32MHz Xtal is used. */
+#define UICR_XTALFREQ_XTALFREQ_16MHz (0xFFUL) /*!< 16MHz Xtal is used. */
+
+/* Register: UICR_FWID */
+/* Description: Firmware ID. */
+
+/* Bits 15..0 : Identification number for the firmware loaded into the chip. */
+#define UICR_FWID_FWID_Pos (0UL) /*!< Position of FWID field. */
+#define UICR_FWID_FWID_Msk (0xFFFFUL << UICR_FWID_FWID_Pos) /*!< Bit mask of FWID field. */
+
+
+/* Peripheral: WDT */
+/* Description: Watchdog Timer. */
+
+/* Register: WDT_INTENSET */
+/* Description: Interrupt enable set register. */
+
+/* Bit 0 : Enable interrupt on TIMEOUT event. */
+#define WDT_INTENSET_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */
+#define WDT_INTENSET_TIMEOUT_Msk (0x1UL << WDT_INTENSET_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */
+#define WDT_INTENSET_TIMEOUT_Disabled (0UL) /*!< Interrupt disabled. */
+#define WDT_INTENSET_TIMEOUT_Enabled (1UL) /*!< Interrupt enabled. */
+#define WDT_INTENSET_TIMEOUT_Set (1UL) /*!< Enable interrupt on write. */
+
+/* Register: WDT_INTENCLR */
+/* Description: Interrupt enable clear register. */
+
+/* Bit 0 : Disable interrupt on TIMEOUT event. */
+#define WDT_INTENCLR_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */
+#define WDT_INTENCLR_TIMEOUT_Msk (0x1UL << WDT_INTENCLR_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */
+#define WDT_INTENCLR_TIMEOUT_Disabled (0UL) /*!< Interrupt disabled. */
+#define WDT_INTENCLR_TIMEOUT_Enabled (1UL) /*!< Interrupt enabled. */
+#define WDT_INTENCLR_TIMEOUT_Clear (1UL) /*!< Disable interrupt on write. */
+
+/* Register: WDT_RUNSTATUS */
+/* Description: Watchdog running status. */
+
+/* Bit 0 : Watchdog running status. */
+#define WDT_RUNSTATUS_RUNSTATUS_Pos (0UL) /*!< Position of RUNSTATUS field. */
+#define WDT_RUNSTATUS_RUNSTATUS_Msk (0x1UL << WDT_RUNSTATUS_RUNSTATUS_Pos) /*!< Bit mask of RUNSTATUS field. */
+#define WDT_RUNSTATUS_RUNSTATUS_NotRunning (0UL) /*!< Watchdog timer is not running. */
+#define WDT_RUNSTATUS_RUNSTATUS_Running (1UL) /*!< Watchdog timer is running. */
+
+/* Register: WDT_REQSTATUS */
+/* Description: Request status. */
+
+/* Bit 7 : Request status for RR[7]. */
+#define WDT_REQSTATUS_RR7_Pos (7UL) /*!< Position of RR7 field. */
+#define WDT_REQSTATUS_RR7_Msk (0x1UL << WDT_REQSTATUS_RR7_Pos) /*!< Bit mask of RR7 field. */
+#define WDT_REQSTATUS_RR7_DisabledOrRequested (0UL) /*!< RR[7] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR7_EnabledAndUnrequested (1UL) /*!< RR[7] register is enabled and has not jet requested. */
+
+/* Bit 6 : Request status for RR[6]. */
+#define WDT_REQSTATUS_RR6_Pos (6UL) /*!< Position of RR6 field. */
+#define WDT_REQSTATUS_RR6_Msk (0x1UL << WDT_REQSTATUS_RR6_Pos) /*!< Bit mask of RR6 field. */
+#define WDT_REQSTATUS_RR6_DisabledOrRequested (0UL) /*!< RR[6] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR6_EnabledAndUnrequested (1UL) /*!< RR[6] register is enabled and has not jet requested. */
+
+/* Bit 5 : Request status for RR[5]. */
+#define WDT_REQSTATUS_RR5_Pos (5UL) /*!< Position of RR5 field. */
+#define WDT_REQSTATUS_RR5_Msk (0x1UL << WDT_REQSTATUS_RR5_Pos) /*!< Bit mask of RR5 field. */
+#define WDT_REQSTATUS_RR5_DisabledOrRequested (0UL) /*!< RR[5] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR5_EnabledAndUnrequested (1UL) /*!< RR[5] register is enabled and has not jet requested. */
+
+/* Bit 4 : Request status for RR[4]. */
+#define WDT_REQSTATUS_RR4_Pos (4UL) /*!< Position of RR4 field. */
+#define WDT_REQSTATUS_RR4_Msk (0x1UL << WDT_REQSTATUS_RR4_Pos) /*!< Bit mask of RR4 field. */
+#define WDT_REQSTATUS_RR4_DisabledOrRequested (0UL) /*!< RR[4] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR4_EnabledAndUnrequested (1UL) /*!< RR[4] register is enabled and has not jet requested. */
+
+/* Bit 3 : Request status for RR[3]. */
+#define WDT_REQSTATUS_RR3_Pos (3UL) /*!< Position of RR3 field. */
+#define WDT_REQSTATUS_RR3_Msk (0x1UL << WDT_REQSTATUS_RR3_Pos) /*!< Bit mask of RR3 field. */
+#define WDT_REQSTATUS_RR3_DisabledOrRequested (0UL) /*!< RR[3] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR3_EnabledAndUnrequested (1UL) /*!< RR[3] register is enabled and has not jet requested. */
+
+/* Bit 2 : Request status for RR[2]. */
+#define WDT_REQSTATUS_RR2_Pos (2UL) /*!< Position of RR2 field. */
+#define WDT_REQSTATUS_RR2_Msk (0x1UL << WDT_REQSTATUS_RR2_Pos) /*!< Bit mask of RR2 field. */
+#define WDT_REQSTATUS_RR2_DisabledOrRequested (0UL) /*!< RR[2] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR2_EnabledAndUnrequested (1UL) /*!< RR[2] register is enabled and has not jet requested. */
+
+/* Bit 1 : Request status for RR[1]. */
+#define WDT_REQSTATUS_RR1_Pos (1UL) /*!< Position of RR1 field. */
+#define WDT_REQSTATUS_RR1_Msk (0x1UL << WDT_REQSTATUS_RR1_Pos) /*!< Bit mask of RR1 field. */
+#define WDT_REQSTATUS_RR1_DisabledOrRequested (0UL) /*!< RR[1] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR1_EnabledAndUnrequested (1UL) /*!< RR[1] register is enabled and has not jet requested. */
+
+/* Bit 0 : Request status for RR[0]. */
+#define WDT_REQSTATUS_RR0_Pos (0UL) /*!< Position of RR0 field. */
+#define WDT_REQSTATUS_RR0_Msk (0x1UL << WDT_REQSTATUS_RR0_Pos) /*!< Bit mask of RR0 field. */
+#define WDT_REQSTATUS_RR0_DisabledOrRequested (0UL) /*!< RR[0] register is not enabled or has already requested reload. */
+#define WDT_REQSTATUS_RR0_EnabledAndUnrequested (1UL) /*!< RR[0] register is enabled and has not jet requested. */
+
+/* Register: WDT_RREN */
+/* Description: Reload request enable. */
+
+/* Bit 7 : Enable or disable RR[7] register. */
+#define WDT_RREN_RR7_Pos (7UL) /*!< Position of RR7 field. */
+#define WDT_RREN_RR7_Msk (0x1UL << WDT_RREN_RR7_Pos) /*!< Bit mask of RR7 field. */
+#define WDT_RREN_RR7_Disabled (0UL) /*!< RR[7] register is disabled. */
+#define WDT_RREN_RR7_Enabled (1UL) /*!< RR[7] register is enabled. */
+
+/* Bit 6 : Enable or disable RR[6] register. */
+#define WDT_RREN_RR6_Pos (6UL) /*!< Position of RR6 field. */
+#define WDT_RREN_RR6_Msk (0x1UL << WDT_RREN_RR6_Pos) /*!< Bit mask of RR6 field. */
+#define WDT_RREN_RR6_Disabled (0UL) /*!< RR[6] register is disabled. */
+#define WDT_RREN_RR6_Enabled (1UL) /*!< RR[6] register is enabled. */
+
+/* Bit 5 : Enable or disable RR[5] register. */
+#define WDT_RREN_RR5_Pos (5UL) /*!< Position of RR5 field. */
+#define WDT_RREN_RR5_Msk (0x1UL << WDT_RREN_RR5_Pos) /*!< Bit mask of RR5 field. */
+#define WDT_RREN_RR5_Disabled (0UL) /*!< RR[5] register is disabled. */
+#define WDT_RREN_RR5_Enabled (1UL) /*!< RR[5] register is enabled. */
+
+/* Bit 4 : Enable or disable RR[4] register. */
+#define WDT_RREN_RR4_Pos (4UL) /*!< Position of RR4 field. */
+#define WDT_RREN_RR4_Msk (0x1UL << WDT_RREN_RR4_Pos) /*!< Bit mask of RR4 field. */
+#define WDT_RREN_RR4_Disabled (0UL) /*!< RR[4] register is disabled. */
+#define WDT_RREN_RR4_Enabled (1UL) /*!< RR[4] register is enabled. */
+
+/* Bit 3 : Enable or disable RR[3] register. */
+#define WDT_RREN_RR3_Pos (3UL) /*!< Position of RR3 field. */
+#define WDT_RREN_RR3_Msk (0x1UL << WDT_RREN_RR3_Pos) /*!< Bit mask of RR3 field. */
+#define WDT_RREN_RR3_Disabled (0UL) /*!< RR[3] register is disabled. */
+#define WDT_RREN_RR3_Enabled (1UL) /*!< RR[3] register is enabled. */
+
+/* Bit 2 : Enable or disable RR[2] register. */
+#define WDT_RREN_RR2_Pos (2UL) /*!< Position of RR2 field. */
+#define WDT_RREN_RR2_Msk (0x1UL << WDT_RREN_RR2_Pos) /*!< Bit mask of RR2 field. */
+#define WDT_RREN_RR2_Disabled (0UL) /*!< RR[2] register is disabled. */
+#define WDT_RREN_RR2_Enabled (1UL) /*!< RR[2] register is enabled. */
+
+/* Bit 1 : Enable or disable RR[1] register. */
+#define WDT_RREN_RR1_Pos (1UL) /*!< Position of RR1 field. */
+#define WDT_RREN_RR1_Msk (0x1UL << WDT_RREN_RR1_Pos) /*!< Bit mask of RR1 field. */
+#define WDT_RREN_RR1_Disabled (0UL) /*!< RR[1] register is disabled. */
+#define WDT_RREN_RR1_Enabled (1UL) /*!< RR[1] register is enabled. */
+
+/* Bit 0 : Enable or disable RR[0] register. */
+#define WDT_RREN_RR0_Pos (0UL) /*!< Position of RR0 field. */
+#define WDT_RREN_RR0_Msk (0x1UL << WDT_RREN_RR0_Pos) /*!< Bit mask of RR0 field. */
+#define WDT_RREN_RR0_Disabled (0UL) /*!< RR[0] register is disabled. */
+#define WDT_RREN_RR0_Enabled (1UL) /*!< RR[0] register is enabled. */
+
+/* Register: WDT_CONFIG */
+/* Description: Configuration register. */
+
+/* Bit 3 : Configure the watchdog to pause or not while the CPU is halted by the debugger. */
+#define WDT_CONFIG_HALT_Pos (3UL) /*!< Position of HALT field. */
+#define WDT_CONFIG_HALT_Msk (0x1UL << WDT_CONFIG_HALT_Pos) /*!< Bit mask of HALT field. */
+#define WDT_CONFIG_HALT_Pause (0UL) /*!< Pause watchdog while the CPU is halted by the debugger. */
+#define WDT_CONFIG_HALT_Run (1UL) /*!< Do not pause watchdog while the CPU is halted by the debugger. */
+
+/* Bit 0 : Configure the watchdog to pause or not while the CPU is sleeping. */
+#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */
+#define WDT_CONFIG_SLEEP_Msk (0x1UL << WDT_CONFIG_SLEEP_Pos) /*!< Bit mask of SLEEP field. */
+#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause watchdog while the CPU is asleep. */
+#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Do not pause watchdog while the CPU is asleep. */
+
+/* Register: WDT_RR */
+/* Description: Reload requests registers. */
+
+/* Bits 31..0 : Reload register. */
+#define WDT_RR_RR_Pos (0UL) /*!< Position of RR field. */
+#define WDT_RR_RR_Msk (0xFFFFFFFFUL << WDT_RR_RR_Pos) /*!< Bit mask of RR field. */
+#define WDT_RR_RR_Reload (0x6E524635UL) /*!< Value to request a reload of the watchdog timer. */
+
+/* Register: WDT_POWER */
+/* Description: Peripheral power control. */
+
+/* Bit 0 : Peripheral power control. */
+#define WDT_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */
+#define WDT_POWER_POWER_Msk (0x1UL << WDT_POWER_POWER_Pos) /*!< Bit mask of POWER field. */
+#define WDT_POWER_POWER_Disabled (0UL) /*!< Module power disabled. */
+#define WDT_POWER_POWER_Enabled (1UL) /*!< Module power enabled. */
+
+
+/*lint --flb "Leave library region" */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/device/nrf51_deprecated.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF51_DEPRECATED_H
+#define NRF51_DEPRECATED_H
+
+/*lint ++flb "Enter library region */
+
+/* This file is given to prevent your SW from not compiling with the updates made to nrf51.h and 
+ * nrf51_bitfields.h. The macros defined in this file were available previously. Do not use these
+ * macros on purpose. Use the ones defined in nrf51.h and nrf51_bitfields.h instead.
+ */
+
+/* NVMC */
+/* The register ERASEPROTECTEDPAGE is called ERASEPCR0 in the documentation. */
+#define ERASEPROTECTEDPAGE   ERASEPCR0
+
+ 
+/* LPCOMP */
+/* The interrupt ISR was renamed. Adding old name to the macros. */
+#define LPCOMP_COMP_IRQHandler      LPCOMP_IRQHandler
+#define LPCOMP_COMP_IRQn            LPCOMP_IRQn
+ 
+ 
+/* MPU */
+/* The field MPU.PERR0.LPCOMP_COMP was renamed. Added into deprecated in case somebody was using the macros defined for it. */
+#define MPU_PERR0_LPCOMP_COMP_Pos           MPU_PERR0_LPCOMP_Pos
+#define MPU_PERR0_LPCOMP_COMP_Msk           MPU_PERR0_LPCOMP_Msk
+#define MPU_PERR0_LPCOMP_COMP_InRegion1     MPU_PERR0_LPCOMP_InRegion1
+#define MPU_PERR0_LPCOMP_COMP_InRegion0     MPU_PERR0_LPCOMP_InRegion0
+ 
+ 
+/* POWER */
+/* The field POWER.RAMON.OFFRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
+#define POWER_RAMON_OFFRAM3_Pos         (19UL)                                  
+#define POWER_RAMON_OFFRAM3_Msk         (0x1UL << POWER_RAMON_OFFRAM3_Pos)      
+#define POWER_RAMON_OFFRAM3_RAM3Off     (0UL)                                   
+#define POWER_RAMON_OFFRAM3_RAM3On      (1UL)                                   
+/* The field POWER.RAMON.OFFRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
+#define POWER_RAMON_OFFRAM2_Pos         (18UL)                                  
+#define POWER_RAMON_OFFRAM2_Msk         (0x1UL << POWER_RAMON_OFFRAM2_Pos)      
+#define POWER_RAMON_OFFRAM2_RAM2Off     (0UL)                                   
+#define POWER_RAMON_OFFRAM2_RAM2On      (1UL)                                  
+/* The field POWER.RAMON.ONRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
+#define POWER_RAMON_ONRAM3_Pos          (3UL)                                  
+#define POWER_RAMON_ONRAM3_Msk          (0x1UL << POWER_RAMON_ONRAM3_Pos)      
+#define POWER_RAMON_ONRAM3_RAM3Off      (0UL)                                  
+#define POWER_RAMON_ONRAM3_RAM3On       (1UL)                                  
+/* The field POWER.RAMON.ONRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
+#define POWER_RAMON_ONRAM2_Pos          (2UL)                                  
+#define POWER_RAMON_ONRAM2_Msk          (0x1UL << POWER_RAMON_ONRAM2_Pos)       
+#define POWER_RAMON_ONRAM2_RAM2Off      (0UL)                                  
+#define POWER_RAMON_ONRAM2_RAM2On       (1UL)                                 
+
+ 
+/* RADIO */
+/* The enumerated value RADIO.TXPOWER.TXPOWER.Neg40dBm was renamed. Added into deprecated with the new macro name. */
+#define RADIO_TXPOWER_TXPOWER_Neg40dBm  RADIO_TXPOWER_TXPOWER_Neg30dBm      
+/* The name of the field SKIPADDR was corrected. Old macros added for compatibility. */
+#define RADIO_CRCCNF_SKIP_ADDR_Pos      RADIO_CRCCNF_SKIPADDR_Pos 
+#define RADIO_CRCCNF_SKIP_ADDR_Msk      RADIO_CRCCNF_SKIPADDR_Msk 
+#define RADIO_CRCCNF_SKIP_ADDR_Include  RADIO_CRCCNF_SKIPADDR_Include 
+#define RADIO_CRCCNF_SKIP_ADDR_Skip     RADIO_CRCCNF_SKIPADDR_Skip 
+/* The name of the field PLLLOCK was corrected. Old macros added for compatibility. */
+#define RADIO_TEST_PLL_LOCK_Pos         RADIO_TEST_PLLLOCK_Pos 
+#define RADIO_TEST_PLL_LOCK_Msk         RADIO_TEST_PLLLOCK_Msk 
+#define RADIO_TEST_PLL_LOCK_Disabled    RADIO_TEST_PLLLOCK_Disabled 
+#define RADIO_TEST_PLL_LOCK_Enabled     RADIO_TEST_PLLLOCK_Enabled 
+/* The name of the field CONSTCARRIER was corrected. Old macros added for compatibility. */
+#define RADIO_TEST_CONST_CARRIER_Pos        RADIO_TEST_CONSTCARRIER_Pos 
+#define RADIO_TEST_CONST_CARRIER_Msk        RADIO_TEST_CONSTCARRIER_Msk 
+#define RADIO_TEST_CONST_CARRIER_Disabled   RADIO_TEST_CONSTCARRIER_Disabled 
+#define RADIO_TEST_CONST_CARRIER_Enabled    RADIO_TEST_CONSTCARRIER_Enabled 
+
+
+/* FICR */
+/* The registers FICR.SIZERAMBLOCK0, FICR.SIZERAMBLOCK1, FICR.SIZERAMBLOCK2 and FICR.SIZERAMBLOCK3 were renamed into an array. */
+#define SIZERAMBLOCK0   SIZERAMBLOCKS                   
+#define SIZERAMBLOCK1   SIZERAMBLOCKS                   
+#define SIZERAMBLOCK2   SIZERAMBLOCK[2]                 /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
+#define SIZERAMBLOCK3   SIZERAMBLOCK[3]                 /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
+/* The registers FICR.DEVICEID0 and FICR.DEVICEID1 were renamed into an array. */
+#define DEVICEID0       DEVICEID[0]                     
+#define DEVICEID1       DEVICEID[1]                     
+/* The registers FICR.ER0, FICR.ER1, FICR.ER2 and FICR.ER3 were renamed into an array. */
+#define ER0             ER[0]                           
+#define ER1             ER[1]                          
+#define ER2             ER[2]                       
+#define ER3             ER[3]                      
+/* The registers FICR.IR0, FICR.IR1, FICR.IR2 and FICR.IR3 were renamed into an array. */
+#define IR0             IR[0]                         
+#define IR1             IR[1]                         
+#define IR2             IR[2]                         
+#define IR3             IR[3]                          
+/* The registers FICR.DEVICEADDR0 and FICR.DEVICEADDR1 were renamed into an array. */
+#define DEVICEADDR0     DEVICEADDR[0]                  
+#define DEVICEADDR1     DEVICEADDR[1]                  
+
+
+/* PPI */
+/* The tasks PPI.TASKS_CHGxEN and PPI.TASKS_CHGxDIS were renamed into an array of structs. */
+#define TASKS_CHG0EN     TASKS_CHG[0].EN                    
+#define TASKS_CHG0DIS    TASKS_CHG[0].DIS                  
+#define TASKS_CHG1EN     TASKS_CHG[1].EN                    
+#define TASKS_CHG1DIS    TASKS_CHG[1].DIS                  
+#define TASKS_CHG2EN     TASKS_CHG[2].EN                   
+#define TASKS_CHG2DIS    TASKS_CHG[2].DIS                  
+#define TASKS_CHG3EN     TASKS_CHG[3].EN                    
+#define TASKS_CHG3DIS    TASKS_CHG[3].DIS                  
+/* The registers PPI.CHx_EEP and PPI.CHx_TEP were renamed into an array of structs. */
+#define CH0_EEP          CH[0].EEP                          
+#define CH0_TEP          CH[0].TEP                          
+#define CH1_EEP          CH[1].EEP                         
+#define CH1_TEP          CH[1].TEP                         
+#define CH2_EEP          CH[2].EEP                          
+#define CH2_TEP          CH[2].TEP                         
+#define CH3_EEP          CH[3].EEP                          
+#define CH3_TEP          CH[3].TEP                         
+#define CH4_EEP          CH[4].EEP                         
+#define CH4_TEP          CH[4].TEP                         
+#define CH5_EEP          CH[5].EEP                          
+#define CH5_TEP          CH[5].TEP                          
+#define CH6_EEP          CH[6].EEP                          
+#define CH6_TEP          CH[6].TEP                         
+#define CH7_EEP          CH[7].EEP                          
+#define CH7_TEP          CH[7].TEP                          
+#define CH8_EEP          CH[8].EEP                         
+#define CH8_TEP          CH[8].TEP                          
+#define CH9_EEP          CH[9].EEP                          
+#define CH9_TEP          CH[9].TEP                          
+#define CH10_EEP         CH[10].EEP                         
+#define CH10_TEP         CH[10].TEP                         
+#define CH11_EEP         CH[11].EEP                         
+#define CH11_TEP         CH[11].TEP                         
+#define CH12_EEP         CH[12].EEP                         
+#define CH12_TEP         CH[12].TEP                         
+#define CH13_EEP         CH[13].EEP                         
+#define CH13_TEP         CH[13].TEP                         
+#define CH14_EEP         CH[14].EEP                         
+#define CH14_TEP         CH[14].TEP                         
+#define CH15_EEP         CH[15].EEP                         
+#define CH15_TEP         CH[15].TEP                        
+/* The registers PPI.CHG0, PPI.CHG1, PPI.CHG2 and PPI.CHG3 were renamed into an array. */
+#define CHG0             CHG[0]                            
+#define CHG1             CHG[1]                            
+#define CHG2             CHG[2]                             
+#define CHG3             CHG[3]                           
+/* All bitfield macros for the CHGx registers therefore changed name. */
+#define PPI_CHG0_CH15_Pos       PPI_CHG_CH15_Pos            
+#define PPI_CHG0_CH15_Msk       PPI_CHG_CH15_Msk            
+#define PPI_CHG0_CH15_Excluded  PPI_CHG_CH15_Excluded       
+#define PPI_CHG0_CH15_Included  PPI_CHG_CH15_Included       
+#define PPI_CHG0_CH14_Pos       PPI_CHG_CH14_Pos            
+#define PPI_CHG0_CH14_Msk       PPI_CHG_CH14_Msk           
+#define PPI_CHG0_CH14_Excluded  PPI_CHG_CH14_Excluded       
+#define PPI_CHG0_CH14_Included  PPI_CHG_CH14_Included       
+#define PPI_CHG0_CH13_Pos       PPI_CHG_CH13_Pos            
+#define PPI_CHG0_CH13_Msk       PPI_CHG_CH13_Msk            
+#define PPI_CHG0_CH13_Excluded  PPI_CHG_CH13_Excluded      
+#define PPI_CHG0_CH13_Included  PPI_CHG_CH13_Included       
+#define PPI_CHG0_CH12_Pos       PPI_CHG_CH12_Pos            
+#define PPI_CHG0_CH12_Msk       PPI_CHG_CH12_Msk            
+#define PPI_CHG0_CH12_Excluded  PPI_CHG_CH12_Excluded       
+#define PPI_CHG0_CH12_Included  PPI_CHG_CH12_Included       
+#define PPI_CHG0_CH11_Pos       PPI_CHG_CH11_Pos            
+#define PPI_CHG0_CH11_Msk       PPI_CHG_CH11_Msk            
+#define PPI_CHG0_CH11_Excluded  PPI_CHG_CH11_Excluded       
+#define PPI_CHG0_CH11_Included  PPI_CHG_CH11_Included       
+#define PPI_CHG0_CH10_Pos       PPI_CHG_CH10_Pos            
+#define PPI_CHG0_CH10_Msk       PPI_CHG_CH10_Msk            
+#define PPI_CHG0_CH10_Excluded  PPI_CHG_CH10_Excluded       
+#define PPI_CHG0_CH10_Included  PPI_CHG_CH10_Included       
+#define PPI_CHG0_CH9_Pos        PPI_CHG_CH9_Pos             
+#define PPI_CHG0_CH9_Msk        PPI_CHG_CH9_Msk             
+#define PPI_CHG0_CH9_Excluded   PPI_CHG_CH9_Excluded        
+#define PPI_CHG0_CH9_Included   PPI_CHG_CH9_Included        
+#define PPI_CHG0_CH8_Pos        PPI_CHG_CH8_Pos             
+#define PPI_CHG0_CH8_Msk        PPI_CHG_CH8_Msk             
+#define PPI_CHG0_CH8_Excluded   PPI_CHG_CH8_Excluded        
+#define PPI_CHG0_CH8_Included   PPI_CHG_CH8_Included        
+#define PPI_CHG0_CH7_Pos        PPI_CHG_CH7_Pos             
+#define PPI_CHG0_CH7_Msk        PPI_CHG_CH7_Msk             
+#define PPI_CHG0_CH7_Excluded   PPI_CHG_CH7_Excluded        
+#define PPI_CHG0_CH7_Included   PPI_CHG_CH7_Included        
+#define PPI_CHG0_CH6_Pos        PPI_CHG_CH6_Pos             
+#define PPI_CHG0_CH6_Msk        PPI_CHG_CH6_Msk             
+#define PPI_CHG0_CH6_Excluded   PPI_CHG_CH6_Excluded        
+#define PPI_CHG0_CH6_Included   PPI_CHG_CH6_Included        
+#define PPI_CHG0_CH5_Pos        PPI_CHG_CH5_Pos             
+#define PPI_CHG0_CH5_Msk        PPI_CHG_CH5_Msk             
+#define PPI_CHG0_CH5_Excluded   PPI_CHG_CH5_Excluded       
+#define PPI_CHG0_CH5_Included   PPI_CHG_CH5_Included        
+#define PPI_CHG0_CH4_Pos        PPI_CHG_CH4_Pos             
+#define PPI_CHG0_CH4_Msk        PPI_CHG_CH4_Msk             
+#define PPI_CHG0_CH4_Excluded   PPI_CHG_CH4_Excluded       
+#define PPI_CHG0_CH4_Included   PPI_CHG_CH4_Included       
+#define PPI_CHG0_CH3_Pos        PPI_CHG_CH3_Pos             
+#define PPI_CHG0_CH3_Msk        PPI_CHG_CH3_Msk            
+#define PPI_CHG0_CH3_Excluded   PPI_CHG_CH3_Excluded        
+#define PPI_CHG0_CH3_Included   PPI_CHG_CH3_Included       
+#define PPI_CHG0_CH2_Pos        PPI_CHG_CH2_Pos            
+#define PPI_CHG0_CH2_Msk        PPI_CHG_CH2_Msk             
+#define PPI_CHG0_CH2_Excluded   PPI_CHG_CH2_Excluded       
+#define PPI_CHG0_CH2_Included   PPI_CHG_CH2_Included       
+#define PPI_CHG0_CH1_Pos        PPI_CHG_CH1_Pos            
+#define PPI_CHG0_CH1_Msk        PPI_CHG_CH1_Msk            
+#define PPI_CHG0_CH1_Excluded   PPI_CHG_CH1_Excluded        
+#define PPI_CHG0_CH1_Included   PPI_CHG_CH1_Included       
+#define PPI_CHG0_CH0_Pos        PPI_CHG_CH0_Pos            
+#define PPI_CHG0_CH0_Msk        PPI_CHG_CH0_Msk            
+#define PPI_CHG0_CH0_Excluded   PPI_CHG_CH0_Excluded        
+#define PPI_CHG0_CH0_Included   PPI_CHG_CH0_Included       
+#define PPI_CHG1_CH15_Pos       PPI_CHG_CH15_Pos           
+#define PPI_CHG1_CH15_Msk       PPI_CHG_CH15_Msk           
+#define PPI_CHG1_CH15_Excluded  PPI_CHG_CH15_Excluded       
+#define PPI_CHG1_CH15_Included  PPI_CHG_CH15_Included      
+#define PPI_CHG1_CH14_Pos       PPI_CHG_CH14_Pos           
+#define PPI_CHG1_CH14_Msk       PPI_CHG_CH14_Msk            
+#define PPI_CHG1_CH14_Excluded  PPI_CHG_CH14_Excluded      
+#define PPI_CHG1_CH14_Included  PPI_CHG_CH14_Included       
+#define PPI_CHG1_CH13_Pos       PPI_CHG_CH13_Pos           
+#define PPI_CHG1_CH13_Msk       PPI_CHG_CH13_Msk            
+#define PPI_CHG1_CH13_Excluded  PPI_CHG_CH13_Excluded      
+#define PPI_CHG1_CH13_Included  PPI_CHG_CH13_Included      
+#define PPI_CHG1_CH12_Pos       PPI_CHG_CH12_Pos            
+#define PPI_CHG1_CH12_Msk       PPI_CHG_CH12_Msk           
+#define PPI_CHG1_CH12_Excluded  PPI_CHG_CH12_Excluded      
+#define PPI_CHG1_CH12_Included  PPI_CHG_CH12_Included      
+#define PPI_CHG1_CH11_Pos       PPI_CHG_CH11_Pos            
+#define PPI_CHG1_CH11_Msk       PPI_CHG_CH11_Msk           
+#define PPI_CHG1_CH11_Excluded  PPI_CHG_CH11_Excluded      
+#define PPI_CHG1_CH11_Included  PPI_CHG_CH11_Included      
+#define PPI_CHG1_CH10_Pos       PPI_CHG_CH10_Pos           
+#define PPI_CHG1_CH10_Msk       PPI_CHG_CH10_Msk            
+#define PPI_CHG1_CH10_Excluded  PPI_CHG_CH10_Excluded      
+#define PPI_CHG1_CH10_Included  PPI_CHG_CH10_Included      
+#define PPI_CHG1_CH9_Pos        PPI_CHG_CH9_Pos            
+#define PPI_CHG1_CH9_Msk        PPI_CHG_CH9_Msk            
+#define PPI_CHG1_CH9_Excluded   PPI_CHG_CH9_Excluded       
+#define PPI_CHG1_CH9_Included   PPI_CHG_CH9_Included       
+#define PPI_CHG1_CH8_Pos        PPI_CHG_CH8_Pos            
+#define PPI_CHG1_CH8_Msk        PPI_CHG_CH8_Msk            
+#define PPI_CHG1_CH8_Excluded   PPI_CHG_CH8_Excluded       
+#define PPI_CHG1_CH8_Included   PPI_CHG_CH8_Included       
+#define PPI_CHG1_CH7_Pos        PPI_CHG_CH7_Pos             
+#define PPI_CHG1_CH7_Msk        PPI_CHG_CH7_Msk            
+#define PPI_CHG1_CH7_Excluded   PPI_CHG_CH7_Excluded        
+#define PPI_CHG1_CH7_Included   PPI_CHG_CH7_Included       
+#define PPI_CHG1_CH6_Pos        PPI_CHG_CH6_Pos             
+#define PPI_CHG1_CH6_Msk        PPI_CHG_CH6_Msk            
+#define PPI_CHG1_CH6_Excluded   PPI_CHG_CH6_Excluded       
+#define PPI_CHG1_CH6_Included   PPI_CHG_CH6_Included       
+#define PPI_CHG1_CH5_Pos        PPI_CHG_CH5_Pos             
+#define PPI_CHG1_CH5_Msk        PPI_CHG_CH5_Msk             
+#define PPI_CHG1_CH5_Excluded   PPI_CHG_CH5_Excluded       
+#define PPI_CHG1_CH5_Included   PPI_CHG_CH5_Included        
+#define PPI_CHG1_CH4_Pos        PPI_CHG_CH4_Pos             
+#define PPI_CHG1_CH4_Msk        PPI_CHG_CH4_Msk             
+#define PPI_CHG1_CH4_Excluded   PPI_CHG_CH4_Excluded        
+#define PPI_CHG1_CH4_Included   PPI_CHG_CH4_Included        
+#define PPI_CHG1_CH3_Pos        PPI_CHG_CH3_Pos            
+#define PPI_CHG1_CH3_Msk        PPI_CHG_CH3_Msk             
+#define PPI_CHG1_CH3_Excluded   PPI_CHG_CH3_Excluded        
+#define PPI_CHG1_CH3_Included   PPI_CHG_CH3_Included       
+#define PPI_CHG1_CH2_Pos        PPI_CHG_CH2_Pos            
+#define PPI_CHG1_CH2_Msk        PPI_CHG_CH2_Msk             
+#define PPI_CHG1_CH2_Excluded   PPI_CHG_CH2_Excluded        
+#define PPI_CHG1_CH2_Included   PPI_CHG_CH2_Included        
+#define PPI_CHG1_CH1_Pos        PPI_CHG_CH1_Pos             
+#define PPI_CHG1_CH1_Msk        PPI_CHG_CH1_Msk            
+#define PPI_CHG1_CH1_Excluded   PPI_CHG_CH1_Excluded        
+#define PPI_CHG1_CH1_Included   PPI_CHG_CH1_Included       
+#define PPI_CHG1_CH0_Pos        PPI_CHG_CH0_Pos             
+#define PPI_CHG1_CH0_Msk        PPI_CHG_CH0_Msk            
+#define PPI_CHG1_CH0_Excluded   PPI_CHG_CH0_Excluded       
+#define PPI_CHG1_CH0_Included   PPI_CHG_CH0_Included       
+#define PPI_CHG2_CH15_Pos       PPI_CHG_CH15_Pos           
+#define PPI_CHG2_CH15_Msk       PPI_CHG_CH15_Msk            
+#define PPI_CHG2_CH15_Excluded  PPI_CHG_CH15_Excluded      
+#define PPI_CHG2_CH15_Included  PPI_CHG_CH15_Included      
+#define PPI_CHG2_CH14_Pos       PPI_CHG_CH14_Pos           
+#define PPI_CHG2_CH14_Msk       PPI_CHG_CH14_Msk           
+#define PPI_CHG2_CH14_Excluded  PPI_CHG_CH14_Excluded       
+#define PPI_CHG2_CH14_Included  PPI_CHG_CH14_Included      
+#define PPI_CHG2_CH13_Pos       PPI_CHG_CH13_Pos           
+#define PPI_CHG2_CH13_Msk       PPI_CHG_CH13_Msk            
+#define PPI_CHG2_CH13_Excluded  PPI_CHG_CH13_Excluded       
+#define PPI_CHG2_CH13_Included  PPI_CHG_CH13_Included      
+#define PPI_CHG2_CH12_Pos       PPI_CHG_CH12_Pos            
+#define PPI_CHG2_CH12_Msk       PPI_CHG_CH12_Msk            
+#define PPI_CHG2_CH12_Excluded  PPI_CHG_CH12_Excluded      
+#define PPI_CHG2_CH12_Included  PPI_CHG_CH12_Included       
+#define PPI_CHG2_CH11_Pos       PPI_CHG_CH11_Pos           
+#define PPI_CHG2_CH11_Msk       PPI_CHG_CH11_Msk           
+#define PPI_CHG2_CH11_Excluded  PPI_CHG_CH11_Excluded       
+#define PPI_CHG2_CH11_Included  PPI_CHG_CH11_Included       
+#define PPI_CHG2_CH10_Pos       PPI_CHG_CH10_Pos            
+#define PPI_CHG2_CH10_Msk       PPI_CHG_CH10_Msk            
+#define PPI_CHG2_CH10_Excluded  PPI_CHG_CH10_Excluded      
+#define PPI_CHG2_CH10_Included  PPI_CHG_CH10_Included      
+#define PPI_CHG2_CH9_Pos        PPI_CHG_CH9_Pos            
+#define PPI_CHG2_CH9_Msk        PPI_CHG_CH9_Msk            
+#define PPI_CHG2_CH9_Excluded   PPI_CHG_CH9_Excluded        
+#define PPI_CHG2_CH9_Included   PPI_CHG_CH9_Included       
+#define PPI_CHG2_CH8_Pos        PPI_CHG_CH8_Pos            
+#define PPI_CHG2_CH8_Msk        PPI_CHG_CH8_Msk            
+#define PPI_CHG2_CH8_Excluded   PPI_CHG_CH8_Excluded       
+#define PPI_CHG2_CH8_Included   PPI_CHG_CH8_Included        
+#define PPI_CHG2_CH7_Pos        PPI_CHG_CH7_Pos            
+#define PPI_CHG2_CH7_Msk        PPI_CHG_CH7_Msk            
+#define PPI_CHG2_CH7_Excluded   PPI_CHG_CH7_Excluded       
+#define PPI_CHG2_CH7_Included   PPI_CHG_CH7_Included       
+#define PPI_CHG2_CH6_Pos        PPI_CHG_CH6_Pos            
+#define PPI_CHG2_CH6_Msk        PPI_CHG_CH6_Msk            
+#define PPI_CHG2_CH6_Excluded   PPI_CHG_CH6_Excluded       
+#define PPI_CHG2_CH6_Included   PPI_CHG_CH6_Included       
+#define PPI_CHG2_CH5_Pos        PPI_CHG_CH5_Pos            
+#define PPI_CHG2_CH5_Msk        PPI_CHG_CH5_Msk            
+#define PPI_CHG2_CH5_Excluded   PPI_CHG_CH5_Excluded       
+#define PPI_CHG2_CH5_Included   PPI_CHG_CH5_Included        
+#define PPI_CHG2_CH4_Pos        PPI_CHG_CH4_Pos             
+#define PPI_CHG2_CH4_Msk        PPI_CHG_CH4_Msk             
+#define PPI_CHG2_CH4_Excluded   PPI_CHG_CH4_Excluded        
+#define PPI_CHG2_CH4_Included   PPI_CHG_CH4_Included       
+#define PPI_CHG2_CH3_Pos        PPI_CHG_CH3_Pos            
+#define PPI_CHG2_CH3_Msk        PPI_CHG_CH3_Msk            
+#define PPI_CHG2_CH3_Excluded   PPI_CHG_CH3_Excluded       
+#define PPI_CHG2_CH3_Included   PPI_CHG_CH3_Included       
+#define PPI_CHG2_CH2_Pos        PPI_CHG_CH2_Pos            
+#define PPI_CHG2_CH2_Msk        PPI_CHG_CH2_Msk           
+#define PPI_CHG2_CH2_Excluded   PPI_CHG_CH2_Excluded       
+#define PPI_CHG2_CH2_Included   PPI_CHG_CH2_Included       
+#define PPI_CHG2_CH1_Pos        PPI_CHG_CH1_Pos             
+#define PPI_CHG2_CH1_Msk        PPI_CHG_CH1_Msk             
+#define PPI_CHG2_CH1_Excluded   PPI_CHG_CH1_Excluded       
+#define PPI_CHG2_CH1_Included   PPI_CHG_CH1_Included       
+#define PPI_CHG2_CH0_Pos        PPI_CHG_CH0_Pos            
+#define PPI_CHG2_CH0_Msk        PPI_CHG_CH0_Msk            
+#define PPI_CHG2_CH0_Excluded   PPI_CHG_CH0_Excluded       
+#define PPI_CHG2_CH0_Included   PPI_CHG_CH0_Included        
+#define PPI_CHG3_CH15_Pos       PPI_CHG_CH15_Pos           
+#define PPI_CHG3_CH15_Msk       PPI_CHG_CH15_Msk           
+#define PPI_CHG3_CH15_Excluded  PPI_CHG_CH15_Excluded     
+#define PPI_CHG3_CH15_Included  PPI_CHG_CH15_Included      
+#define PPI_CHG3_CH14_Pos       PPI_CHG_CH14_Pos          
+#define PPI_CHG3_CH14_Msk       PPI_CHG_CH14_Msk           
+#define PPI_CHG3_CH14_Excluded  PPI_CHG_CH14_Excluded      
+#define PPI_CHG3_CH14_Included  PPI_CHG_CH14_Included       
+#define PPI_CHG3_CH13_Pos       PPI_CHG_CH13_Pos           
+#define PPI_CHG3_CH13_Msk       PPI_CHG_CH13_Msk            
+#define PPI_CHG3_CH13_Excluded  PPI_CHG_CH13_Excluded      
+#define PPI_CHG3_CH13_Included  PPI_CHG_CH13_Included      
+#define PPI_CHG3_CH12_Pos       PPI_CHG_CH12_Pos            
+#define PPI_CHG3_CH12_Msk       PPI_CHG_CH12_Msk            
+#define PPI_CHG3_CH12_Excluded  PPI_CHG_CH12_Excluded       
+#define PPI_CHG3_CH12_Included  PPI_CHG_CH12_Included       
+#define PPI_CHG3_CH11_Pos       PPI_CHG_CH11_Pos            
+#define PPI_CHG3_CH11_Msk       PPI_CHG_CH11_Msk            
+#define PPI_CHG3_CH11_Excluded  PPI_CHG_CH11_Excluded      
+#define PPI_CHG3_CH11_Included  PPI_CHG_CH11_Included       
+#define PPI_CHG3_CH10_Pos       PPI_CHG_CH10_Pos            
+#define PPI_CHG3_CH10_Msk       PPI_CHG_CH10_Msk            
+#define PPI_CHG3_CH10_Excluded  PPI_CHG_CH10_Excluded      
+#define PPI_CHG3_CH10_Included  PPI_CHG_CH10_Included      
+#define PPI_CHG3_CH9_Pos        PPI_CHG_CH9_Pos            
+#define PPI_CHG3_CH9_Msk        PPI_CHG_CH9_Msk            
+#define PPI_CHG3_CH9_Excluded   PPI_CHG_CH9_Excluded       
+#define PPI_CHG3_CH9_Included   PPI_CHG_CH9_Included       
+#define PPI_CHG3_CH8_Pos        PPI_CHG_CH8_Pos            
+#define PPI_CHG3_CH8_Msk        PPI_CHG_CH8_Msk             
+#define PPI_CHG3_CH8_Excluded   PPI_CHG_CH8_Excluded       
+#define PPI_CHG3_CH8_Included   PPI_CHG_CH8_Included       
+#define PPI_CHG3_CH7_Pos        PPI_CHG_CH7_Pos             
+#define PPI_CHG3_CH7_Msk        PPI_CHG_CH7_Msk            
+#define PPI_CHG3_CH7_Excluded   PPI_CHG_CH7_Excluded        
+#define PPI_CHG3_CH7_Included   PPI_CHG_CH7_Included       
+#define PPI_CHG3_CH6_Pos        PPI_CHG_CH6_Pos             
+#define PPI_CHG3_CH6_Msk        PPI_CHG_CH6_Msk             
+#define PPI_CHG3_CH6_Excluded   PPI_CHG_CH6_Excluded       
+#define PPI_CHG3_CH6_Included   PPI_CHG_CH6_Included        
+#define PPI_CHG3_CH5_Pos        PPI_CHG_CH5_Pos             
+#define PPI_CHG3_CH5_Msk        PPI_CHG_CH5_Msk             
+#define PPI_CHG3_CH5_Excluded   PPI_CHG_CH5_Excluded        
+#define PPI_CHG3_CH5_Included   PPI_CHG_CH5_Included       
+#define PPI_CHG3_CH4_Pos        PPI_CHG_CH4_Pos             
+#define PPI_CHG3_CH4_Msk        PPI_CHG_CH4_Msk            
+#define PPI_CHG3_CH4_Excluded   PPI_CHG_CH4_Excluded        
+#define PPI_CHG3_CH4_Included   PPI_CHG_CH4_Included        
+#define PPI_CHG3_CH3_Pos        PPI_CHG_CH3_Pos             
+#define PPI_CHG3_CH3_Msk        PPI_CHG_CH3_Msk            
+#define PPI_CHG3_CH3_Excluded   PPI_CHG_CH3_Excluded        
+#define PPI_CHG3_CH3_Included   PPI_CHG_CH3_Included        
+#define PPI_CHG3_CH2_Pos        PPI_CHG_CH2_Pos             
+#define PPI_CHG3_CH2_Msk        PPI_CHG_CH2_Msk             
+#define PPI_CHG3_CH2_Excluded   PPI_CHG_CH2_Excluded        
+#define PPI_CHG3_CH2_Included   PPI_CHG_CH2_Included       
+#define PPI_CHG3_CH1_Pos        PPI_CHG_CH1_Pos             
+#define PPI_CHG3_CH1_Msk        PPI_CHG_CH1_Msk             
+#define PPI_CHG3_CH1_Excluded   PPI_CHG_CH1_Excluded        
+#define PPI_CHG3_CH1_Included   PPI_CHG_CH1_Included        
+#define PPI_CHG3_CH0_Pos        PPI_CHG_CH0_Pos             
+#define PPI_CHG3_CH0_Msk        PPI_CHG_CH0_Msk             
+#define PPI_CHG3_CH0_Excluded   PPI_CHG_CH0_Excluded        
+#define PPI_CHG3_CH0_Included   PPI_CHG_CH0_Included        
+
+
+
+/*lint --flb "Leave library region" */
+
+#endif /* NRF51_DEPRECATED_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/ble_flash/ble_flash.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_flash.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "nrf.h"
+#include "app_util.h"
+
+
+static volatile bool m_radio_active = false;  /**< TRUE if radio is active (or about to become active), FALSE otherwise. */
+
+
+uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc)
+{
+    uint16_t i;
+    uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc;
+
+    for (i = 0; i < size; i++)
+    {
+        crc  = (unsigned char)(crc >> 8) | (crc << 8);
+        crc ^= p_data[i];
+        crc ^= (unsigned char)(crc & 0xff) >> 4;
+        crc ^= (crc << 8) << 4;
+        crc ^= ((crc & 0xff) << 4) << 1;
+    }
+    return crc;
+}
+
+
+/**@brief Function for erasing a page in flash.
+ * 
+ * @param[in]  p_page  Pointer to first word in page to be erased.
+ */
+static void flash_page_erase(uint32_t * p_page)
+{
+    // Turn on flash erase enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+
+    // Erase page.
+    NRF_NVMC->ERASEPAGE = (uint32_t)p_page;
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+
+    // Turn off flash erase enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing
+    }
+}
+
+
+/**@brief Function for writing one word to flash. Unprotected write, which can interfere with radio communication.
+ *
+ * @details This function DOES NOT use the m_radio_active variable, but will force the write even
+ *          when the radio is active. To be used only from @ref ble_flash_page_write.
+ *
+ * @note Flash location to be written must have been erased previously.
+ *
+ * @param[in]  p_address   Pointer to flash location to be written.
+ * @param[in]  value       Value to write to flash.
+ */
+static void flash_word_unprotected_write(uint32_t * p_address, uint32_t value)
+{
+    // Turn on flash write enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+    *p_address = value;
+    
+    // Wait flash write to finish
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+
+    // Turn off flash write enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+}
+
+
+/**@brief Function for writing one word to flash.
+ *
+ * @note Flash location to be written must have been erased previously.
+ *
+ * @param[in]  p_address   Pointer to flash location to be written.
+ * @param[in]  value       Value to write to flash.
+ */
+static void flash_word_write(uint32_t * p_address, uint32_t value)
+{
+    // If radio is active, wait for it to become inactive.
+    while (m_radio_active)
+    {
+        // Do nothing (just wait for radio to become inactive).
+        (void) sd_app_evt_wait();
+    }
+
+    // Turn on flash write enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+
+    *p_address = value;
+    // Wait flash write to finish
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing.
+    }
+    // Turn off flash write enable and wait until the NVMC is ready.
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+        // Do nothing
+    }
+}
+
+
+uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value)
+{
+    flash_word_write(p_address, value);
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count)
+{
+    uint16_t i;
+
+    for (i = 0; i < word_count; i++)
+    {
+        flash_word_write(p_address, p_in_array[i]);
+        p_address++;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_flash_page_erase(uint8_t page_num)
+{
+    uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
+    flash_page_erase(p_page);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count)
+{
+    int        i;
+    uint32_t * p_page;
+    uint32_t * p_curr_addr;
+    uint16_t   in_data_crc;
+    uint16_t   flash_crc;
+    uint32_t   flash_header;
+
+    p_page      = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
+    p_curr_addr = p_page;
+
+    // Calculate CRC of the data to write.
+    in_data_crc = ble_flash_crc16_compute((uint8_t *)p_in_array,
+                                          word_count * sizeof(uint32_t),
+                                          NULL);
+
+    // Compare the calculated to the one in flash.
+    flash_header = *p_curr_addr;
+    flash_crc    = (uint16_t)flash_header;
+
+    if (flash_crc == in_data_crc)
+    {
+        // Data is the same as the data already stored in flash, return without modifying flash.
+        return NRF_SUCCESS;
+    }
+
+    // Erase flash page
+    flash_page_erase(p_page);
+
+    // Reserve space for magic number (for detecting if flash content is valid).
+    p_curr_addr++;
+
+    // Reserve space for saving word_count.
+    p_curr_addr++;
+
+    // Write data
+    for (i = 0; i < word_count; i++)
+    {
+        flash_word_unprotected_write(p_curr_addr, p_in_array[i]);
+        p_curr_addr++;
+    }
+
+    // Write number of elements.
+    flash_word_write(p_page + 1, (uint32_t)(word_count));
+
+    // Write magic number and CRC to indicate that flash content is valid.
+    flash_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)in_data_crc;
+    flash_word_write(p_page, flash_header);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count)
+{
+    int        byte_count;
+    uint32_t * p_page;
+    uint32_t * p_curr_addr;
+    uint32_t   flash_header;
+    uint32_t   calc_header;
+    uint16_t   calc_crc;
+    uint32_t   tmp;
+
+    p_page      = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);    
+    p_curr_addr = p_page;
+
+    // Check if block is valid
+    flash_header = *p_curr_addr;
+    tmp = flash_header & 0xFFFF0000;
+    if (tmp != BLE_FLASH_MAGIC_NUMBER)
+    {
+        *p_word_count = 0;
+        return NRF_ERROR_NOT_FOUND;
+    }
+    p_curr_addr++;
+
+    // Read number of elements
+    *p_word_count = (uint8_t)(*(p_curr_addr));
+    p_curr_addr++;
+
+    // Read data
+    byte_count = (*p_word_count) * sizeof(uint32_t);
+    memcpy(p_out_array, p_curr_addr, byte_count);
+
+    // Check CRC
+    calc_crc = ble_flash_crc16_compute((uint8_t *)p_out_array,
+                                       (*p_word_count) * sizeof(uint32_t),
+                                       NULL);
+    calc_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)calc_crc;
+
+    if (calc_header != flash_header)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr)
+{
+    *pp_page_addr = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
+    return NRF_SUCCESS;
+}
+
+
+void ble_flash_on_radio_active_evt(bool radio_active)
+{
+    m_radio_active = radio_active;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/ble_flash/ble_flash.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_flash_module Flash Manager
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for accessing flash memory.
+ *
+ * @details It contains functions for reading, writing and erasing one page in flash.
+ *
+ *          The module uses the first 32 bits of the flash page to write a magic number in order to
+ *          determine if the page has been written or not.
+ *
+ * @note Be careful not to use a page number in the SoftDevice area (which currently occupies the
+ *       range 0 to 127), or in your application space! In both cases, this would end up
+ *       with a hard fault.
+ */
+
+#ifndef BLE_FLASH_H__
+#define BLE_FLASH_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+
+#define BLE_FLASH_PAGE_SIZE     ((uint16_t)NRF_FICR->CODEPAGESIZE)  /**< Size of one flash page. */
+#define BLE_FLASH_MAGIC_NUMBER  0x45DE0000                          /**< Magic value to identify if flash contains valid data. */
+#define BLE_FLASH_EMPTY_MASK    0xFFFFFFFF                          /**< Bit mask that defines an empty address in flash. */
+
+
+/**@brief Macro for getting the end of the flash available for application.
+ * 
+ * @details    The result flash page number indicates the end boundary of the flash available 
+ *             to the application. If a bootloader is used, the end will be the start of the 
+ *             bootloader region. Otherwise, the end will be the size of the flash. 
+ */
+#define BLE_FLASH_PAGE_END \
+    ((NRF_UICR->BOOTLOADERADDR != BLE_FLASH_EMPTY_MASK) \
+        ? (NRF_UICR->BOOTLOADERADDR / BLE_FLASH_PAGE_SIZE) \
+        : NRF_FICR->CODESIZE)
+
+/**@brief Function for erasing the specified flash page, and then writes the given data to this page.
+ *
+ * @warning This operation blocks the CPU. DO NOT use while in a connection!
+ *
+ * @param[in]  page_num     Page number to update.
+ * @param[in]  p_in_array   Pointer to a RAM area containing the elements to write in flash.
+ *                          This area has to be 32 bits aligned.
+ * @param[in]  word_count   Number of 32 bits words to write in flash.
+ *
+ * @return     NRF_SUCCESS on successful flash write, otherwise an error code.
+ */
+uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count);
+
+/**@brief Function for reading data from flash to RAM.
+ *
+ * @param[in]  page_num       Page number to read.
+ * @param[out] p_out_array    Pointer to a RAM area where the found data will be written. 
+ *                            This area has to be 32 bits aligned.
+ * @param[out] p_word_count   Number of 32 bits words read.
+ *
+ * @return     NRF_SUCCESS on successful upload, NRF_ERROR_NOT_FOUND if no valid data has been found
+ *             in flash (first 32 bits not equal to the MAGIC_NUMBER+CRC).
+ */
+uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count);
+
+/**@brief Function for erasing a flash page.
+ *
+ * @note This operation blocks the CPU, so it should not be done while the radio is running!
+ *
+ * @param[in]  page_num   Page number to erase.
+ *
+ * @return     NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t ble_flash_page_erase(uint8_t page_num);
+
+/**@brief Function for writing one word to flash.
+ *
+ * @note Flash location to be written must have been erased previously.
+ *
+ * @param[in]  p_address   Pointer to flash location to be written.
+ * @param[in]  value       Value to write to flash.
+ *
+ * @return     NRF_SUCCESS.
+ */
+uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value);
+
+/**@brief Function for writing a data block to flash.
+ *
+ * @note Flash locations to be written must have been erased previously.
+ *
+ * @param[in]  p_address    Pointer to start of flash location to be written.
+ * @param[in]  p_in_array   Pointer to start of flash block to be written.
+ * @param[in]  word_count   Number of words to be written.
+ *
+ * @return     NRF_SUCCESS.
+ */
+uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count);
+
+/**@brief Function for computing pointer to start of specified flash page.
+ *
+ * @param[in]  page_num       Page number.
+ * @param[out] pp_page_addr   Pointer to start of flash page.
+ *
+ * @return     NRF_SUCCESS.
+ */
+uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr);
+
+/**@brief Function for calculating a 16 bit CRC using the CRC-16-CCITT scheme.
+ * 
+ * @param[in]  p_data   Pointer to data on which the CRC is to be calulated.
+ * @param[in]  size     Number of bytes on which the CRC is to be calulated.
+ * @param[in]  p_crc    Initial CRC value (if NULL, a preset value is used as the initial value).
+ *
+ * @return     Calculated CRC.
+ */
+uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc);
+
+/**@brief Function for handling flashing module Radio Notification event.
+ *
+ * @note For flash writing to work safely while in a connection or while advertising, this function
+ *       MUST be called from the Radio Notification module's event handler (see
+ *       @ref ble_radio_notification for details).
+ *
+ * @param[in]  radio_active   TRUE if radio is active (or about to become active), FALSE otherwise.
+ */
+void ble_flash_on_radio_active_evt(bool radio_active);
+
+#endif // BLE_FLASH_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/delay/nrf_delay.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 <stdio.h> 
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#include "nrf_delay.h"
+
+/*lint --e{438} "Variable not used" */
+void nrf_delay_ms(uint32_t volatile number_of_ms)
+{
+    while(number_of_ms != 0)
+    {
+        number_of_ms--;
+        nrf_delay_us(999);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/delay/nrf_delay.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 _NRF_DELAY_H
+#define _NRF_DELAY_H
+
+#include "nrf.h"
+
+/**
+ * @brief Function for delaying execution for number of microseconds.
+ *
+ * @note NRF52 has instruction cache and because of that delay is not precise.
+ *
+ * @param number_of_ms
+ */
+/*lint --e{438, 522} "Variable not used" "Function lacks side-effects" */
+#if defined ( __CC_ARM   )
+
+static __ASM void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
+{
+loop
+        SUBS    R0, R0, #1
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+#ifdef NRF52
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+        NOP
+#endif
+        BNE    loop
+        BX     LR
+}
+
+#elif defined ( __ICCARM__ )
+
+static void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
+{
+__ASM (
+"loop:\n\t"
+       " SUBS R0, R0, #1\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+       " NOP\n\t"
+#ifdef NRF52
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+        " NOP\n\t"
+#endif
+       " BNE.n loop\n\t");
+}
+
+#elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ )
+
+__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us);
+
+#ifndef CUSTOM_NRF_DELAY_US
+__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us)
+{}
+#endif
+
+#elif defined ( __GNUC__ )
+
+static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) __attribute__((always_inline));
+static void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
+{
+register uint32_t delay __ASM ("r0") = number_of_us;
+__ASM volatile (
+#ifdef NRF51
+        ".syntax unified\n"
+#endif
+    "1:\n"
+    " SUBS %0, %0, #1\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"   
+    " NOP\n"  
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+#ifdef NRF52
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+    " NOP\n"
+#endif
+    " BNE 1b\n"
+#ifdef NRF51
+    ".syntax divided\n"
+#endif
+    : "+r" (delay));
+}
+#endif
+
+void nrf_delay_ms(uint32_t volatile number_of_ms);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_ecb.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 Implementation of AES ECB driver
+ */
+
+
+//lint -e438
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include "nrf.h" 
+#include "nrf_ecb.h"
+
+static uint8_t  ecb_data[48];   ///< ECB data structure for RNG peripheral to access.
+static uint8_t* ecb_key;        ///< Key:        Starts at ecb_data 
+static uint8_t* ecb_cleartext;  ///< Cleartext:  Starts at ecb_data + 16 bytes.
+static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes.
+
+bool nrf_ecb_init(void)
+{
+  ecb_key = ecb_data;
+  ecb_cleartext  = ecb_data + 16;
+  ecb_ciphertext = ecb_data + 32;
+
+  NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data;
+  return true;
+}
+
+
+bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf)
+{
+   uint32_t counter = 0x1000000;
+   if(src_buf != ecb_cleartext)
+   {
+     memcpy(ecb_cleartext,src_buf,16);
+   }
+   NRF_ECB->EVENTS_ENDECB = 0;
+   NRF_ECB->TASKS_STARTECB = 1;
+   while(NRF_ECB->EVENTS_ENDECB == 0)
+   {
+    counter--;
+    if(counter == 0)
+    {
+      return false;
+    }
+   }
+   NRF_ECB->EVENTS_ENDECB = 0;
+   if(dest_buf != ecb_ciphertext)
+   {
+     memcpy(dest_buf,ecb_ciphertext,16);
+   }
+   return true;
+}
+
+void nrf_ecb_set_key(const uint8_t * key)
+{
+  memcpy(ecb_key,key,16);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_ecb.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 ECB driver API.
+ */
+
+#ifndef NRF_ECB_H__
+#define NRF_ECB_H__
+
+/**
+ * @defgroup nrf_ecb AES ECB encryption
+ * @{
+ * @ingroup nrf_drivers
+ * @brief Driver for the AES Electronic Code Book (ECB) peripheral.
+ *
+ * To encrypt and decrypt data, the peripheral must first be powered on
+ * using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key.
+ */
+
+#include <stdint.h>
+
+/**
+ * @brief Function for initializing and powering on the ECB peripheral.
+ *
+ * This function allocates memory for the ECBDATAPTR.
+ * @retval true If initialization was successful.
+ * @retval false If powering on failed.
+ */
+bool nrf_ecb_init(void);
+
+/**
+ * @brief Function for encrypting and decrypting 16-byte data using current key.
+ *
+ * This function avoids unnecessary copying of data if the parameters point to the 
+ * correct locations in the ECB data structure.
+ *
+ * @param dst Result of encryption/decryption. 16 bytes will be written. 
+ * @param src Source with 16-byte data to be encrypted/decrypted.
+ *
+ * @retval true  If the encryption operation completed.
+ * @retval false If the encryption operation did not complete.
+ */
+bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src);
+
+/**
+ * @brief Function for setting the key to be used for encryption and decryption.
+ *
+ * @param key Pointer to the key. 16 bytes will be read.
+ */
+void nrf_ecb_set_key(const uint8_t * key);
+
+#endif  // NRF_ECB_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_gpio.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF_GPIO_H__
+#define NRF_GPIO_H__
+
+#include "nrf.h"
+#include <stdbool.h>
+
+/**
+ * @defgroup nrf_gpio GPIO abstraction
+ * @{
+ * @ingroup nrf_drivers
+ * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports.
+ *
+ * Here, the GPIO ports are defined as follows:
+ * - Port 0 -> pin 0-7
+ * - Port 1 -> pin 8-15
+ * - Port 2 -> pin 16-23
+ * - Port 3 -> pin 24-31
+ */
+
+#define NUMBER_OF_PINS 32
+
+/**
+ * @brief Enumerator used for selecting between port 0 - 3.
+ */
+typedef enum
+{
+    NRF_GPIO_PORT_SELECT_PORT0 = 0,           ///<  Port 0 (GPIO pin 0-7)
+    NRF_GPIO_PORT_SELECT_PORT1,               ///<  Port 1 (GPIO pin 8-15)
+    NRF_GPIO_PORT_SELECT_PORT2,               ///<  Port 2 (GPIO pin 16-23)
+    NRF_GPIO_PORT_SELECT_PORT3,               ///<  Port 3 (GPIO pin 24-31)
+} nrf_gpio_port_select_t;
+
+/**
+ * @brief Enumerator used for setting the direction of a GPIO port.
+ */
+typedef enum
+{
+    NRF_GPIO_PORT_DIR_OUTPUT,       ///<  Output
+    NRF_GPIO_PORT_DIR_INPUT         ///<  Input
+} nrf_gpio_port_dir_t;
+
+/**
+ * @brief Pin direction definitions.
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_DIR_INPUT  = GPIO_PIN_CNF_DIR_Input,   ///< Input
+    NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output   ///< Output
+} nrf_gpio_pin_dir_t;
+
+/**
+ * @brief Connection of input buffer
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_INPUT_CONNECT    = GPIO_PIN_CNF_INPUT_Connect,   ///< Connect input buffer
+    NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer
+} nrf_gpio_pin_input_t;
+
+/**
+ * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_NOPULL   = GPIO_PIN_CNF_PULL_Disabled,                 ///<  Pin pullup resistor disabled
+    NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown,                 ///<  Pin pulldown resistor enabled
+    NRF_GPIO_PIN_PULLUP   = GPIO_PIN_CNF_PULL_Pullup,                   ///<  Pin pullup resistor enabled
+} nrf_gpio_pin_pull_t;
+
+/**
+ * @brief Enumerator used for selecting output drive mode
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'
+    NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1'
+    NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1'
+    NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1''
+    NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'
+    NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1'
+    NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1'
+    NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1'
+} nrf_gpio_pin_drive_t;
+
+/**
+ * @brief Enumerator used for selecting the pin to sense high or low level on the pin input.
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_NOSENSE    = GPIO_PIN_CNF_SENSE_Disabled,              ///<  Pin sense level disabled.
+    NRF_GPIO_PIN_SENSE_LOW  = GPIO_PIN_CNF_SENSE_Low,                   ///<  Pin sense low level.
+    NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High,                  ///<  Pin sense high level.
+} nrf_gpio_pin_sense_t;
+
+
+/**
+ * @brief Function for configuring the GPIO pin range as outputs with normal drive strength.
+ *        This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @note For configuring only one pin as output use @ref nrf_gpio_cfg_output
+ *       Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
+ */
+__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end);
+
+/**
+ * @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input.
+ *
+ * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high)
+ *
+ * @note  For configuring only one pin as input use @ref nrf_gpio_cfg_input
+ *        Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
+ */
+__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config);
+
+/**
+ * @brief Pin configuration function
+ *
+ * The main pin configuration function.
+ * This function allows to set any aspect in PIN_CNF register.
+ * @param pin_number Specifies the pin number (allowed values 0-31).
+ * @param dir   Pin direction
+ * @param input Connect or disconnect input buffer
+ * @param pull  Pull configuration
+ * @param drive Drive configuration
+ * @param sense Pin sensing mechanism
+ */
+__STATIC_INLINE void nrf_gpio_cfg(
+        uint32_t             pin_number,
+        nrf_gpio_pin_dir_t   dir,
+        nrf_gpio_pin_input_t input,
+        nrf_gpio_pin_pull_t  pull,
+        nrf_gpio_pin_drive_t drive,
+        nrf_gpio_pin_sense_t sense);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_number specifies the pin number (allowed values 0-31)
+ *
+ * @note  Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
+ */
+__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_number Specifies the pin number (allowed values 0-30).
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high).
+ *
+ * @note  Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
+ */
+__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
+
+/**
+ * @brief Function for reseting pin configuration to its default state.
+ *
+ * @param pin_number Specifies the pin number (allowed values 0-31).
+ */
+__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
+ *
+ * @param pin_number Specifies the pin number (allowed values 0-31).
+ *
+ */
+__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number);
+
+/**
+ * @brief Function for disconnecting input for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number (allowed values 0-31).
+ *
+ */
+__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *        Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable.
+ *
+ * @param pin_number   Specifies the pin number (allowed values 0-30).
+ * @param pull_config  State of the pin pull resistor (no pull, pulled down or pulled high).
+ * @param sense_config Sense level of the pin (no sense, sense low or sense high).
+ */
+__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config);
+
+/**
+ * @brief Function for configuring sense level for the given GPIO.
+ *
+ * @param pin_number   Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30).
+ * @param sense_config Sense configuration.
+ *
+ */
+__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config);
+
+/**
+ * @brief Function for setting the direction for a GPIO pin.
+ *
+ * @param pin_number specifies the pin number [0:31] for which to
+ * set the direction.
+ *
+ * @param direction specifies the direction
+ */
+__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction);
+
+/**
+ * @brief Function for setting a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * set.
+ */
+__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
+
+/**
+ * @brief Function for setting GPIO pins.
+ *
+ * Note that pins must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_mask Specifies the pins to set.
+ * set.
+ */
+__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask);
+
+/**
+ * @brief Function for clearing a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * clear.
+ */
+__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing GPIO pins.
+ *
+ * Note that pins must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_mask Specifies the pins to clear.
+ * set.
+ */
+__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask);
+
+/**
+ * @brief Function for toggling a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * toggle.
+ */
+__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
+
+/**
+ * @brief Function for writing a value to a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * write.
+ *
+ * @param value specifies the value to be written to the pin.
+ * @arg 0 clears the pin
+ * @arg >=1 sets the pin.
+ */
+__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value);
+
+/**
+ * @brief Function for reading the input level of a GPIO pin.
+ *
+ * Note that the pin must have input connected for the value
+ * returned from this function to be valid.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * read.
+ *
+ * @return
+ * @retval 0 if the pin input level is low.
+ * @retval 1 if the pin input level is high.
+ * @retval > 1 should never occur.
+ */
+__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
+
+/**
+ * @brief Function for reading the input level of all GPIO pins.
+ *
+ * Note that the pin must have input connected for the value
+ * returned from this function to be valid.
+ *
+ * @retval Status of input of all pins
+ */
+__STATIC_INLINE uint32_t nrf_gpio_pins_read(void);
+
+/**
+ * @brief Function for reading the sense configuration of a GPIO pin.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * read.
+ *
+ * @retval Sense configuration
+ */
+__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number);
+
+/**
+ * @brief Generic function for writing a single byte of a 32 bit word at a given
+ * address.
+ *
+ * This function should not be called from outside the nrf_gpio
+ * abstraction layer.
+ *
+ * @param word_address is the address of the word to be written.
+ *
+ * @param byte_no is the word byte number (0-3) to be written.
+ *
+ * @param value is the value to be written to byte "byte_no" of word
+ * at address "word_address"
+ */
+__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value);
+
+/**
+ * @brief Generic function for reading a single byte of a 32 bit word at a given
+ * address.
+ *
+ * This function should not be called from outside the nrf_gpio
+ * abstraction layer.
+ *
+ * @param word_address is the address of the word to be read.
+ *
+ * @param byte_no is the byte number (0-3) of the word to be read.
+ *
+ * @return byte "byte_no" of word at address "word_address".
+ */
+__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no);
+
+/**
+ * @brief Function for setting the direction of a port.
+ *
+ * @param port is the port for which to set the direction.
+ *
+ * @param dir direction to be set for this port.
+ */
+__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir);
+
+/**
+ * @brief Function for reading a GPIO port.
+ *
+ * @param port is the port to read.
+ *
+ * @return the input value on this port.
+ */
+__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port);
+
+/**
+ * @brief Function for writing to a GPIO port.
+ *
+ * @param port is the port to write.
+ *
+ * @param value is the value to write to this port.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value);
+
+/**
+ * @brief Function for setting individual pins on GPIO port.
+ *
+ * @param port is the port for which to set the pins.
+ *
+ * @param set_mask is a mask specifying which pins to set. A bit
+ * set to 1 indicates that the corresponding port pin shall be
+ * set.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask);
+
+/**
+ * @brief Function for clearing individual pins on GPIO port.
+ *
+ * @param port is the port for which to clear the pins.
+ *
+ * @param clr_mask is a mask specifying which pins to clear. A bit
+ * set to 1 indicates that the corresponding port pin shall be
+ * cleared.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    for (; pin_range_start <= pin_range_end; pin_range_start++)
+    {
+        nrf_gpio_cfg_output(pin_range_start);
+    }
+}
+
+__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    for (; pin_range_start <= pin_range_end; pin_range_start++)
+    {
+        nrf_gpio_cfg_input(pin_range_start, pull_config);
+    }
+}
+
+__STATIC_INLINE void nrf_gpio_cfg(
+        uint32_t             pin_number,
+        nrf_gpio_pin_dir_t   dir,
+        nrf_gpio_pin_input_t input,
+        nrf_gpio_pin_pull_t  pull,
+        nrf_gpio_pin_drive_t drive,
+        nrf_gpio_pin_sense_t sense)
+{
+    NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir   << GPIO_PIN_CNF_DIR_Pos)
+                                  | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos)
+                                  | ((uint32_t)pull  << GPIO_PIN_CNF_PULL_Pos)
+                                  | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
+                                  | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
+{
+    nrf_gpio_cfg(
+            pin_number,
+            NRF_GPIO_PIN_DIR_OUTPUT,
+            NRF_GPIO_PIN_INPUT_DISCONNECT,
+            NRF_GPIO_PIN_NOPULL,
+            NRF_GPIO_PIN_S0S1,
+            NRF_GPIO_PIN_NOSENSE);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
+{
+    nrf_gpio_cfg(
+            pin_number,
+            NRF_GPIO_PIN_DIR_INPUT,
+            NRF_GPIO_PIN_INPUT_CONNECT,
+            pull_config,
+            NRF_GPIO_PIN_S0S1,
+            NRF_GPIO_PIN_NOSENSE);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number)
+{
+    nrf_gpio_cfg(
+            pin_number,
+            NRF_GPIO_PIN_DIR_INPUT,
+            NRF_GPIO_PIN_INPUT_DISCONNECT,
+            NRF_GPIO_PIN_NOPULL,
+            NRF_GPIO_PIN_S0S1,
+            NRF_GPIO_PIN_NOSENSE);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
+    NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos);
+}
+
+__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
+    NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config)
+{
+    nrf_gpio_cfg(
+            pin_number,
+            NRF_GPIO_PIN_DIR_INPUT,
+            NRF_GPIO_PIN_INPUT_CONNECT,
+            pull_config,
+            NRF_GPIO_PIN_S0S1,
+            sense_config);
+}
+
+__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    //uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk;
+    NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk;
+    NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos);
+}
+
+__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)
+{
+    if(direction == NRF_GPIO_PIN_DIR_INPUT)
+    {
+        nrf_gpio_cfg(
+                pin_number,
+                NRF_GPIO_PIN_DIR_INPUT,
+                NRF_GPIO_PIN_INPUT_CONNECT,
+                NRF_GPIO_PIN_NOPULL,
+                NRF_GPIO_PIN_S0S1,
+                NRF_GPIO_PIN_NOSENSE);
+    }
+    else
+    {
+        NRF_GPIO->DIRSET = (1UL << pin_number);
+    }
+}
+
+__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number)
+{
+    NRF_GPIO->OUTSET = (1UL << pin_number);
+}
+
+__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask)
+{
+    NRF_GPIO->OUTSET = pin_mask;
+}
+
+__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
+{
+    NRF_GPIO->OUTCLR = (1UL << pin_number);
+}
+
+__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask)
+{
+    NRF_GPIO->OUTCLR = pin_mask;
+}
+
+__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
+{
+    const uint32_t pin_bit   = 1UL << pin_number;
+    const uint32_t pin_state = ((NRF_GPIO->OUT >> pin_number) & 1UL);
+
+    if (pin_state == 0)
+    {
+        // Current state low, set high.
+        NRF_GPIO->OUTSET = pin_bit;
+    }
+    else
+    {
+        // Current state high, set low.
+        NRF_GPIO->OUTCLR = pin_bit;
+    }
+}
+
+__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
+{
+    if (value == 0)
+    {
+        nrf_gpio_pin_clear(pin_number);
+    }
+    else
+    {
+        nrf_gpio_pin_set(pin_number);
+    }
+}
+
+__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
+{
+    return  ((NRF_GPIO->IN >> pin_number) & 1UL);
+}
+
+__STATIC_INLINE uint32_t nrf_gpio_pins_read(void)
+{
+    return NRF_GPIO->IN;
+}
+
+__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number)
+{
+    return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos);
+}
+
+__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value)
+{
+    *((volatile uint8_t*)(word_address) + byte_no) = value;
+}
+
+__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no)
+{
+    return (*((const volatile uint8_t*)(word_address) + byte_no));
+}
+
+__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir)
+{
+    if (dir == NRF_GPIO_PORT_DIR_OUTPUT)
+    {
+        nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF);
+    }
+    else
+    {
+        nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL);
+    }
+}
+
+__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port)
+{
+    return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port);
+}
+
+__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value);
+}
+
+__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask);
+}
+
+__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/** @} */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_gpiote.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF_GPIOTE_H__
+#define NRF_GPIOTE_H__
+
+#include "nrf.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+/**
+* @defgroup nrf_gpiote_abs GPIOTE abstraction
+* @{
+* @ingroup nrf_gpiote
+* @brief GPIOTE abstraction for configuration of channels.
+*/
+#ifdef NRF51
+#define NUMBER_OF_GPIO_TE 4
+#elif defined NRF52
+#define NUMBER_OF_GPIO_TE 8
+#else
+#error "Chip family not specified"
+#endif
+
+ /**
+ * @enum nrf_gpiote_polarity_t
+ * @brief Polarity for the GPIOTE channel.
+ */
+typedef enum
+{
+  NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi,       ///<  Low to high.
+  NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo,       ///<  High to low.
+  NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle        ///<  Toggle.
+} nrf_gpiote_polarity_t;
+
+
+ /**
+ * @enum nrf_gpiote_outinit_t
+ * @brief Initial output value for the GPIOTE channel.
+ */
+typedef enum
+{
+  NRF_GPIOTE_INITIAL_VALUE_LOW  = GPIOTE_CONFIG_OUTINIT_Low,       ///<  Low to high.
+  NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High       ///<  High to low.
+} nrf_gpiote_outinit_t;
+
+/**
+ * @brief Tasks.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+    NRF_GPIOTE_TASKS_OUT_0     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
+    NRF_GPIOTE_TASKS_OUT_1     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
+    NRF_GPIOTE_TASKS_OUT_2     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
+    NRF_GPIOTE_TASKS_OUT_3     = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
+    /*lint -restore*/
+} nrf_gpiote_tasks_t;
+
+/**
+ * @brief Events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+    NRF_GPIOTE_EVENTS_IN_0     = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/
+    NRF_GPIOTE_EVENTS_IN_1     = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/
+    NRF_GPIOTE_EVENTS_IN_2     = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/
+    NRF_GPIOTE_EVENTS_IN_3     = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/
+    NRF_GPIOTE_EVENTS_PORT     = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**<  Port event.*/
+    /*lint -restore*/
+} nrf_gpiote_events_t;
+
+/**
+ * @enum nrf_gpiote_int_t
+ * @brief GPIOTE interrupts.
+ */
+typedef enum
+{
+    NRF_GPIOTE_INT_IN0_MASK  = GPIOTE_INTENSET_IN0_Msk,  /**< GPIOTE interrupt from IN0. */
+    NRF_GPIOTE_INT_IN1_MASK  = GPIOTE_INTENSET_IN1_Msk,  /**< GPIOTE interrupt from IN1. */
+    NRF_GPIOTE_INT_IN2_MASK  = GPIOTE_INTENSET_IN2_Msk,  /**< GPIOTE interrupt from IN2. */
+    NRF_GPIOTE_INT_IN3_MASK  = GPIOTE_INTENSET_IN3_Msk,  /**< GPIOTE interrupt from IN3. */
+    NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */
+} nrf_gpiote_int_t;
+
+#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
+                                NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK)
+/**
+ * @brief Function for activating a specific GPIOTE task.
+ *
+ * @param[in]  task Task.
+ */
+__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task);
+
+/**
+ * @brief Function for getting the address of a specific GPIOTE task.
+ *
+ * @param[in] task Task.
+ *
+ * @returns Address.
+ */
+__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task);
+
+/**
+ * @brief Function for getting the state of a specific GPIOTE event.
+ *
+ * @param[in] event Event.
+ */
+__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event);
+
+/**
+ * @brief Function for clearing a specific GPIOTE event.
+ *
+ * @param[in] event Event.
+ */
+__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event);
+
+/**
+ * @brief Function for getting the address of a specific GPIOTE event.
+ *
+ * @param[in] event Event.
+ *
+ * @return Address
+ */
+__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event);
+
+/**@brief Function for enabling interrupts.
+ *
+ * @param[in]  mask          Interrupt mask to be enabled.
+ */
+__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask);
+
+/**@brief Function for disabling interrupts.
+ *
+ * @param[in]  mask          Interrupt mask to be disabled.
+ */
+__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask);
+
+/**@brief Function for checking if interrupts are enabled.
+ *
+ * @param[in]  mask          Mask of interrupt flags to check.
+ *
+ * @return                   Mask with enabled interrupts.
+ */
+__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask);
+
+/**@brief Function for enabling a GPIOTE event.
+ *
+ * @param[in]  idx        Task-Event index.
+ */
+__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx);
+
+/**@brief Function for disabling a GPIOTE event.
+ *
+ * @param[in]  idx        Task-Event index.
+ */
+__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx);
+
+/**@brief Function for configuring a GPIOTE event.
+ *
+ * @param[in]  idx        Task-Event index.
+ * @param[in]  pin        Pin associated with event.
+ * @param[in]  polarity   Transition that should generate an event.
+ */
+__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin,
+                                                nrf_gpiote_polarity_t polarity);
+
+/**@brief Function for getting the pin associated with a GPIOTE event.
+ *
+ * @param[in]  idx        Task-Event index.
+ *
+ * @return Pin number.
+ */
+__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx);
+
+/**@brief Function for getting the polarity associated with a GPIOTE event.
+ *
+ * @param[in]  idx        Task-Event index.
+ *
+ * @return Polarity.
+ */
+__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx);
+
+/**@brief Function for enabling a GPIOTE task.
+ *
+ * @param[in]  idx        Task-Event index.
+ */
+__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx);
+
+/**@brief Function for disabling a GPIOTE task.
+ *
+ * @param[in]  idx        Task-Event index.
+ */
+__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx);
+
+/**@brief Function for configuring a GPIOTE task.
+ * @note  Function is not configuring mode field so task is disabled after this function is called.
+ *
+ * @param[in]  idx        Task-Event index.
+ * @param[in]  pin        Pin associated with event.
+ * @param[in]  polarity   Transition that should generate an event.
+ * @param[in]  init_val   Initial value of pin.
+ */
+__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
+                                               nrf_gpiote_polarity_t polarity,
+                                               nrf_gpiote_outinit_t  init_val);
+
+/**@brief Function for forcing a specific state on the pin connected to GPIOTE.
+ *
+ * @param[in]  idx        Task-Event index.
+ * @param[in]  init_val   Pin state.
+ */
+__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val);
+
+/**@brief Function for resetting a GPIOTE task event configuration to the default state.
+ *
+ * @param[in]  idx        Task-Event index.
+ */
+__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task)
+{
+    *(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL;
+}
+
+__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task)
+{
+    return ((uint32_t)NRF_GPIOTE + task);
+}
+
+__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event)
+{
+    return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false;
+}
+
+__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event)
+{
+    *(uint32_t *)nrf_gpiote_event_addr_get(event) = 0;
+#if __CORTEX_M == 0x04
+    volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event));
+    (void)dummy;
+#endif
+}
+
+__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event)
+{
+    return ((uint32_t)NRF_GPIOTE + event);
+}
+
+__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask)
+{
+    NRF_GPIOTE->INTENSET = mask;
+}
+
+__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask)
+{
+    NRF_GPIOTE->INTENCLR = mask;
+}
+
+__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask)
+{
+    return (NRF_GPIOTE->INTENSET & mask);
+}
+
+__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx)
+{
+   NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event;
+}
+
+__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx)
+{
+   NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event;
+}
+
+__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity)
+{
+  NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk);
+  NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
+                              ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk);
+}
+
+__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx)
+{
+    return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PSEL_Msk) >> GPIOTE_CONFIG_PSEL_Pos);
+}
+
+__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx)
+{
+    return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos);
+}
+
+__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
+{
+    uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
+    /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
+    on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
+    correct state in GPIOTE but not in the OUT register. */
+    /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
+    NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk);
+    __NOP();
+    __NOP();
+    __NOP();
+    NRF_GPIOTE->CONFIG[idx] = final_config;
+}
+
+__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx)
+{
+    NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task;
+}
+
+__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
+                                                nrf_gpiote_polarity_t polarity,
+                                                nrf_gpiote_outinit_t  init_val)
+{
+  NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk |
+                               GPIOTE_CONFIG_POLARITY_Msk |
+                               GPIOTE_CONFIG_OUTINIT_Msk);
+
+  NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
+                             ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) |
+                             ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
+}
+
+__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val)
+{
+    NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) 
+                              | ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
+}
+
+__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx)
+{
+    NRF_GPIOTE->CONFIG[idx] = 0;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/** @} */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_nvmc.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NMVC driver implementation 
+ */
+
+#include "stdbool.h"
+#include "nrf.h"
+#include "nrf_nvmc.h"
+
+
+void nrf_nvmc_page_erase(uint32_t address)
+{ 
+  // Enable erase.
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+
+  // Erase the page
+  NRF_NVMC->ERASEPAGE = address;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+  
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+}
+
+
+void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
+{
+  uint32_t byte_shift = address & (uint32_t)0x03;
+  uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in.
+  uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
+  value32 = value32 + ((uint32_t)value << (byte_shift << 3));
+
+  // Enable write.
+  NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+
+  *(uint32_t*)address32 = value32;
+  while(NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+
+  NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+  {
+  }
+}
+
+void nrf_nvmc_write_word(uint32_t address, uint32_t value)
+{
+  // Enable write.
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
+  }
+
+  *(uint32_t*)address = value;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
+  }
+
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+}
+
+void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes)
+{
+  uint32_t i;
+  for(i=0;i<num_bytes;i++)
+  {
+     nrf_nvmc_write_byte(address+i,src[i]);
+  }
+}
+
+void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words)
+{
+  uint32_t i;
+
+  // Enable write.
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+
+  for(i=0;i<num_words;i++)
+  {
+    ((uint32_t*)address)[i] = src[i];
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+    {
+    }
+  }
+
+  NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+  while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
+  {
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_nvmc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NMVC driver API.
+ */
+
+#ifndef NRF_NVMC_H__
+#define NRF_NVMC_H__
+
+#include <stdint.h>
+
+
+/**
+ * @defgroup nrf_nvmc Non-volatile memory controller
+ * @{
+ * @ingroup nrf_drivers
+ * @brief Driver for the NVMC peripheral.
+ *
+ * This driver allows writing to the non-volatile memory (NVM) regions
+ * of the chip. In order to write to NVM the controller must be powered
+ * on and the relevant page must be erased.
+ *
+ */
+
+
+/**
+ * @brief Erase a page in flash. This is required before writing to any
+ * address in the page.
+ *
+ * @param address Start address of the page. 
+ */
+void nrf_nvmc_page_erase(uint32_t address);
+
+
+/**
+ * @brief Write a single byte to flash.
+ *
+ * The function reads the word containing the byte, and then
+ * rewrites the entire word.
+ *
+ * @param address Address to write to.
+ * @param value   Value to write.
+ */
+void nrf_nvmc_write_byte(uint32_t address , uint8_t value);
+
+
+/**
+ * @brief Write a 32-bit word to flash. 
+ * @param address Address to write to.
+ * @param value   Value to write.
+ */
+void nrf_nvmc_write_word(uint32_t address, uint32_t value);
+
+
+/**
+ * @brief Write consecutive bytes to flash.
+ *
+ * @param address   Address to write to.
+ * @param src       Pointer to data to copy from.
+ * @param num_bytes Number of bytes in src to write.
+ */
+void nrf_nvmc_write_bytes(uint32_t  address, const uint8_t * src, uint32_t num_bytes);
+
+
+/**
+ * @brief Write consecutive words to flash.
+ * 
+ * @param address   Address to write to.
+ * @param src       Pointer to data to copy from.
+ * @param num_words Number of bytes in src to write.
+ */
+void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words);
+
+
+#endif // NRF_NVMC_H__
+/** @} */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_temp.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF_TEMP_H__
+#define NRF_TEMP_H__
+
+#include "nrf.h"
+
+/**
+* @defgroup nrf_temperature TEMP (temperature) abstraction
+* @{
+* @ingroup nrf_drivers temperature_example
+* @brief Temperature module init and read functions.
+*
+*/
+
+/**@cond NO_DOXYGEN */
+#define MASK_SIGN           (0x00000200UL)
+#define MASK_SIGN_EXTENSION (0xFFFFFC00UL)
+
+/**
+ * @brief Function for preparing the temp module for temperature measurement.
+ *
+ * This function initializes the TEMP module and writes to the hidden configuration register.
+ */
+static __INLINE void nrf_temp_init(void)
+{
+    /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */
+    *(uint32_t *) 0x4000C504 = 0;
+}
+
+/**
+ * @brief Function for reading temperature measurement.
+ *
+ * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value.
+ */
+static __INLINE int32_t nrf_temp_read(void)
+{    
+    /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */
+    return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP);    
+}
+/**@endcond */
+
+/** @} */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/hal/nrf_wdt.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_wdt_hal WDT HAL
+ * @{
+ * @ingroup nrf_wdt
+ *
+ * @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral.
+ */
+
+#ifndef NRF_WDT_H__
+#define NRF_WDT_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+
+#define NRF_WDT_CHANNEL_NUMBER 0x8UL
+#define NRF_WDT_RR_VALUE       0x6E524635UL /* Fixed value, shouldn't be modified.*/
+
+#define NRF_WDT_TASK_SET       1UL
+#define NRF_WDT_EVENT_CLEAR    0UL
+
+/**
+ * @enum nrf_wdt_task_t
+ * @brief WDT tasks.
+ */
+typedef enum
+{
+    /*lint -save -e30 -esym(628,__INTADDR__)*/
+    NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
+    /*lint -restore*/
+} nrf_wdt_task_t;
+
+/**
+ * @enum nrf_wdt_event_t
+ * @brief WDT events.
+ */
+typedef enum
+{
+    /*lint -save -e30*/
+    NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
+    /*lint -restore*/
+} nrf_wdt_event_t;
+
+/**
+ * @enum nrf_wdt_behaviour_t
+ * @brief WDT behavior in CPU SLEEP or HALT mode.
+ */
+typedef enum
+{
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP        = WDT_CONFIG_SLEEP_Msk,                       /**< WDT will run when CPU is in SLEEP mode. */
+    NRF_WDT_BEHAVIOUR_RUN_HALT         = WDT_CONFIG_HALT_Msk,                        /**< WDT will run when CPU is in HALT mode. */
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT   = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
+    NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0,                                          /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
+} nrf_wdt_behaviour_t;
+
+/**
+ * @enum nrf_wdt_rr_register_t
+ * @brief WDT reload request registers.
+ */
+typedef enum
+{
+    NRF_WDT_RR0 = 0, /**< Reload request register 0. */
+    NRF_WDT_RR1,     /**< Reload request register 1. */
+    NRF_WDT_RR2,     /**< Reload request register 2. */
+    NRF_WDT_RR3,     /**< Reload request register 3. */
+    NRF_WDT_RR4,     /**< Reload request register 4. */
+    NRF_WDT_RR5,     /**< Reload request register 5. */
+    NRF_WDT_RR6,     /**< Reload request register 6. */
+    NRF_WDT_RR7      /**< Reload request register 7. */
+} nrf_wdt_rr_register_t;
+
+/**
+ * @enum nrf_wdt_int_mask_t
+ * @brief WDT interrupts.
+ */
+typedef enum
+{
+    NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
+} nrf_wdt_int_mask_t;
+
+/**
+ * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
+ *
+ * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
+ */
+__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
+{
+    NRF_WDT->CONFIG = behaviour;
+}
+
+
+/**
+ * @brief Function for starting the watchdog.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
+}
+
+
+/**
+ * @brief Function for clearing the WDT event.
+ *
+ * @param[in]  event       Event.
+ */
+__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
+}
+
+
+/**
+ * @brief Function for retrieving the state of the WDT event.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     true              If the event is set.
+ * @retval     false             If the event is not set.
+ */
+__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
+{
+    return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
+}
+
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
+{
+    NRF_WDT->INTENSET = int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of given interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ *
+ * @retval     true                   Interrupt is enabled.
+ * @retval     false                  Interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
+{
+    return (bool)(NRF_WDT->INTENSET & int_mask);
+}
+
+
+/**
+ * @brief Function for disabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
+{
+    NRF_WDT->INTENCLR = int_mask;
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT task register.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
+{
+    return ((uint32_t)NRF_WDT + task);
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT event register.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     address of requested event register
+ */
+__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
+{
+    return ((uint32_t)NRF_WDT + event);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog status.
+ *
+ * @retval     true             If the watchdog is started.
+ * @retval     false            If the watchdog is not started.
+ */
+__STATIC_INLINE bool nrf_wdt_started(void)
+{
+    return (bool)(NRF_WDT->RUNSTATUS);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload request status.
+ *
+ * @param[in]  rr_register      Reload request register to check.
+ *
+ * @retval     true             If a reload request is running.
+ * @retval     false            If no reload request is running.
+ */
+__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
+}
+
+
+/**
+ * @brief Function for setting the watchdog reload value.
+ *
+ * @param[in]  reload_value     Watchdog counter initial value.
+ */
+__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
+{
+    NRF_WDT->CRV = reload_value;
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload value.
+ *
+ * @retval                      Reload value.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
+{
+    return (uint32_t)NRF_WDT->CRV;
+}
+
+
+/**
+ * @brief Function for enabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to enable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN |= 0x1UL << rr_register;
+}
+
+
+/**
+ * @brief Function for disabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to disable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN &= ~(0x1UL << rr_register);
+}
+
+
+/**
+ * @brief Function for retrieving the status of a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to check.
+ *
+ * @retval     true              If the reload request register is enabled.
+ * @retval     false             If the reload request register is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
+}
+
+
+/**
+ * @brief Function for setting a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to set.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
+}
+
+
+#endif
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/config/pstorage_platform.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /** @cond To make doxygen skip this file */
+
+/** @file
+ *  This header contains defines with respect persistent storage that are specific to
+ *  persistent storage implementation and application use case.
+ */
+#ifndef PSTORAGE_PL_H__
+#define PSTORAGE_PL_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+static __INLINE uint16_t pstorage_flash_page_size()
+{
+  return (uint16_t)NRF_FICR->CODEPAGESIZE;
+}
+
+#define PSTORAGE_FLASH_PAGE_SIZE     pstorage_flash_page_size()          /**< Size of one flash page. */
+#define PSTORAGE_FLASH_EMPTY_MASK    0xFFFFFFFF                          /**< Bit mask that defines an empty address in flash. */
+
+#ifdef NRF51
+#define BOOTLOADER_ADDRESS           (NRF_UICR->BOOTLOADERADDR)
+#elif defined NRF52
+#define BOOTLOADER_ADDRESS           (PSTORAGE_FLASH_EMPTY_MASK)
+#endif 
+
+static __INLINE uint32_t pstorage_flash_page_end()
+{
+   uint32_t bootloader_addr = BOOTLOADER_ADDRESS;
+  
+   return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ?
+           (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE);
+}
+
+#define PSTORAGE_FLASH_PAGE_END     pstorage_flash_page_end()
+
+#define PSTORAGE_NUM_OF_PAGES       1                                                           /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */
+#define PSTORAGE_MIN_BLOCK_SIZE     0x0010                                                      /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */
+
+#define PSTORAGE_DATA_START_ADDR    ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \
+                                    * PSTORAGE_FLASH_PAGE_SIZE)                                 /**< Start address for persistent data, configurable according to system requirements. */
+#define PSTORAGE_DATA_END_ADDR      ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE)  /**< End address for persistent data, configurable according to system requirements. */
+#define PSTORAGE_SWAP_ADDR          PSTORAGE_DATA_END_ADDR                                      /**< Top-most page is used as swap area for clear and update. */
+
+#define PSTORAGE_MAX_BLOCK_SIZE     PSTORAGE_FLASH_PAGE_SIZE                                    /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */
+#define PSTORAGE_CMD_QUEUE_SIZE     2                                                           /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */
+
+
+/** Abstracts persistently memory block identifier. */
+typedef uint32_t pstorage_block_t;
+
+typedef struct
+{
+    uint32_t            module_id;      /**< Module ID.*/
+    pstorage_block_t    block_id;       /**< Block ID.*/
+} pstorage_handle_t;
+
+typedef uint16_t pstorage_size_t;      /** Size of length and offset fields. */
+
+/**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */
+void pstorage_sys_event_handler (uint32_t sys_evt);
+
+#endif // PSTORAGE_PL_H__
+
+/** @} */
+/** @endcond */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/pstorage.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1592 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "pstorage.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "nrf_assert.h"
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "app_util.h"
+#include "app_error.h"
+
+#define INVALID_OPCODE             0x00                                /**< Invalid op code identifier. */
+#define SOC_MAX_WRITE_SIZE         PSTORAGE_FLASH_PAGE_SIZE            /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API. */
+#define RAW_MODE_APP_ID            (PSTORAGE_NUM_OF_PAGES + 1)         /**< Application id for raw mode. */
+
+#if defined(NRF52)
+#define SD_CMD_MAX_TRIES           1000                                /**< Number of times to try a softdevice flash operatoion, specific for nRF52 to account for longest time of flash page erase*/
+#else
+#define SD_CMD_MAX_TRIES           3                                   /**< Number of times to try a softdevice flash operation when the @ref NRF_EVT_FLASH_OPERATION_ERROR sys_evt is received. */
+#endif /* defined(NRF52) */
+
+#define MASK_TAIL_SWAP_DONE        (1 << 0)                            /**< Flag for checking if the tail restore area has been written to swap page. */     
+#define MASK_SINGLE_PAGE_OPERATION (1 << 1)                            /**< Flag for checking if command is a single flash page operation. */
+#define MASK_MODULE_INITIALIZED    (1 << 2)                            /**< Flag for checking if the module has been initialized. */
+#define MASK_FLASH_API_ERR_BUSY    (1 << 3)                            /**< Flag for checking if flash API returned NRF_ERROR_BUSY. */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ *          could be mapped to nothing in final code versions to save execution and size.
+ *
+ * @{
+ */
+
+/**@brief Check if the input pointer is NULL, if so it returns NRF_ERROR_NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM)                                                                   \
+        if ((PARAM) == NULL)                                                                      \
+        {                                                                                         \
+            return NRF_ERROR_NULL;                                                                \
+        }
+
+/**@brief Verifies that the module identifier supplied by the application is within permissible
+ *        range.
+ */
+#define MODULE_ID_RANGE_CHECK(ID)                                                                 \
+        if ((((ID)->module_id) >= PSTORAGE_NUM_OF_PAGES) ||                                       \
+            (m_app_table[(ID)->module_id].cb == NULL))                                            \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+/**@brief Verifies that the block identifier supplied by the application is within the permissible
+ *        range.
+ */
+#define BLOCK_ID_RANGE_CHECK(ID)                                                                  \
+        if (((ID)->block_id) >= (m_app_table[(ID)->module_id].base_id +                           \
+            (m_app_table[(ID)->module_id].block_count * MODULE_BLOCK_SIZE(ID))))                  \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+/**@brief Verifies that the block size requested by the application can be supported by the module.
+ */
+#define BLOCK_SIZE_CHECK(X)                                                                       \
+        if (((X) > PSTORAGE_MAX_BLOCK_SIZE) || ((X) < PSTORAGE_MIN_BLOCK_SIZE))                   \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+/**@brief Verifies the block size requested by the application in registration API.
+ */
+#define BLOCK_COUNT_CHECK(COUNT, SIZE)                                                            \
+        if (((COUNT) == 0) ||                                                                     \
+            ((m_next_page_addr + ((COUNT) *(SIZE)) > PSTORAGE_SWAP_ADDR)))                        \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }        
+
+/**@brief Verifies the size parameter provided by the application in API.
+ */
+#define SIZE_CHECK(ID, SIZE)                                                                      \
+        if(((SIZE) == 0) || ((SIZE) > MODULE_BLOCK_SIZE(ID)))                                     \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+/**@brief Verifies the offset parameter provided by the application in API.
+ */
+#define OFFSET_CHECK(ID, OFFSET, SIZE)                                                            \
+        if(((SIZE) + (OFFSET)) > MODULE_BLOCK_SIZE(ID))                                           \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+
+/**@brief Verifies the module identifier supplied by the application.
+ */
+#define MODULE_RAW_HANDLE_CHECK(ID)                                                               \
+        if ((((ID)->module_id) != RAW_MODE_APP_ID))                                               \
+        {                                                                                         \
+            return NRF_ERROR_INVALID_PARAM;                                                       \
+        }
+
+#endif // PSTORAGE_RAW_MODE_ENABLE
+
+/**@} */
+
+
+/**@brief Verify module's initialization status.
+ *
+ * @details  Verify module's initialization status. Returns NRF_ERROR_INVALID_STATE when a
+ *           module API is called without initializing the module.
+ */
+#define VERIFY_MODULE_INITIALIZED()                                                               \
+        do                                                                                        \
+        {                                                                                         \
+            if (!(m_flags & MASK_MODULE_INITIALIZED))                                             \
+            {                                                                                     \
+                 return NRF_ERROR_INVALID_STATE;                                                  \
+            }                                                                                     \
+        } while(0)
+
+/**@brief Macro to fetch the block size registered for the module. */
+#define MODULE_BLOCK_SIZE(ID) (m_app_table[(ID)->module_id].block_size)
+
+/**@brief Main state machine of the component. */
+typedef enum
+{
+    STATE_IDLE,                                                        /**< State for being idle (no command execution in progress). */
+    STATE_STORE,                                                       /**< State for storing data when using store/update API. */
+    STATE_DATA_ERASE_WITH_SWAP,                                        /**< State for erasing the data page when using update/clear API when use of swap page is required. */
+    STATE_DATA_ERASE,                                                  /**< State for erasing the data page when using update/clear API without the need to use the swap page. */
+    STATE_ERROR                                                        /**< State entered when command processing is terminated abnormally. */
+} pstorage_state_t;  
+
+/**@brief Sub state machine contained by @ref STATE_DATA_ERASE_WITH_SWAP super state machine. */
+typedef enum
+{
+    STATE_ERASE_SWAP,                                                  /**< State for erasing the swap page when using the update/clear API. */   
+    STATE_WRITE_DATA_TO_SWAP,                                          /**< State for writing the data page into the swap page when using update/clear API. */
+    STATE_ERASE_DATA_PAGE,                                             /**< State for erasing data page when using update/clear API. */
+    STATE_RESTORE_TAIL,                                                /**< State for restoring tail (end) of backed up data from swap to data page when using update/clear API. */
+    STATE_RESTORE_HEAD,                                                /**< State for restoring head (beginning) of backed up data from swap to data page when using update/clear API. */
+    SWAP_SUB_STATE_MAX                                                 /**< Enumeration upper bound. */   
+} flash_swap_sub_state_t;
+
+/**@brief Application registration information.
+ *
+ * @details Defines application specific information that the application needs to maintain to be able 
+ *          to process requests from each one of them.
+ */
+typedef struct
+{
+    pstorage_ntf_cb_t cb;                                              /**< Callback registered with the module to be notified of result of flash access.  */
+    pstorage_block_t  base_id;                                         /**< Base block ID assigned to the module. */
+    pstorage_size_t   block_size;                                      /**< Size of block for the module. */
+    pstorage_size_t   block_count;                                     /**< Number of blocks requested by the application. */
+} pstorage_module_table_t;
+
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+/**@brief Application registration information.
+ *
+ * @details Defines application specific information that the application registered for raw mode.
+ */
+typedef struct
+{
+    pstorage_ntf_cb_t cb;                                              /**< Callback registered with the module to be notified of the result of flash access.  */
+} pstorage_raw_module_table_t;
+#endif // PSTORAGE_RAW_MODE_ENABLE
+
+
+/**@brief Defines command queue element.
+ *
+ * @details Defines command queue element. Each element encapsulates needed information to process
+ *          a flash access command.
+ */
+typedef struct
+{
+    uint8_t           op_code;                                         /**< Identifies the flash access operation being queued. Element is free if op-code is INVALID_OPCODE. */
+    pstorage_size_t   size;                                            /**< Identifies the size in bytes requested for the operation. */
+    pstorage_size_t   offset;                                          /**< Offset requested by the application for the access operation. */
+    pstorage_handle_t storage_addr;                                    /**< Address/Identifier for persistent memory. */
+    uint8_t *         p_data_addr;                                     /**< Address/Identifier for data memory. This is assumed to be resident memory. */
+} cmd_queue_element_t;
+
+
+/**@brief   Defines command queue, an element is free if the op_code field is not invalid.
+ *
+ * @details Defines commands enqueued for flash access. At any point in time, this queue has one or
+ *          more flash access operations pending if the count field is not zero. When the queue is
+ *          not empty, the rp (read pointer) field points to the flash access command in progress 
+ *          or, if none is in progress, the command to be requested next. The queue implements a 
+ *          simple first in first out algorithm. Data addresses are assumed to be resident.
+ */
+typedef struct
+{
+    uint8_t             rp;                                            /**< Read pointer, pointing to flash access that is ongoing or to be requested next. */
+    uint8_t             count;                                         /**< Number of elements in the queue.  */
+    cmd_queue_element_t cmd[PSTORAGE_CMD_QUEUE_SIZE];                  /**< Array to maintain flash access operation details. */
+} cmd_queue_t;
+
+static cmd_queue_t             m_cmd_queue;                            /**< Flash operation request queue. */
+static pstorage_size_t         m_next_app_instance;                    /**< Points to the application module instance that can be allocated next. */
+static uint32_t                m_next_page_addr;                       /**< Points to the flash address that can be allocated to a module next. This is needed as blocks of a module that can span across flash pages. */
+static pstorage_state_t        m_state;                                /**< Main state tracking variable. */
+static flash_swap_sub_state_t  m_swap_sub_state;                       /**< Flash swap erase when swap used state tracking variable. */
+static uint32_t                m_head_word_size;                       /**< Head restore area size in words. */
+static uint32_t                m_tail_word_size;                       /**< Tail restore area size in words. */
+static uint32_t                m_current_page_id;                      /**< Variable for tracking the flash page being processed. */
+static uint32_t                m_num_of_command_retries;               /**< Variable for tracking flash operation retries upon flash operation failures. */
+static pstorage_module_table_t m_app_table[PSTORAGE_NUM_OF_PAGES];     /**< Registered application information table. */
+static uint32_t                m_num_of_bytes_written;                 /**< Variable for tracking the number of bytes written by the store operation. */
+static uint32_t                m_app_data_size;                        /**< Variable for storing the application command size parameter internally. */
+static uint32_t                m_flags = 0;                            /**< Storage for boolean flags for state tracking. */
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+static pstorage_raw_module_table_t m_raw_app_table;                    /**< Registered application information table for raw mode. */
+#endif // PSTORAGE_RAW_MODE_ENABLE
+
+// Required forward declarations.
+static void cmd_process(void);
+static void store_operation_execute(void);
+static void app_notify(uint32_t result, cmd_queue_element_t * p_elem);
+static void cmd_queue_element_init(uint32_t index);
+static void cmd_queue_dequeue(void);
+static void sm_state_change(pstorage_state_t new_state);
+static void swap_sub_state_state_change(flash_swap_sub_state_t new_state); 
+
+/**@brief Function for consuming a command queue element.
+ *
+ * @details Function for consuming a command queue element, which has been fully processed.
+ */
+static void command_queue_element_consume(void)
+{
+    // Initialize/free the element as it is now processed.    
+    cmd_queue_element_init(m_cmd_queue.rp);
+
+    // Adjust command queue state tracking variables.
+    --(m_cmd_queue.count);   
+    if (++(m_cmd_queue.rp) == PSTORAGE_CMD_QUEUE_SIZE)
+    {
+        m_cmd_queue.rp = 0;
+    }    
+}
+
+
+/**@brief Function for executing the finalization procedure for the command executed.
+ *
+ * @details Function for executing the finalization procedure for command executed, which includes 
+ *          notifying the application of command completion, consuming the command queue element, 
+ *          and changing the internal state.
+ */
+static void command_end_procedure_run(void)
+{    
+    app_notify(NRF_SUCCESS, &m_cmd_queue.cmd[m_cmd_queue.rp]);
+    
+    command_queue_element_consume();
+    
+    sm_state_change(STATE_IDLE);
+}
+
+
+/**@brief Function for idle state entry actions.
+ *
+ * @details Function for idle state entry actions, which include resetting relevant state data and 
+ *          scheduling any possible queued flash access operation.
+ */
+static void state_idle_entry_run(void)
+{
+    m_num_of_command_retries = 0;
+    m_num_of_bytes_written   = 0;
+    
+    // Schedule any possible queued flash access operation.
+    cmd_queue_dequeue();
+}
+
+
+/**@brief Function for notifying an application of command completion and transitioning to an error 
+ *        state.
+ *
+ * @param[in] result Result code of the operation for the application.
+ */
+static void app_notify_error_state_transit(uint32_t result)
+{
+    app_notify(result, &m_cmd_queue.cmd[m_cmd_queue.rp]);
+    sm_state_change(STATE_ERROR);                
+}
+
+
+/**@brief Function for processing flash API error code.
+ *
+ * @param[in] err_code Error code from the flash API.
+ */
+static void flash_api_err_code_process(uint32_t err_code)
+{
+    switch (err_code)
+    {
+        case NRF_SUCCESS:
+            break;
+            
+        case NRF_ERROR_BUSY:
+            // Flash access operation was not accepted and must be reissued upon flash operation 
+            // complete event.
+            m_flags |= MASK_FLASH_API_ERR_BUSY;        
+            break;
+            
+        default:
+            // Complete the operation with appropriate result code and transit to an error state. 
+            app_notify_error_state_transit(err_code);
+            break;
+    }
+}
+
+/**@brief Function for writing data to flash.
+ *
+ * @param[in] p_dst         Pointer to start of flash location to be written.
+ * @param[in] p_src         Pointer to buffer with data to be written.
+ * @param[in] size_in_words Number of 32-bit words to write. 
+ */
+static void flash_write(uint32_t * const       p_dst, 
+                        uint32_t const * const p_src, 
+                        uint32_t               size_in_words)
+{
+    flash_api_err_code_process(sd_flash_write(p_dst, p_src, size_in_words));    
+}
+
+
+/**@brief Function for writing data to flash upon store command.
+ *
+ * @details Function for writing data to flash upon executing store command. Data is written to 
+ *          flash in reverse order, meaning starting at the end. If the data that is to be written 
+ *          is greater than the flash page size, it will be fragmented to fit the flash page size.
+ */
+static void store_cmd_flash_write_execute(void)
+{
+    const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    
+    if (p_cmd->size > SOC_MAX_WRITE_SIZE)    
+    {
+        const uint32_t offset = p_cmd->size - PSTORAGE_FLASH_PAGE_SIZE;
+        flash_write((uint32_t *)(p_cmd->storage_addr.block_id + p_cmd->offset + offset),
+                    (uint32_t *)(p_cmd->p_data_addr + offset), 
+                    PSTORAGE_FLASH_PAGE_SIZE / sizeof(uint32_t));   
+
+        m_num_of_bytes_written = PSTORAGE_FLASH_PAGE_SIZE;    
+    }
+    else
+    {
+        flash_write((uint32_t *)(p_cmd->storage_addr.block_id + p_cmd->offset),
+                    (uint32_t *)(p_cmd->p_data_addr), 
+                    p_cmd->size / sizeof(uint32_t));   
+
+        m_num_of_bytes_written = p_cmd->size;        
+    }    
+}
+
+
+/**@brief Function for store state entry action.
+ *
+ * @details Function for store state entry action, which includes writing data to a flash page.
+ */
+static void state_store_entry_run(void)
+{
+    store_cmd_flash_write_execute();    
+}
+
+
+/**@brief Function for data erase with swap state entry actions.
+ *
+ * @details Function for data erase with swap state entry actions. This includes adjusting relevant 
+ *          state and data variables and transitioning to the correct sub state.
+ */
+static void state_data_erase_swap_entry_run(void)
+{
+    m_flags &= ~MASK_TAIL_SWAP_DONE;
+    
+    const cmd_queue_element_t * p_cmd        = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    const pstorage_block_t      cmd_block_id = p_cmd->storage_addr.block_id;
+    
+    const uint32_t clear_start_page_id = cmd_block_id / PSTORAGE_FLASH_PAGE_SIZE;
+    m_current_page_id                  = clear_start_page_id;      
+        
+    // @note: No need to include p_cmd->offset when calculating clear_end_page_id as:
+    // - clear API does not include offset parameter
+    // - update and store APIs are limited to operate on single block boundary thus the boolean 
+    // clause ((m_head_word_size == 0) && is_more_than_one_page) below in this function  will never 
+    // evaluate as true as if is_more_than_one_page == true m_head_word_size is always != 0        
+    const uint32_t clear_end_page_id  = (cmd_block_id + p_cmd->size - 1u) / 
+                                        PSTORAGE_FLASH_PAGE_SIZE;
+
+    if (clear_start_page_id == clear_end_page_id)
+    {
+        m_flags |= MASK_SINGLE_PAGE_OPERATION;
+    }
+    else
+    {
+        m_flags &= ~MASK_SINGLE_PAGE_OPERATION;
+    }
+                            
+    if ((m_head_word_size == 0) && !(m_flags & MASK_SINGLE_PAGE_OPERATION))
+    {        
+        // No head restore required and clear/update area is shared by multiple flash pages, which 
+        // means the current flash page does not have any tail area to restore. You can proceed with 
+        // data page erase directly as no swap is needed for the current flash page.
+        swap_sub_state_state_change(STATE_ERASE_DATA_PAGE);        
+    }
+    else
+    {     
+        swap_sub_state_state_change(STATE_ERASE_SWAP);
+    }               
+}
+
+
+/**@brief Function for erasing flash page.
+ *
+ * @param[in] page_number Page number of the page to be erased.
+ */
+static void flash_page_erase(uint32_t page_number)
+{
+    flash_api_err_code_process(sd_flash_page_erase(page_number));
+}
+
+
+/**@brief Function for data erase state entry action.
+ *
+ * @details Function for data erase state entry action, which includes erasing the data flash page.
+ */
+static void state_data_erase_entry_run(void)
+{
+    flash_page_erase(m_current_page_id);                          
+}
+
+
+/**@brief Function for dispatching the correct application main state entry action.
+ */
+static void state_entry_action_run(void)
+{
+    switch (m_state)
+    {
+        case STATE_IDLE:
+            state_idle_entry_run();
+            break;
+
+        case STATE_STORE:
+            state_store_entry_run();
+            break;
+            
+        case STATE_DATA_ERASE_WITH_SWAP:
+            state_data_erase_swap_entry_run();
+            break;
+            
+        case STATE_DATA_ERASE:
+            state_data_erase_entry_run();        
+            break;
+                        
+        default:
+            // No action needed.
+            break;
+    }
+}
+
+
+/**@brief Function for changing application main state and dispatching state entry action.
+ *
+ * @param[in] new_state New application main state to transit to.
+ */
+static void sm_state_change(pstorage_state_t new_state)
+{
+    m_state = new_state;
+    state_entry_action_run();
+}
+
+
+/**@brief Function for swap erase state entry action.
+ *
+ * @details Function for swap erase state entry action, which includes erasing swap flash 
+ *          page.
+ */
+static void state_swap_erase_entry_run(void)
+{
+    flash_page_erase(PSTORAGE_SWAP_ADDR / PSTORAGE_FLASH_PAGE_SIZE);                
+}
+
+
+/**@brief Function for write data to the swap state entry action.
+ *
+ * @details Function for write data to the swap state entry action, which includes writing the 
+ *          current data page to the swap flash page.
+ */
+static void state_write_data_swap_entry_run(void)
+{
+    // @note: There is room for further optimization here as there is only need to write the
+    // whole flash page to swap area if there is both head and tail area to be restored. In any 
+    // other case we can omit some data from the head or end of the page as that is the clear area.
+    flash_write((uint32_t *)(PSTORAGE_SWAP_ADDR), 
+                (uint32_t *)(m_current_page_id * PSTORAGE_FLASH_PAGE_SIZE), 
+                PSTORAGE_FLASH_PAGE_SIZE / sizeof(uint32_t));    
+}
+
+
+/**@brief Function for erase data page state entry action.
+ *
+ * @details Function for erase data page state entry action, which includes erasing the data flash 
+ *          page.
+ */
+static void state_erase_data_page_entry_run(void)
+{
+    flash_page_erase(m_current_page_id);
+}
+
+
+/**@brief Function for restore tail state entry action.
+ *
+ * @details Function for restore tail state entry action, which includes writing the tail section 
+ *          back from swap to the data page.
+ */
+static void state_restore_tail_entry_run(void)
+{
+    const cmd_queue_element_t * p_cmd        = &m_cmd_queue.cmd[m_cmd_queue.rp];    
+    const pstorage_block_t      cmd_block_id = p_cmd->storage_addr.block_id;                            
+    
+    const uint32_t tail_offset = (cmd_block_id + p_cmd->size + p_cmd->offset) % 
+                                 PSTORAGE_FLASH_PAGE_SIZE; 
+                                 
+    flash_write((uint32_t *)(cmd_block_id + p_cmd->size + p_cmd->offset),
+                (uint32_t *)(PSTORAGE_SWAP_ADDR + tail_offset),
+                m_tail_word_size);
+}
+
+
+/**@brief Function for restore head state entry action.
+ *
+ * @details Function for restore head state entry action, which includes writing the head section 
+ *          back from swap to the data page.
+ */
+static void state_restore_head_entry_run(void)
+{
+    flash_write((uint32_t *)((m_current_page_id - 1u) * PSTORAGE_FLASH_PAGE_SIZE),
+                (uint32_t *)PSTORAGE_SWAP_ADDR,
+                m_head_word_size);
+}
+
+
+/**@brief Function for dispatching the correct swap sub state entry action.
+ */
+static void swap_sub_state_entry_action_run(void)
+{
+    static void (* const swap_sub_state_sm_lut[SWAP_SUB_STATE_MAX])(void) = 
+    {
+        state_swap_erase_entry_run,
+        state_write_data_swap_entry_run,
+        state_erase_data_page_entry_run,
+        state_restore_tail_entry_run,
+        state_restore_head_entry_run
+    };
+    
+    swap_sub_state_sm_lut[m_swap_sub_state]();
+}
+
+
+/**@brief Function for changing the swap sub state and dispatching state entry action.
+ *
+ * @param[in] new_state New swap sub state to transit to.
+ */   
+static void swap_sub_state_state_change(flash_swap_sub_state_t new_state)
+{
+    m_swap_sub_state = new_state;
+    swap_sub_state_entry_action_run();    
+}
+
+
+/**@brief Function for initializing the command queue element.
+ *
+ * @param[in] index Index of the element to be initialized.
+ */
+static void cmd_queue_element_init(uint32_t index)
+{
+    // Internal function and checks on range of index can be avoided.
+    m_cmd_queue.cmd[index].op_code                = INVALID_OPCODE;
+    m_cmd_queue.cmd[index].size                   = 0;
+    m_cmd_queue.cmd[index].storage_addr.module_id = PSTORAGE_NUM_OF_PAGES;
+    m_cmd_queue.cmd[index].storage_addr.block_id  = 0;
+    m_cmd_queue.cmd[index].p_data_addr            = NULL;
+    m_cmd_queue.cmd[index].offset                 = 0;
+}
+
+
+/**@brief Function for initializing the command queue.
+ */
+static void cmd_queue_init(void)
+{
+    m_cmd_queue.rp    = 0;
+    m_cmd_queue.count = 0;
+
+    for (uint32_t cmd_index = 0; cmd_index < PSTORAGE_CMD_QUEUE_SIZE; ++cmd_index)
+    {
+        cmd_queue_element_init(cmd_index);
+    }
+}
+
+
+/**@brief Function for enqueuing, and possibly dispatching, a flash access operation.
+ *
+ * @param[in] opcode         Identifies the operation requested to be enqueued.
+ * @param[in] p_storage_addr Identifies the module and flash address on which the operation is 
+ *                           requested.
+ * @param[in] p_data_addr    Identifies the data address for flash access.
+ * @param[in] size           Size in bytes of data requested for the access operation.
+ * @param[in] offset         Offset within the flash memory block at which operation is requested.
+ *
+ * @retval    NRF_SUCCESS      Upon success.
+ * @retval    NRF_ERROR_NO_MEM Upon failure, when no space is available in the command queue. 
+ */
+static uint32_t cmd_queue_enqueue(uint8_t             opcode,
+                                  pstorage_handle_t * p_storage_addr,
+                                  uint8_t           * p_data_addr,
+                                  pstorage_size_t     size,
+                                  pstorage_size_t     offset)
+{
+    uint32_t err_code;
+
+    if (m_cmd_queue.count != PSTORAGE_CMD_QUEUE_SIZE)
+    {
+        // Enqueue the command if it the queue is not full.
+        uint32_t write_index = m_cmd_queue.rp + m_cmd_queue.count;
+
+        if (write_index >= PSTORAGE_CMD_QUEUE_SIZE) 
+        {
+            write_index -= PSTORAGE_CMD_QUEUE_SIZE;
+        }
+
+        m_cmd_queue.cmd[write_index].op_code      = opcode;
+        m_cmd_queue.cmd[write_index].p_data_addr  = p_data_addr;
+        m_cmd_queue.cmd[write_index].storage_addr = (*p_storage_addr);
+        m_cmd_queue.cmd[write_index].size         = size;
+        m_cmd_queue.cmd[write_index].offset       = offset;
+               
+        m_cmd_queue.count++;
+                                
+        if (m_state == STATE_IDLE)
+        {
+            cmd_process(); 
+        }            
+        
+        err_code = NRF_SUCCESS;        
+    }
+    else
+    {
+        err_code = NRF_ERROR_NO_MEM;
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for dequeing a possible pending flash access operation.
+ */
+static void cmd_queue_dequeue(void)
+{
+    if ((m_cmd_queue.count != 0)) 
+    {
+        cmd_process();
+    }
+}
+
+
+/**@brief Function for notifying an application of command completion.
+ *
+ * @param[in] result Result code of the operation for the application.
+ * @param[in] p_elem Pointer to the command queue element for which this result was received. 
+ */
+static void app_notify(uint32_t result, cmd_queue_element_t * p_elem)
+{
+    pstorage_ntf_cb_t ntf_cb;
+    const uint8_t     op_code = p_elem->op_code;
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+    if (p_elem->storage_addr.module_id == RAW_MODE_APP_ID)
+    {
+        ntf_cb = m_raw_app_table.cb;
+    }
+    else
+#endif // PSTORAGE_RAW_MODE_ENABLE
+    {
+        ntf_cb = m_app_table[p_elem->storage_addr.module_id].cb;
+    }
+
+    ntf_cb(&p_elem->storage_addr, op_code, result, p_elem->p_data_addr, m_app_data_size);
+}
+
+
+/**@brief Function for evaluating if a data page swap is required for the tail section on the 
+ *        current page.
+ *
+ * @retval true  If data page swap is required.
+ * @retval false If data page swap is not required.
+ */
+static bool is_tail_data_page_swap_required(void)
+{
+    bool ret_value;
+
+    // Extract id of the last page command is executed upon.
+    const cmd_queue_element_t * p_cmd        = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    const pstorage_block_t      cmd_block_id = p_cmd->storage_addr.block_id;        
+    const uint32_t              last_page_id = (cmd_block_id + p_cmd->size + p_cmd->offset - 1u) / 
+                                               PSTORAGE_FLASH_PAGE_SIZE;    
+        
+    // If tail section area exists and the current page is the last page then tail data page swap is 
+    // required.    
+    if ((m_tail_word_size != 0) && (m_current_page_id == last_page_id))
+    {
+        ret_value = true;
+    }
+    else
+    {
+        ret_value = false;    
+    }
+    
+    return ret_value;
+}
+
+
+/**@brief Function for performing post processing for the update and clear commands.
+ *
+ * @details Function for performing post processing for the update and clear commands, which implies 
+ *          executing the correct execution path depending on the command. 
+ */
+static void clear_post_processing_run(void)
+{
+    const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 
+    
+    if (p_cmd->op_code != PSTORAGE_UPDATE_OP_CODE)
+    {
+        command_end_procedure_run();    
+    }
+    else
+    {
+        store_operation_execute();                    
+    }
+}
+
+
+/**@brief Function for doing swap sub state exit action.
+ */
+static void swap_sub_sm_exit_action_run(void)
+{
+    clear_post_processing_run();
+}
+
+
+/**@brief Function for evaluating if the page erase operation is required for the current page.
+ *
+ * @retval true  If page erase is required.
+ * @retval false If page erase is not required. 
+ */
+static bool is_page_erase_required(void)
+{
+    bool ret;
+    
+    const cmd_queue_element_t * p_cmd                      = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    const pstorage_block_t      cmd_block_id               = p_cmd->storage_addr.block_id;        
+    const uint32_t              id_last_page_to_be_cleared = (cmd_block_id + p_cmd->size + 
+                                                             p_cmd->offset - 1u) / 
+                                                             PSTORAGE_FLASH_PAGE_SIZE;
+
+    // True if:
+    // - current page is not the last page OR
+    // - current page is the last page AND no tail exists
+    if ((m_current_page_id < id_last_page_to_be_cleared) ||
+        ((m_current_page_id == id_last_page_to_be_cleared) && (m_tail_word_size == 0)))         
+    {
+        ret = true;
+    }
+    else
+    {
+        ret = false;
+    }
+    
+    return ret;
+}
+
+
+/**@brief Function for reissuing the last flash operation request, which was rejected by the flash 
+ *        API, in swap sub sate.
+ */
+static void swap_sub_state_err_busy_process(void)
+{
+    // Reissue the request by doing a self transition to the current state.    
+    m_flags &= ~MASK_FLASH_API_ERR_BUSY;
+    swap_sub_state_state_change(m_swap_sub_state);        
+}
+
+
+/**@brief Function for doing restore head state action upon flash operation success event.
+ *
+ * @details Function for doing restore head state action upon flash operation success event, which 
+ *          includes making a state transition depending on the current state.
+ */
+static void head_restore_state_run(void)
+{
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {            
+        if (is_tail_data_page_swap_required())
+        {
+            // Additional data page needs to be swapped for tail section as we are clearing a block, 
+            // which is shared between 2 flash pages.
+                    
+            // Adjust variables to ensure correct state transition path is taken after the tail 
+            // section swap has completed.
+            m_head_word_size = 0;   
+            m_flags         |= MASK_TAIL_SWAP_DONE;        
+                  
+            swap_sub_state_state_change(STATE_ERASE_SWAP);        
+        }
+        else if (is_page_erase_required())
+        {
+            // Additional page erase operation is required.
+                    
+            // Adjust variable to ensure correct state transition path is taken after the additional 
+            // page erase operation has completed.
+            m_head_word_size = 0;
+            swap_sub_state_state_change(STATE_ERASE_DATA_PAGE);        
+        }            
+        else if (m_tail_word_size != 0)
+        {
+            // Proceed with restoring tail from swap to data page. 
+            swap_sub_state_state_change(STATE_RESTORE_TAIL);
+        }
+        else
+        {            
+            // Swap statemachine execution end reached.
+            swap_sub_sm_exit_action_run();        
+        }
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        swap_sub_state_err_busy_process();        
+    }
+}
+
+
+/**@brief Function for doing restore tail state action upon flash operation success event.
+ */
+static void tail_restore_state_run(void)
+{
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {
+        swap_sub_sm_exit_action_run();        
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        swap_sub_state_err_busy_process();        
+    }    
+}
+
+
+/**@brief Function for doing data page erase state action upon a flash operation success event.
+ *
+ * @details Function for doing data page erase state action upon a flash operation success event, 
+ *          which includes making a state transit to a new state depending on the current state.
+ */
+static void data_page_erase_state_run(void)
+{            
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {
+        ++m_current_page_id;   
+                    
+        if (m_head_word_size != 0)
+        {            
+            swap_sub_state_state_change(STATE_RESTORE_HEAD);
+        }
+        else if (is_page_erase_required())
+        {
+            // Additional page erase operation is required.    
+            swap_sub_state_state_change(STATE_ERASE_DATA_PAGE);                
+        }                
+        else if (m_tail_word_size != 0)
+        {                    
+            if (!(m_flags & MASK_TAIL_SWAP_DONE)) 
+            {
+                // Tail area restore is required and we have not yet written the relevant data page 
+                // to swap area. Start the process of writing the data page to swap.
+                m_flags |= MASK_TAIL_SWAP_DONE;            
+
+                swap_sub_state_state_change(STATE_ERASE_SWAP);            
+            }
+            else
+            {
+                // Tail area restore is required and we have already written the relevant data page 
+                // to swap area. Proceed by restoring the tail area.
+                swap_sub_state_state_change(STATE_RESTORE_TAIL);            
+            }
+        }            
+        else
+        {
+            swap_sub_sm_exit_action_run();        
+        }        
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        swap_sub_state_err_busy_process();        
+    }
+}
+
+
+/**@brief Function for doing data to swap write state action upon flash operation success event.
+ */
+static void data_to_swap_write_state_run(void)
+{        
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {
+        // If the operation is executed only on 1 single flash page it automatically means that tail 
+        // area is written to the swap, which we store to flags.     
+        if (m_flags & MASK_SINGLE_PAGE_OPERATION)
+        {
+            m_flags |= MASK_TAIL_SWAP_DONE;        
+        }
+
+        swap_sub_state_state_change(STATE_ERASE_DATA_PAGE);    
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        swap_sub_state_err_busy_process();        
+    }        
+}
+
+
+/**@brief Function for doing swap erase state action upon flash operation success event.
+ */
+static void swap_erase_state_run(void)
+{
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {        
+        swap_sub_state_state_change(STATE_WRITE_DATA_TO_SWAP);
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        swap_sub_state_err_busy_process();        
+    }
+}
+
+
+/**@brief Function for dispatching the correct state action for data erase with a swap composite 
+*         state upon a flash operation success event.
+ */
+static void swap_sub_state_sm_run(void)
+{  
+    static void (* const swap_sub_state_sm_lut[SWAP_SUB_STATE_MAX])(void) = 
+    {
+        swap_erase_state_run,
+        data_to_swap_write_state_run,
+        data_page_erase_state_run,
+        tail_restore_state_run,
+        head_restore_state_run
+    };
+    
+    swap_sub_state_sm_lut[m_swap_sub_state]();    
+}
+
+
+/**@brief Function for reissuing the last flash operation request, which was rejected by the flash 
+ *        API, in main sate.
+ */
+static void main_state_err_busy_process(void)
+{
+    // Reissue the request by doing a self transition to the current state.    
+    m_flags &= ~MASK_FLASH_API_ERR_BUSY;
+    sm_state_change(m_state);                    
+}
+
+
+/**@brief Function for doing erase state action upon flash operation success event.
+ *
+ * @details Function for doing erase state action upon flash operation success event, which includes 
+ *          making a state transition depending on the current state.
+ */
+static void erase_sub_state_sm_run(void)
+{
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {        
+        // Clear operation request has succeeded.
+        ++m_current_page_id;                        
+                
+        if (!is_page_erase_required())
+        {
+            clear_post_processing_run();
+        }
+        else
+        {   
+            // All required flash pages have not yet been erased, issue erase by doing a self 
+            // transit. 
+            sm_state_change(m_state);        
+        }                              
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        main_state_err_busy_process();
+    }
+}
+
+
+/**@brief Function for doing store state action upon flash operation success event.
+ */
+static void store_sub_state_sm_run(void)
+{
+    if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+    {        
+        // As write operation request has succeeded, adjust the size tracking state information 
+        // accordingly.
+        cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];    
+        p_cmd->size                -= m_num_of_bytes_written;
+
+        if (p_cmd->size == 0)
+        {
+            command_end_procedure_run();
+        }
+        else
+        {
+            store_cmd_flash_write_execute();
+        }
+    }
+    else
+    {
+        // As operation request was rejected by the flash API reissue the request.
+        main_state_err_busy_process();
+    }
+}
+
+
+/**@brief Function for doing action upon flash operation success event.
+ */
+static void flash_operation_success_run(void)
+{    
+    switch (m_state)
+    {                   
+        case STATE_STORE:
+            store_sub_state_sm_run();
+            break;
+                        
+        case STATE_DATA_ERASE:
+            erase_sub_state_sm_run();
+            break;
+                        
+        case STATE_DATA_ERASE_WITH_SWAP:
+            swap_sub_state_sm_run();                        
+            break;                        
+            
+        default:
+            // No implementation needed.
+            break;
+    }                    
+}
+
+
+/**@brief Function for doing action upon flash operation failure event.
+ *
+ * @details Function for doing action upon flash operation failure event, which includes retrying 
+ *          the last operation or if retry count has been reached completing the operation with 
+ *          appropriate result code and transitioning to an error state.
+ *
+ * @note    The command is not removed from the command queue, which will result to stalling of the 
+ *          command pipeline and the appropriate application recovery procedure for this is to reset 
+ *          the system by issuing @ref pstorage_init which will also result to flushing of the 
+ *          command queue.
+ */
+static void flash_operation_failure_run(void)
+{   
+    if (++m_num_of_command_retries != SD_CMD_MAX_TRIES)
+    {
+        // Retry the last operation by doing a self transition to the current state.
+            
+        if (m_state != STATE_DATA_ERASE_WITH_SWAP)
+        {
+            sm_state_change(m_state);        
+        }
+        else
+        {
+            swap_sub_state_state_change(m_swap_sub_state);
+        }
+    }
+    else
+    {
+        // Complete the operation with appropriate result code and transit to an error state.     
+        app_notify_error_state_transit(NRF_ERROR_TIMEOUT);        
+    }   
+}
+
+
+/**@brief Function for handling flash access result events.
+ *
+ * @param[in] sys_evt System event to be handled.
+ */
+void pstorage_sys_event_handler(uint32_t sys_evt)
+{  
+    if (m_state != STATE_IDLE && m_state != STATE_ERROR)
+    {        
+        switch (sys_evt)
+        {
+            case NRF_EVT_FLASH_OPERATION_SUCCESS:
+                flash_operation_success_run();
+                break;
+            
+            case NRF_EVT_FLASH_OPERATION_ERROR:            
+                if (!(m_flags & MASK_FLASH_API_ERR_BUSY))
+                {
+                    flash_operation_failure_run();
+                }
+                else
+                {
+                    // As our last flash operation request was rejected by the flash API reissue the 
+                    // request by doing same code execution path as for flash operation sucess 
+                    // event. This will promote code reuse in the implementation.                    
+                    flash_operation_success_run();
+                }                
+                break;
+                
+            default:
+                // No implementation needed.
+                break;
+        }
+
+    }
+}
+
+
+/**@brief Function for calculating the tail area size in number of 32-bit words.
+ *
+ * @param[in] cmd_end_of_storage_address End of storage area within the scope of the command.
+ * @param[in] end_of_storage_address     End of allocated storage area for the application.
+ */
+static void tail_word_size_calculate(pstorage_size_t cmd_end_of_storage_address, 
+                                     pstorage_size_t end_of_storage_address)
+{ 
+    // Two different cases to resolve when calculating correct size for restore tail section:
+    // 1) End of storage area and command end area are in the same page.
+    // 2) End of storage area and command end area are not in the same page.
+    
+    const uint32_t end_of_storage_area_page         = end_of_storage_address     / 
+                                                      PSTORAGE_FLASH_PAGE_SIZE;
+    const uint32_t command_end_of_storage_area_page = cmd_end_of_storage_address / 
+                                                      PSTORAGE_FLASH_PAGE_SIZE;
+
+    if (end_of_storage_area_page == command_end_of_storage_area_page)
+    {
+        //lint -e{573} suppress "Signed-unsigned mix with divide".
+        m_tail_word_size = (end_of_storage_address - cmd_end_of_storage_address) / sizeof(uint32_t);                                           
+    }
+    else
+    {
+        //lint -e{573} suppress "Signed-unsigned mix with divide".    
+        m_tail_word_size = (PSTORAGE_FLASH_PAGE_SIZE - 
+                           (cmd_end_of_storage_address % PSTORAGE_FLASH_PAGE_SIZE)) / 
+                           sizeof(uint32_t);               
+    }            
+}
+
+
+/**@brief Function for executing the clear operation.
+ */
+static void clear_operation_execute(void)
+{    
+    const cmd_queue_element_t * p_cmd        = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    const pstorage_block_t      cmd_block_id = p_cmd->storage_addr.block_id;
+
+    const pstorage_size_t  block_size    = m_app_table[p_cmd->storage_addr.module_id].block_size;
+    const pstorage_size_t  block_count   = m_app_table[p_cmd->storage_addr.module_id].block_count;
+    const pstorage_block_t block_base_id = m_app_table[p_cmd->storage_addr.module_id].base_id;  
+      
+    const bool is_start_address_page_aligned = (cmd_block_id % PSTORAGE_FLASH_PAGE_SIZE) == 0;
+    
+    // Calculate the end (1 beyond allocated area) for complete storage area and to the area only 
+    // within scope of this command.
+    const pstorage_block_t end_of_storage_address     = block_base_id + (block_size * block_count); 
+    const pstorage_block_t cmd_end_of_storage_address = cmd_block_id + p_cmd->size + p_cmd->offset;
+
+    // Zero tail to make sure no extra erase is done erroneously.
+    m_tail_word_size = 0;        
+        
+    // If the following is true no swap access is needed:
+    // - 1st logical test covers the case of: clear/update 1 complete single page.
+    // - 2nd logical test covers the case of: 
+    //   1) Clear/update last allocated page and page is not full (page can't be shared between 
+    //      multiple clients so the end of the page is unused area).
+    //   2) Clear/update all allocated storage.
+    if ((is_start_address_page_aligned && (p_cmd->size == PSTORAGE_FLASH_PAGE_SIZE)) ||
+        (is_start_address_page_aligned && (cmd_end_of_storage_address == end_of_storage_address) && 
+        (p_cmd->offset == 0)) || (p_cmd->storage_addr.module_id == RAW_MODE_APP_ID)) 
+    {
+        // Nothing to put to the swap and we can just erase the pages(s).         
+        
+        m_current_page_id = cmd_block_id / PSTORAGE_FLASH_PAGE_SIZE;
+        
+        sm_state_change(STATE_DATA_ERASE);                        
+    }
+    else
+    {
+        // Not all the blocks for the module can be cleared, we need to use swap page for storing 
+        // data temporarily.                        
+        
+        m_head_word_size = ((cmd_block_id + p_cmd->offset) % PSTORAGE_FLASH_PAGE_SIZE) / 
+                           sizeof(uint32_t);
+        
+        const bool is_cmd_end_address_page_aligned = ((cmd_end_of_storage_address % 
+                                                      PSTORAGE_FLASH_PAGE_SIZE) == 0);
+        if ((cmd_end_of_storage_address != end_of_storage_address) && 
+            !is_cmd_end_address_page_aligned)
+        {
+            // When command area is not equal to end of the storage allocation area and not ending 
+            // to page boundary there is a need to restore the tail area.
+            tail_word_size_calculate(cmd_end_of_storage_address, end_of_storage_address);
+        }
+
+        sm_state_change(STATE_DATA_ERASE_WITH_SWAP);         
+    }        
+}
+
+
+/**@brief Function for executing the store operation.
+ */
+static void store_operation_execute(void)
+{    
+    sm_state_change(STATE_STORE);
+}
+ 
+
+/**@brief Function for executing the update operation.
+ */ 
+static void update_operation_execute(void)
+{
+    clear_operation_execute();
+}
+
+
+/**@brief Function for dispatching the flash access operation.
+ */  
+static void cmd_process(void)
+{
+    const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    m_app_data_size                   = p_cmd->size;
+
+    switch (p_cmd->op_code)
+    {
+        case PSTORAGE_STORE_OP_CODE:                   
+            store_operation_execute();       
+            break;
+
+        case PSTORAGE_CLEAR_OP_CODE:
+            clear_operation_execute();
+            break;
+
+        case PSTORAGE_UPDATE_OP_CODE:
+            update_operation_execute();
+            break;
+
+        default:
+            // No action required.
+            break;
+    }
+}
+
+
+uint32_t pstorage_init(void)
+{
+    cmd_queue_init();
+
+    m_next_app_instance = 0;
+    m_next_page_addr    = PSTORAGE_DATA_START_ADDR;
+    m_current_page_id   = 0;
+    
+    for (uint32_t index = 0; index < PSTORAGE_NUM_OF_PAGES; index++)
+    {
+        m_app_table[index].cb           = NULL;
+        m_app_table[index].block_size   = 0;
+        m_app_table[index].block_count  = 0;
+    }
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+    m_raw_app_table.cb           = NULL;
+#endif //PSTORAGE_RAW_MODE_ENABLE
+
+    m_state                     = STATE_IDLE;
+    m_num_of_command_retries    = 0;
+    m_flags                     = 0;
+    m_num_of_bytes_written      = 0;
+    m_flags                    |= MASK_MODULE_INITIALIZED;
+       
+    return NRF_SUCCESS;
+}
+
+
+uint32_t pstorage_register(pstorage_module_param_t * p_module_param,
+                           pstorage_handle_t       * p_block_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_module_param);
+    NULL_PARAM_CHECK(p_block_id);
+    NULL_PARAM_CHECK(p_module_param->cb);
+    BLOCK_SIZE_CHECK(p_module_param->block_size);    
+    BLOCK_COUNT_CHECK(p_module_param->block_count, p_module_param->block_size);
+
+    if (!((p_module_param->block_size % sizeof(uint32_t)) == 0))
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+    
+    if (m_next_app_instance == PSTORAGE_NUM_OF_PAGES)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    p_block_id->module_id = m_next_app_instance;
+    p_block_id->block_id  = m_next_page_addr;
+
+    m_app_table[m_next_app_instance].base_id     = p_block_id->block_id;
+    m_app_table[m_next_app_instance].cb          = p_module_param->cb;
+    m_app_table[m_next_app_instance].block_size  = p_module_param->block_size;
+    m_app_table[m_next_app_instance].block_count = p_module_param->block_count;
+
+    // Calculate number of flash pages allocated for the device and adjust next free page address.
+    /*lint -save -e666 */
+    const uint32_t page_count = CEIL_DIV((p_module_param->block_size * p_module_param->block_count), 
+                                         PSTORAGE_FLASH_PAGE_SIZE);
+    /*lint -restore */
+    m_next_page_addr         += page_count * PSTORAGE_FLASH_PAGE_SIZE;
+    
+    ++m_next_app_instance;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id,
+                                       pstorage_size_t     block_num,
+                                       pstorage_handle_t * p_block_id)
+{
+    pstorage_handle_t temp_id;
+
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_base_id);
+    NULL_PARAM_CHECK(p_block_id);
+    MODULE_ID_RANGE_CHECK(p_base_id);
+
+    temp_id           = (*p_base_id);
+    temp_id.block_id += (block_num * MODULE_BLOCK_SIZE(p_base_id));
+
+    BLOCK_ID_RANGE_CHECK(&temp_id);
+
+    (*p_block_id) = temp_id;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t pstorage_store(pstorage_handle_t * p_dest,
+                        uint8_t           * p_src,
+                        pstorage_size_t     size,
+                        pstorage_size_t     offset)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_src);
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_ID_RANGE_CHECK(p_dest);
+    BLOCK_ID_RANGE_CHECK(p_dest);
+    SIZE_CHECK(p_dest, size);    
+    OFFSET_CHECK(p_dest, offset, size);
+    
+    if ((!is_word_aligned(p_src))                    || 
+        (!is_word_aligned((void *)(uint32_t)offset)) || 
+        (!is_word_aligned((uint32_t *)p_dest->block_id)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset);
+}
+
+
+uint32_t pstorage_update(pstorage_handle_t * p_dest,
+                         uint8_t           * p_src,
+                         pstorage_size_t     size,
+                         pstorage_size_t     offset)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_src);
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_ID_RANGE_CHECK(p_dest);
+    BLOCK_ID_RANGE_CHECK(p_dest);
+    SIZE_CHECK(p_dest, size);
+    OFFSET_CHECK(p_dest, offset, size);
+
+    if ((!is_word_aligned(p_src))                    || 
+        (!is_word_aligned((void *)(uint32_t)offset)) || 
+        (!is_word_aligned((uint32_t *)p_dest->block_id)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    return cmd_queue_enqueue(PSTORAGE_UPDATE_OP_CODE, p_dest, p_src, size, offset);
+}
+
+
+uint32_t pstorage_load(uint8_t           * p_dest,
+                       pstorage_handle_t * p_src,
+                       pstorage_size_t     size,
+                       pstorage_size_t     offset)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_src);
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_ID_RANGE_CHECK(p_src);
+    BLOCK_ID_RANGE_CHECK(p_src);
+    SIZE_CHECK(p_src, size);
+    OFFSET_CHECK(p_src, offset, size);
+
+    if ((!is_word_aligned(p_dest))                   || 
+        (!is_word_aligned((void *)(uint32_t)offset)) || 
+        (!is_word_aligned((uint32_t *)p_src->block_id)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    memcpy(p_dest, (((uint8_t *)p_src->block_id) + offset), size);
+
+    m_app_table[p_src->module_id].cb(p_src, PSTORAGE_LOAD_OP_CODE, NRF_SUCCESS, p_dest, size);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_ID_RANGE_CHECK(p_dest);
+    BLOCK_ID_RANGE_CHECK(p_dest);
+
+    if ((!is_word_aligned((uint32_t *)p_dest->block_id)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    // Check is the area starting from block_id multiple of block_size.
+    if (
+        !(
+            ((p_dest->block_id - m_app_table[p_dest->module_id].base_id) %
+             m_app_table[p_dest->module_id].block_size) == 0
+            )
+        )
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    // Check is requested size multiple of registered block size or 0.
+    if (((size % m_app_table[p_dest->module_id].block_size) != 0) || (size == 0))    
+    {        
+        return NRF_ERROR_INVALID_PARAM;        
+    }
+
+    const uint32_t registered_allocation_size = m_app_table[p_dest->module_id].block_size * 
+                                                m_app_table[p_dest->module_id].block_count;
+    
+    const pstorage_block_t clear_request_end_address = p_dest->block_id + size;
+    const pstorage_block_t allocation_end_address    = m_app_table[p_dest->module_id].base_id + 
+                                                       registered_allocation_size;
+    // Check if request would lead to a buffer overrun.                                                       
+    if (clear_request_end_address > allocation_end_address)
+    {        
+        return NRF_ERROR_INVALID_PARAM;            
+    }
+    
+    return cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL, size, 0);
+}
+
+
+uint32_t pstorage_access_status_get(uint32_t * p_count)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_count);
+
+    (*p_count) = m_cmd_queue.count;
+
+    return NRF_SUCCESS;
+}
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+
+uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param,
+                               pstorage_handle_t       * p_block_id)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_module_param);
+    NULL_PARAM_CHECK(p_block_id);
+    NULL_PARAM_CHECK(p_module_param->cb);
+
+    if (m_raw_app_table.cb != NULL)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    p_block_id->module_id = RAW_MODE_APP_ID;
+    m_raw_app_table.cb    = p_module_param->cb;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t pstorage_raw_store(pstorage_handle_t * p_dest,
+                            uint8_t           * p_src,
+                            pstorage_size_t     size,
+                            pstorage_size_t     offset)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_src);
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_RAW_HANDLE_CHECK(p_dest);
+    
+    if (size == 0)
+    {
+        return NRF_ERROR_INVALID_PARAM;        
+    }
+    
+    // Verify word alignment.
+    if ((!is_word_aligned(p_src))                    || 
+        (!is_word_aligned((void *)(uint32_t)size))   ||     
+        (!is_word_aligned((void *)(uint32_t)offset)) || 
+        (!is_word_aligned((void *)(p_dest->block_id))))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+       
+    return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset);
+}
+
+
+uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, pstorage_size_t size)
+{
+    VERIFY_MODULE_INITIALIZED();
+    NULL_PARAM_CHECK(p_dest);
+    MODULE_RAW_HANDLE_CHECK(p_dest);
+    
+    if ((!is_word_aligned((uint32_t *)p_dest->block_id)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }    
+
+    return cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL, size, 0);
+}
+
+#endif // PSTORAGE_RAW_MODE_ENABLE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/drivers_nrf/pstorage/pstorage.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 persistent_storage Persistent Storage Interface
+ * @{
+ * @ingroup app_common
+ * @brief Abstracted flash interface.
+ *
+ * @details  An abstracted interface is provided by the module to easily port the application and 
+ *           SDK modules to an alternate option. This ensures that the SDK and application are moved 
+ *           to alternate persistent storage instead of the one provided by default.
+ */
+
+#ifndef PSTORAGE_H__
+#define PSTORAGE_H__
+
+#include "pstorage_platform.h"
+
+
+/**@defgroup ps_opcode Persistent Storage Access Operation Codes
+ * @{
+ * @brief    Persistent Storage Access Operation Codes. 
+ *
+ * @details  Persistent Storage Access Operation Codes are used by Persistent storage operation 
+ *           completion callback @ref pstorage_ntf_cb_t to identify the operation type requested by 
+ *           the application.
+ */
+#define PSTORAGE_STORE_OP_CODE    0x01  /**< Store Operation type. */
+#define PSTORAGE_LOAD_OP_CODE     0x02  /**< Load Operation type. */
+#define PSTORAGE_CLEAR_OP_CODE    0x03  /**< Clear Operation type. */
+#define PSTORAGE_UPDATE_OP_CODE   0x04  /**< Update Operation type. */
+
+/**@} */
+
+/**@defgroup pstorage_data_types Persistent Memory Interface Data Types
+ * @{
+ * @brief Data Types needed for interfacing with persistent memory.
+ *
+ * @details Data Types needed for interfacing with persistent memory.
+ */
+
+/**@brief Persistent storage operation completion callback function type.
+ *
+ * @details The persistent storage operation completion callback is used by the interface to report
+ *          success or failure of a flash operation. Since data is not copied for a store operation, 
+ *          a callback is an indication that the resident memory can now be reused or freed.
+ * 
+ * @param[in] handle   Identifies the module and block for the callback that is received.
+ * @param[in] op_code  Identifies the operation for the event that is notified.
+ * @param[in] result   Identifies the result of a flash access operation. NRF_SUCCESS implies 
+ *                     operation succeeded.
+ *
+ *                     @note Unmanaged (abnormal behaviour) error codes from the SoftDevice flash 
+ *                     access API are forwarded as is and are expected to be handled by the 
+ *                     application. For details refer to the implementation file and corresponding 
+ *                     SoftDevice flash API documentation.
+ *                     
+ * @param[in] p_data   Identifies the application data pointer. For a store operation, this points 
+ *                     to the resident source of application memory that the application can now 
+ *                     free or reuse. When there is a clear operation, this is NULL since no 
+ *                     application pointer is needed for this operation.
+ * @param[in] data_len Length data the application provided for the operation. 
+ */
+typedef void (*pstorage_ntf_cb_t)(pstorage_handle_t * p_handle,
+                                  uint8_t             op_code,
+                                  uint32_t            result,
+                                  uint8_t *           p_data,
+                                  uint32_t            data_len);
+
+/**@brief Struct containing module registration context. */
+typedef struct
+{
+    pstorage_ntf_cb_t cb;             /**< Persistent storage operation completion callback function @ref pstorage_ntf_cb_t.  */
+    pstorage_size_t   block_size;     /**< Desired block size for persistent memory storage. For example, if a module has a table with 10 entries, and each entry is 64 bytes in size,
+                                       *   it can request 10 blocks with a block size of 64 bytes. The module can also request one block that is 640 bytes depending 
+                                       *   on how it would like to access or alter the memory in persistent memory.
+                                       *   The first option is preferred when it is a single entry that needs to be updated often and doesn't impact the other entries.
+                                       *   The second option is preferred when table entries are not changed individually but have a common point of loading and storing
+                                       *   data. */
+    pstorage_size_t   block_count;    /** Number of blocks requested by the module; minimum values is 1. */
+} pstorage_module_param_t;
+
+/**@} */
+
+/**@defgroup pstorage_routines Persistent Storage Access Routines
+ * @{
+ * @brief Functions/Interface SDK modules used to persistently store data.
+ *
+ * @details Interface for the Application and SDK modules to load/store information persistently.
+ *          Note: While implementation of each of the persistent storage access functions
+ *          depends on the system and is specific to system/solution, the signature of the
+ *          interface routines should not be altered.
+ */
+
+/**@brief Function for initializing the module.
+ *
+ * @details Function for initializing the module. This function is called once before any other APIs 
+ *          of the module are used.
+ *
+ * @retval     NRF_SUCCESS             Operation success.
+ */
+uint32_t pstorage_init(void);
+
+/**@brief Function for registering with persistent storage interface.
+ *
+ * @param[in]  p_module_param Module registration parameter.
+ * @param[out] p_block_id     Block identifier to identify persistent memory blocks when 
+ *                            registration succeeds. Application is expected to use the block IDs 
+ *                            for subsequent operations on requested persistent memory. Maximum 
+ *                            registrations permitted is determined by the configuration of the 
+ *                            parameter PSTORAGE_NUM_OF_PAGES. If more than one memory block is 
+ *                            requested, the identifier provided here is the base identifier for the 
+ *                            first block and used to identify the subsequent block. The application 
+ *                            uses \@ref pstorage_block_identifier_get with this base identifier and 
+ *                            block number. Therefore if 10 blocks of size 64 are requested and the 
+ *                            application wishes to store memory in the 6th block, it shall use
+ *                            \@ref pstorage_block_identifier_get with the base ID and provide a 
+ *                            block number of 5. This way the application is only expected to 
+ *                            remember the base block identifier.
+ *
+ * @retval     NRF_SUCCESS             Operation success.
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. Additional registrations can't be 
+ *                                     supported.
+ */
+uint32_t pstorage_register(pstorage_module_param_t * p_module_param,
+                           pstorage_handle_t *       p_block_id);
+
+/**@brief Function for getting block ID with reference to base block identifier provided at the time 
+ *        of registration.
+ *
+ * @details Function to get the block ID with reference to base block identifier provided at the 
+ *          time of registration.
+ *          If more than one memory block was requested when registering, the identifier provided 
+ *          here is the base identifier for the first block which is used to identify subsequent
+ *          blocks. The application shall use this routine to get the block identifier, providing 
+ *          input as base identifier and block number. Therefore, if 10 blocks of size 64 are 
+ *          requested and the application wishes to store memory in the 6th block, it shall use
+ *          \@ref pstorage_block_identifier_get with the base ID and provide a block number of 5.
+ *          This way the application is only expected to remember the base block identifier.
+ *
+ * @param[in]  p_base_id  Base block ID received at the time of registration.
+ * @param[in]  block_num  Block Number, with first block numbered zero.
+ * @param[out] p_block_id Block identifier for the block number requested when the API succeeds.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ */
+uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id,
+                                       pstorage_size_t     block_num,
+                                       pstorage_handle_t * p_block_id);
+
+/**@brief Function for persistently storing data of length 'size' contained in the 'p_src' address
+ *        in the storage module at 'p_dest' address. Equivalent to Storage Write.
+ *
+ * @param[in]  p_dest Destination address where data is to be stored persistently.
+ * @param[in]  p_src  Source address containing data to be stored. API assumes this to be resident
+ *                    memory and no intermediate copy of data is made by the API. Must be word 
+ *                    aligned.
+ * @param[in]  size   Size of data to be stored expressed in bytes. Must be word aligned and size + 
+ *                    offset must be <= block size.                      
+ * @param[in]  offset Offset in bytes to be applied when writing to the block.
+ *                    For example, if within a block of 100 bytes, the application wishes to
+ *                    write 20 bytes at an offset of 12, then this field should be set to 12.
+ *                    Must be word aligned.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_ADDR  Operation failure. Parameter is not aligned.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ *
+ * @warning    No copy of the data is made, meaning memory provided for the data source that is to 
+ *             be written to flash cannot be freed or reused by the application until this procedure
+ *             is complete. The application is notified when the procedure is finished using the
+ *             notification callback registered by the application.
+ */
+uint32_t pstorage_store(pstorage_handle_t * p_dest,
+                        uint8_t *           p_src,
+                        pstorage_size_t     size,
+                        pstorage_size_t     offset);
+
+/**@brief Function for updating persistently stored data of length 'size' contained in the 'p_src' 
+ *        address in the storage module at 'p_dest' address.
+ *
+ * @param[in]  p_dest Destination address where data is to be updated.
+ * @param[in]  p_src  Source address containing data to be stored. API assumes this to be resident
+ *                    memory and no intermediate copy of data is made by the API.
+ * @param[in]  size   Size of data to be stored expressed in bytes. Must be word aligned and size + 
+ *                    offset must be <= block size.
+ * @param[in]  offset Offset in bytes to be applied when writing to the block.
+ *                    For example, if within a block of 100 bytes, the application wishes to
+ *                    write 20 bytes at an offset of 12 bytes, then this field should be set to 12.
+ *                    Must be word aligned.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_ADDR  Operation failure. Parameter is not aligned.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ *
+ * @warning    No copy of the data is made, meaning memory provided for the data source that is to 
+ *             be written to flash cannot be freed or reused by the application until this procedure
+ *             is complete. The application is notified when the procedure is finished using the
+ *             notification callback registered by the application.
+ */
+uint32_t pstorage_update(pstorage_handle_t * p_dest,
+                         uint8_t *           p_src,
+                         pstorage_size_t     size,
+                         pstorage_size_t     offset);
+
+/**@brief Function for loading persistently stored data of length 'size' from 'p_src' address
+ *        to 'p_dest' address. Equivalent to Storage Read.
+ *
+ * @param[in]  p_dest Destination address where persistently stored data is to be loaded.
+ * @param[in]  p_src  Source where data is loaded from persistent memory.
+ * @param[in]  size   Size of data to be loaded from persistent memory expressed in bytes.
+ *                    Should be word aligned.
+ * @param[in]  offset Offset in bytes, to be applied when loading from the block.
+ *                    For example, if within a block of 100 bytes, the application wishes to
+ *                    load 20 bytes from offset of 12 bytes, then this field should be set to 12.
+ *                    Should be word aligned.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_ADDR  Operation failure. Parameter is not aligned.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ */
+uint32_t pstorage_load(uint8_t *           p_dest,
+                       pstorage_handle_t * p_src,
+                       pstorage_size_t     size,
+                       pstorage_size_t     offset);
+
+/**@brief Function for clearing data in persistent memory.
+ *
+ * @param[in]  p_base_id Base block identifier in persistent memory that needs to be cleared;
+ *                       equivalent to an Erase Operation.
+ * @param[in]  size      Size of data to be cleared from persistent memory expressed in bytes.
+ *                       This parameter is to provision for clearing of certain blocks
+ *                       of memory, or all memory blocks in a registered module. If the total size 
+ *                       of the application module is used (blocks * block size) in combination with
+ *                       the identifier for the first block in the module, all blocks in the 
+ *                       module will be erased. Must be multiple of block size.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_ADDR  Operation failure. Parameter is not aligned.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ *
+ * @note       Clear operations may take time. This API however, does not block until the clear
+ *             procedure is complete. The application is notified of procedure completion using
+ *             a notification callback registered by the application. The 'result' parameter of the
+ *             callback indicates if the procedure was successful or not.
+ */
+uint32_t pstorage_clear(pstorage_handle_t * p_base_id, pstorage_size_t size);
+
+/**@brief Function for getting the number of pending operations with the module.
+ *
+ * @param[out] p_count Number of storage operations pending with the module. If 0, there are no 
+ *                     outstanding requests.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ */
+uint32_t pstorage_access_status_get(uint32_t * p_count);
+
+#ifdef PSTORAGE_RAW_MODE_ENABLE
+
+/**@brief Function for registering with the persistent storage interface.
+ *
+ * @param[in]  p_module_param Module registration parameter.
+ * @param[out] p_block_id     Block identifier used to identify persistent memory blocks upon 
+ *                            successful registration. The application is expected to use the block 
+ *                            IDs for subsequent operations on requested persistent memory. When 
+ *                            more than one memory block is requested, this identifier is the base 
+ *                            identifier for the first block and used to identify subsequent blocks. 
+ *                            The application shall use \@ref pstorage_block_identifier_get with 
+ *                            this base identifier and block number. Therefore if 10 blocks of size 
+ *                            64 are requested and the application wishes to store memory in the 6th 
+ *                            block, it shall use \@ref pstorage_block_identifier_get with the base 
+ *                            ID and provide a block number of 5. Therefore, the application is only 
+ *                            expected to remember the base block identifier.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ */
+uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param,
+                               pstorage_handle_t *       p_block_id);
+
+/**@brief Function for persistently storing data of length 'size' contained in 'p_src' address in 
+ *        storage module at 'p_dest' address. Equivalent to Storage Write.
+ *
+ * @param[in]  p_dest Destination address where data is to be stored persistently.
+ * @param[in]  p_src  Source address containing data to be stored. The API assumes this is resident
+ *                    memory and no intermediate copy of data is made by the API. Must be word 
+ *                    aligned.
+ * @param[in]  size   Size of data to be stored expressed in bytes. Must be word aligned.
+ * @param[in]  offset Offset in bytes to be applied when writing to the block.
+ *                    For example, if within a block of 100 bytes, the application wishes to
+ *                    write 20 bytes at an offset of 12 bytes, this field should be set to 12.
+ *                    Must be word aligned.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_ADDR  Operation failure. Parameter is not aligned.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ *
+ * @warning    No copy of the data is made, meaning memory provided for data source that is to be 
+ *             written to flash cannot be freed or reused by the application until this procedure
+ *             is complete. The application is notified when the procedure is finished using the
+ *             notification callback registered by the application.
+ */
+uint32_t pstorage_raw_store(pstorage_handle_t * p_dest,
+                            uint8_t *           p_src,
+                            pstorage_size_t     size,
+                            pstorage_size_t     offset);
+
+/**@brief Function for clearing data in persistent memory in raw mode.
+ *
+ * @param[in]  p_dest Base block identifier in persistent memory that needs to be cleared.
+ *                    Equivalent to an Erase Operation.
+ * @param[in]  size   Size of data to be cleared from persistent memory expressed in bytes. 
+ *                    Not used.
+ *
+ * @retval     NRF_SUCCESS             Operation success. 
+ * @retval     NRF_ERROR_INVALID_STATE Operation failure. API is called without module 
+ *                                     initialization.
+ * @retval     NRF_ERROR_NULL          Operation failure. NULL parameter has been passed.
+ * @retval     NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
+ * @retval     NRF_ERROR_NO_MEM        Operation failure. No storage space available.
+ *
+ * @note       Clear operations may take time. This API, however, does not block until the clear
+ *             procedure is complete. The application is notified of procedure completion using
+ *             a notification callback registered by the application. The 'result' parameter of the
+ *             callback indicates if the procedure was successful or not.
+ */
+uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, pstorage_size_t size);
+
+#endif // PSTORAGE_RAW_MODE_ENABLE
+
+/**@} */
+/**@} */
+
+#endif // PSTORAGE_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_bootloader Bootloader API.
+ * @{     
+ *
+ * @brief Bootloader module interface.
+ */
+
+#ifndef BOOTLOADER_H__
+#define BOOTLOADER_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "bootloader_types.h"
+#include <dfu_types.h>
+
+/**@brief Function for initializing the Bootloader.
+ * 
+ * @retval     NRF_SUCCESS If bootloader was succesfully initialized. 
+ */
+uint32_t bootloader_init(void);
+
+/**@brief Function for validating application region in flash.
+ * 
+ * @param[in]  app_addr      Address to the region in flash where the application is stored.
+ * 
+ * @retval     true          If Application region is valid.
+ * @retval     false         If Application region is not valid.
+ */
+bool bootloader_app_is_valid(uint32_t app_addr);
+
+/**@brief Function for starting the Device Firmware Update.
+ * 
+ * @retval     NRF_SUCCESS If new application image was successfully transferred.
+ */
+uint32_t bootloader_dfu_start(void);
+
+/**@brief Function for exiting bootloader and booting into application.
+ *
+ * @details This function will disable SoftDevice and all interrupts before jumping to application.
+ *          The SoftDevice vector table base for interrupt forwarding will be set the application
+ *          address.
+ *
+ * @param[in]  app_addr      Address to the region where the application is stored.
+ */
+void bootloader_app_start(uint32_t app_addr);
+
+/**@brief Function for retrieving the bootloader settings.
+ *
+ * @param[out] p_settings    A copy of the current bootloader settings is returned in the structure
+ *                           provided.
+ */
+void bootloader_settings_get(bootloader_settings_t * const p_settings);
+
+/**@brief Function for processing DFU status update.
+ *
+ * @param[in]  update_status DFU update status.
+ */
+void bootloader_dfu_update_process(dfu_update_status_t update_status);
+
+/**@brief Function getting state of SoftDevice update in progress.
+ *        After a successfull SoftDevice transfer the system restarts in orderto disable SoftDevice
+ *        and complete the update.
+ *
+ * @retval     true          A SoftDevice update is in progress. This indicates that second stage 
+ *                           of a SoftDevice update procedure can be initiated.
+ * @retval     false         No SoftDevice update is in progress.
+ */
+bool bootloader_dfu_sd_in_progress(void);
+
+/**@brief Function for continuing the Device Firmware Update of a SoftDevice.
+ * 
+ * @retval     NRF_SUCCESS If the final stage of SoftDevice update was successful. 
+ */
+uint32_t bootloader_dfu_sd_update_continue(void);
+
+/**@brief Function for finalizing the Device Firmware Update of a SoftDevice.
+ * 
+ * @retval     NRF_SUCCESS If the final stage of SoftDevice update was successful. 
+ */
+uint32_t bootloader_dfu_sd_update_finalize(void);
+
+#endif // BOOTLOADER_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_bootloader_types Types and definitions.
+ * @{     
+ *  
+ * @ingroup nrf_bootloader
+ * 
+ * @brief Bootloader module type and definitions.
+ */
+ 
+#ifndef BOOTLOADER_TYPES_H__
+#define BOOTLOADER_TYPES_H__
+
+#include <stdint.h>
+
+#define BOOTLOADER_DFU_START 0xB1
+
+#define BOOTLOADER_SVC_APP_DATA_PTR_GET 0x02
+
+/**@brief DFU Bank state code, which indicates wether the bank contains: A valid image, invalid image, or an erased flash.
+  */
+typedef enum
+{
+    BANK_VALID_APP   = 0x01,
+    BANK_VALID_SD    = 0xA5,
+    BANK_VALID_BOOT  = 0xAA,
+    BANK_ERASED      = 0xFE,
+    BANK_INVALID_APP = 0xFF,
+} bootloader_bank_code_t;
+
+/**@brief Structure holding bootloader settings for application and bank data.
+ */
+typedef struct
+{
+    bootloader_bank_code_t bank_0;          /**< Variable to store if bank 0 contains a valid application. */
+    uint16_t               bank_0_crc;      /**< If bank is valid, this field will contain a valid CRC of the total image. */
+    bootloader_bank_code_t bank_1;          /**< Variable to store if bank 1 has been erased/prepared for new image. Bank 1 is only used in Banked Update scenario. */
+    uint32_t               bank_0_size;     /**< Size of active image in bank0 if present, otherwise 0. */
+    uint32_t               sd_image_size;   /**< Size of SoftDevice image in bank0 if bank_0 code is BANK_VALID_SD. */
+    uint32_t               bl_image_size;   /**< Size of Bootloader image in bank0 if bank_0 code is BANK_VALID_SD. */
+    uint32_t               app_image_size;  /**< Size of Application image in bank0 if bank_0 code is BANK_VALID_SD. */
+    uint32_t               sd_image_start;  /**< Location in flash where SoftDevice image is stored for SoftDevice update. */
+} bootloader_settings_t;
+
+#endif // BOOTLOADER_TYPES_H__ 
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_util.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "bootloader_util.h"
+#include <stdint.h>
+#include <string.h>
+
+
+/**
+ * @brief Function for aborting current application/bootloader jump to to other app/bootloader.
+ *
+ * @details This functions will use the address provide to swap the stack pointer and then load 
+ *          the address of the reset handler to be executed. It will check current system mode 
+ *          (thread/handler) and if in thread mode it will reset into other application.
+ *          If in handler mode \ref isr_abort will be executed to ensure correct exit of handler 
+ *          mode and jump into reset handler of other application.
+ *
+ * @param[in]  start_addr  Start address of other application. This address must point to the 
+               initial stack pointer of the application.
+ *
+ * @note This function will never return but issue a reset into provided application.
+ */
+#if defined ( __CC_ARM )
+__asm static void bootloader_util_reset(uint32_t start_addr)
+{
+    LDR   R5, [R0]              ; Get App initial MSP for bootloader.
+    MSR   MSP, R5               ; Set the main stack pointer to the applications MSP.
+    LDR   R0, [R0, #0x04]       ; Load Reset handler into R0. This will be first argument to branch instruction (BX).
+
+    MOVS  R4, #0xFF             ; Load ones to R4.
+    SXTB  R4, R4                ; Sign extend R4 to obtain 0xFFFFFFFF instead of 0xFF.
+    MRS   R5, IPSR              ; Load IPSR to R5 to check for handler or thread mode.
+    CMP   R5, #0x00             ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader.
+    BNE   isr_abort             ; If not zero we need to exit current ISR and jump to reset handler of bootloader.
+
+    MOV   LR, R4                ; Clear the link register and set to ones to ensure no return, R4 = 0xFFFFFFFF.
+    BX    R0                    ; Branch to reset handler of bootloader.
+
+isr_abort
+                                ; R4 contains ones from line above. Will be popped as R12 when exiting ISR (Cleaning up the registers).
+    MOV   R5, R4                ; Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application.
+    MOV   R6, R0                ; Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
+    MOVS  r7, #0x21             ; Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21.
+    REV   r7, r7                ; Reverse byte order to put 0x21 as MSB.
+    PUSH  {r4-r7}               ; Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
+
+    MOVS  R4, #0x00             ; Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
+    MOVS  R5, #0x00             ; Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
+    MOVS  R6, #0x00             ; Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
+    MOVS  R7, #0x00             ; Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
+    PUSH  {r4-r7}               ; Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
+
+    MOVS  R0, #0xF9             ; Move the execution return command into register, 0xFFFFFFF9.
+    SXTB  R0, R0                ; Sign extend R0 to obtain 0xFFFFFFF9 instead of 0xF9.
+    BX    R0                    ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
+    ALIGN
+}
+#elif defined ( __GNUC__ )
+static inline void bootloader_util_reset(uint32_t start_addr)
+{
+    __asm volatile(
+        "ldr   r0, [%0]\t\n"            // Get App initial MSP for bootloader.
+        "msr   msp, r0\t\n"             // Set the main stack pointer to the applications MSP.
+        "ldr   r0, [%0, #0x04]\t\n"     // Load Reset handler into R0.
+
+        "movs  r4, #0xFF\t\n"           // Move ones to R4.
+        "sxtb  r4, r4\t\n"              // Sign extend R4 to obtain 0xFFFFFFFF instead of 0xFF.
+
+        "mrs   r5, IPSR\t\n"            // Load IPSR to R5 to check for handler or thread mode.
+        "cmp   r5, #0x00\t\n"           // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader.
+        "bne   isr_abort\t\n"           // If not zero we need to exit current ISR and jump to reset handler of bootloader.
+
+        "mov   lr, r4\t\n"              // Clear the link register and set to ones to ensure no return.
+        "bx    r0\t\n"                  // Branch to reset handler of bootloader.
+
+        "isr_abort:  \t\n"
+
+        "mov   r5, r4\t\n"              // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application.
+        "mov   r6, r0\t\n"              // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
+        "movs  r7, #0x21\t\n"           // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21.
+        "rev   r7, r7\t\n"              // Reverse byte order to put 0x21 as MSB.
+        "push  {r4-r7}\t\n"             // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
+
+        "movs  r4, #0x00\t\n"           // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
+        "movs  r5, #0x00\t\n"           // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
+        "movs  r6, #0x00\t\n"           // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
+        "movs  r7, #0x00\t\n"           // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
+        "push  {r4-r7}\t\n"             // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
+
+        "movs  r0, #0xF9\t\n"           // Move the execution return command into register, 0xFFFFFFF9.
+        "sxtb  r0, r0\t\n"              // Sign extend R0 to obtain 0xFFFFFFF9 instead of 0xF9.
+        "bx    r0\t\n"                  // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
+        ".align\t\n"
+        :: "r" (start_addr)             // Argument list for the gcc assembly. start_addr is %0.
+        :  "r0", "r4", "r5", "r6", "r7" // List of register maintained manually.
+    );
+}
+#elif defined ( __ICCARM__ )
+static inline void bootloader_util_reset(uint32_t start_addr)
+{
+    asm("ldr   r5, [%0]\n"                    // Get App initial MSP for bootloader.
+        "msr   msp, r5\n"                     // Set the main stack pointer to the applications MSP.
+        "ldr   r0, [%0, #0x04]\n"             // Load Reset handler into R0.
+
+        "movs  r4, #0x00\n"                   // Load zero into R4.
+        "mvns  r4, r4\n"                      // Invert R4 to ensure it contain ones.
+
+        "mrs   r5, IPSR\n"                    // Load IPSR to R5 to check for handler or thread mode 
+        "cmp   r5, #0x00\n"                   // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader.
+        "bne   isr_abort\n"                   // If not zero we need to exit current ISR and jump to reset handler of bootloader.
+
+        "mov   lr, r4\n"                      // Clear the link register and set to ones to ensure no return.
+        "bx    r0\n"                          // Branch to reset handler of bootloader.
+
+        "isr_abort: \n"
+                                              // R4 contains ones from line above. We be popped as R12 when exiting ISR (Cleaning up the registers).
+        "mov   r5, r4\n"                      // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application.
+        "mov   r6, r0\n"                      // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
+        "movs  r7, #0x21\n"                   // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21.
+        "rev   r7, r7\n"                      // Reverse byte order to put 0x21 as MSB.
+        "push  {r4-r7}\n"                     // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
+
+        "movs  r4, #0x00\n"                   // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
+        "movs  r5, #0x00\n"                   // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
+        "movs  r6, #0x00\n"                   // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
+        "movs  r7, #0x00\n"                   // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
+        "push  {r4-r7}\n"                     // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
+
+        "movs  r0, #0x06\n"                   // Load 0x06 into R6 to prepare for exec return command.
+        "mvns  r0, r0\n"                      // Invert 0x06 to obtain EXEC_RETURN, 0xFFFFFFF9.
+        "bx    r0\n"                          // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
+        :: "r" (start_addr)                   // Argument list for the IAR assembly. start_addr is %0.
+        :  "r0", "r4", "r5", "r6", "r7");     // List of register maintained manually.
+}
+#else
+#error Compiler not supported.
+#endif
+
+
+void bootloader_util_app_start(uint32_t start_addr)
+{
+    bootloader_util_reset(start_addr);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/bootloader_util.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_bootloader_util Bootloader util API.
+ * @{     
+ *  
+ * @brief Bootloader util module interface.
+ */
+ 
+#ifndef BOOTLOADER_UTIL_H__
+#define BOOTLOADER_UTIL_H__
+
+#include <stdint.h>
+#include "bootloader_types.h"
+
+/**@brief Function for starting the application (or bootloader) at the provided address.
+ * 
+ * @param[in]  start_addr             Start address.
+ *
+ * @note This function will never retrun. Instead it will reset into the application of the 
+ *       provided address.
+ */
+void bootloader_util_app_start(uint32_t start_addr);
+
+#endif // BOOTLOADER_UTIL_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu Device Firmware Update API.
+ * @{     
+ *
+ * @brief Device Firmware Update module interface.
+ */
+
+#ifndef DFU_H__
+#define DFU_H__
+
+#include <dfu_types.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+/**@brief DFU event callback for asynchronous calls.
+ *
+ * @param[in] packet  Packet type for which this callback is related. START_PACKET, DATA_PACKET.
+ * @param[in] result  Operation result code. NRF_SUCCESS when a queued operation was successful.
+ * @param[in] p_data  Pointer to the data to which the operation is related.
+ */
+typedef void (*dfu_callback_t)(uint32_t packet, uint32_t  result, uint8_t * p_data);
+
+/**@brief Function for initializing the Device Firmware Update module.
+ * 
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_init(void);
+
+/**@brief Function for registering a callback listener for \ref dfu_data_pkt_handle callbacks.
+ *
+ * @param[in] callback_handler  Callback handler for receiving DFU events on completed operations
+ *                              of DFU packets.
+ */
+void dfu_register_callback(dfu_callback_t callback_handler);
+
+/**@brief Function for setting the DFU image size. 
+ *
+ * @details Function sets the DFU image size. This function must be called when an update is started 
+ *          in order to notify the DFU of the new image size. If multiple images are to be 
+ *          transferred within the same update context then this function must be called with size 
+ *          information for each image being transfered.
+ *          If an image type is not being transfered, e.g. SoftDevice but no Application , then the
+ *          image size for application must be zero.
+ * 
+ * @param[in] p_packet   Pointer to the DFU packet containing information on DFU update process to
+ *                       be started.
+ *
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet);
+
+/**@brief Function for handling DFU data packets.
+ *
+ * @param[in] p_packet   Pointer to the DFU packet.
+ *
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet);
+
+/**@brief Function for handling DFU init packets.
+ *
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet);
+
+/**@brief Function for validating a transferred image after the transfer has completed.
+ * 
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_image_validate(void);
+
+/**@brief Function for activating the transfered image after validation has successfully completed.
+ *
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_image_activate(void);
+
+/**@brief Function for reseting the current update procedure and return to initial state.
+ *        
+ * @details This function call will result in a system reset to ensure correct system behavior.
+ *          The reset will might be scheduled to execute at a later point in time to ensure pending 
+ *          flash operations has completed.
+ */
+void dfu_reset(void);
+
+/**@brief Function for validating that new bootloader has been correctly installed.
+ *        
+ * @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs.
+ */
+uint32_t dfu_bl_image_validate(void);
+
+/**@brief Function for validating that new SoftDevicehas been correctly installed.
+ *        
+ * @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs.
+ */
+uint32_t dfu_sd_image_validate(void);
+
+/**@brief Function for swapping existing bootloader with newly received.
+ *        
+ * @return NRF_SUCCESS on succesfull swapping. For error code please refer to 
+ *         \ref sd_mbr_command_copy_bl_t.
+ */
+uint32_t dfu_bl_image_swap(void);
+
+/**@brief Function for swapping existing SoftDevice with newly received.
+ *        
+ * @return NRF_SUCCESS on succesfull swapping. For error code please refer to 
+ *         \ref sd_mbr_command_copy_sd_t.
+ */
+uint32_t dfu_sd_image_swap(void);
+
+/**@brief Function for handling DFU init packet complete.
+ *
+ * @return    NRF_SUCCESS on success, an error_code otherwise.
+ */
+uint32_t dfu_init_pkt_complete(void);
+
+#endif // DFU_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_app_handler.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "dfu_app_handler.h"
+#include <string.h>
+#include "bootloader_util.h"
+#include "nrf.h"
+#include "nrf_sdm.h"
+#include "ble_gatt.h"
+#include "ble_gatts.h"
+#include "app_error.h"
+#include "dfu_ble_svc.h"
+#include "device_manager.h"
+#include "nrf_delay.h"
+
+#define IRQ_ENABLED            0x01                                     /**< Field that identifies if an interrupt is enabled. */
+#define MAX_NUMBER_INTERRUPTS  32                                       /**< Maximum number of interrupts available. */
+
+static void                    dfu_app_reset_prepare(void);             /**< Forward declaration of default reset handler. */
+static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to clean up service and memory before reset. */
+static dfu_ble_peer_data_t     m_peer_data;                             /**< Peer data to be used for data exchange when resetting into DFU mode. */
+static dm_handle_t             m_dm_handle;                             /**< Device Manager handle with instance IDs of current BLE connection. */
+
+
+/**@brief Function for reset_prepare handler if the application has not registered a handler.
+ */
+static void dfu_app_reset_prepare(void)
+{
+    // Reset prepare should be handled by application.
+    // This function can be extended to include default handling if application does not implement
+    // own handler.
+}
+
+
+/**@brief Function for disabling all interrupts before jumping from bootloader to application.
+ */
+static void interrupts_disable(void)
+{
+    uint32_t interrupt_setting_mask;
+    uint32_t irq;
+
+    // Fetch the current interrupt settings.
+    interrupt_setting_mask = NVIC->ISER[0];
+
+    // Loop from interrupt 0 for disabling of all interrupts.
+    for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++)
+    {
+        if (interrupt_setting_mask & (IRQ_ENABLED << irq))
+        {
+            // The interrupt was enabled, hence disable it.
+            NVIC_DisableIRQ((IRQn_Type)irq);
+        }
+    }
+}
+
+
+/**@brief Function for providing peer information to DFU for re-establishing a bonded connection in
+ *        DFU mode.
+ *
+ * @param[in] conn_handle   Connection handle for the connection requesting DFU mode.
+ */
+static void dfu_app_peer_data_set(uint16_t conn_handle)
+{
+    uint32_t                 err_code;
+    dm_sec_keyset_t          key_set;
+    uint32_t                 app_context_data = 0;
+    dm_application_context_t app_context;
+
+
+/** [DFU bond sharing] */
+    err_code = dm_handle_get(conn_handle, &m_dm_handle);
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
+        if (err_code == NRF_SUCCESS)
+        {
+            APP_ERROR_CHECK(err_code);
+
+            m_peer_data.addr              = key_set.keys_central.p_id_key->id_addr_info;
+            m_peer_data.irk               = key_set.keys_central.p_id_key->id_info;
+            m_peer_data.enc_key.enc_info  = key_set.keys_periph.enc_key.p_enc_key->enc_info;
+            m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id;
+
+            err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
+            APP_ERROR_CHECK(err_code);
+
+            app_context_data   = (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS);
+            app_context.len    = sizeof(app_context_data);
+            app_context.p_data = (uint8_t *)&app_context_data;
+            app_context.flags  = 0;
+
+            err_code = dm_application_context_set(&m_dm_handle, &app_context);
+            APP_ERROR_CHECK(err_code);
+        }
+        else
+        {
+            // Keys were not available, thus we have a non-encrypted connection.
+            err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr);
+            APP_ERROR_CHECK(err_code);
+
+            err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
+            APP_ERROR_CHECK(err_code);
+        }
+    }
+/** [DFU bond sharing] */
+}
+
+
+/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader.
+ *
+ * @param[in] conn_handle Connection handle for peer requesting to enter DFU mode.
+ */
+static void bootloader_start(uint16_t conn_handle)
+{
+    uint32_t err_code;
+    uint16_t sys_serv_attr_len = sizeof(m_peer_data.sys_serv_attr);
+
+    err_code = sd_ble_gatts_sys_attr_get(conn_handle,
+                                         m_peer_data.sys_serv_attr,
+                                         &sys_serv_attr_len,
+                                         BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+    if (err_code != NRF_SUCCESS)
+    {
+        // Any error at this stage means the system service attributes could not be fetched.
+        // This means the service changed indication cannot be sent in DFU mode, but connection
+        // is still possible to establish.
+    }
+
+    m_reset_prepare();
+
+    err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = sd_softdevice_disable();
+    APP_ERROR_CHECK(err_code);
+
+    err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
+    APP_ERROR_CHECK(err_code);
+
+    dfu_app_peer_data_set(conn_handle);
+
+    NVIC_ClearPendingIRQ(SWI2_IRQn);
+    interrupts_disable();
+    bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
+}
+
+
+void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
+{
+    switch (p_evt->ble_dfu_evt_type)
+    {
+        case BLE_DFU_START:
+            // Starting the bootloader - will cause reset.
+            bootloader_start(p_dfu->conn_handle);
+            break;
+
+        default:
+            {
+                // Unsupported event received from DFU Service. 
+                // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
+                uint32_t err_code = ble_dfu_response_send(p_dfu,
+                                                          BLE_DFU_START_PROCEDURE,
+                                                          BLE_DFU_RESP_VAL_NOT_SUPPORTED);
+                APP_ERROR_CHECK(err_code);
+            }
+            break;
+    }
+}
+
+
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
+{
+    m_reset_prepare = reset_prepare_func;
+}
+
+
+void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance)
+{
+    uint32_t err_code;
+    
+    err_code = dm_application_instance_set(&app_instance, &m_dm_handle);
+    APP_ERROR_CHECK(err_code);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_app_handler.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_app_handler DFU BLE packet handling in application
+ * @{
+ *
+ * @brief Handling of DFU BLE packets in the application.
+ *
+ * @details This module implements the handling of DFU packets for switching 
+ *          from an application to the bootloader and start DFU mode. The DFU
+ *          packets are transmitted over BLE. 
+ *          This module handles only the StartDFU packet, which allows a BLE 
+ *          application to expose support for the DFU Service.
+ *          The actual DFU Service runs in a dedicated environment after a BLE 
+ *          disconnect and reset of the \nRFXX device. 
+ *          The host must reconnect and continue the update procedure with 
+ *          access to the full DFU Service.
+ *
+ * @note The application must propagate DFU events to this module by calling
+ *       @ref dfu_app_on_dfu_evt from the @ref ble_dfu_evt_handler_t callback.
+ */
+ 
+#ifndef DFU_APP_HANDLER_H__
+#define DFU_APP_HANDLER_H__
+
+#include "ble_dfu.h"
+#include "nrf_svc.h"
+#include "bootloader_types.h"
+#include "device_manager.h"
+
+#define DFU_APP_ATT_TABLE_POS     0                     /**< Position for the ATT table changed setting. */
+#define DFU_APP_ATT_TABLE_CHANGED 1                     /**< Value indicating that the ATT table might have changed. This value will be set in the application-specific context in Device Manager when entering DFU mode. */
+
+/**@brief DFU application reset_prepare function. This function is a callback that allows the 
+ *        application to prepare for an upcoming application reset. 
+ */
+typedef void (*dfu_app_reset_prepare_t)(void);
+
+/**@brief   Function for handling events from the DFU Service. 
+ *
+ * @details The application must inject this function into the DFU Service or propagate DFU events 
+ *          to the dfu_app_handler module by calling this function in the application-specific DFU event 
+ *          handler.
+ * 
+ * @param[in] p_dfu  Pointer to the DFU Service structure to which the include event relates.
+ * @param[in] p_evt  Pointer to the DFU event.
+ */
+void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
+
+/**@brief Function for registering a function to prepare a reset.
+ *
+ * @details The provided function is executed before resetting the system into bootloader/DFU
+ *          mode. By registering this function, the caller is notified before the reset and can
+ *          thus prepare the application for reset. For example, the application can gracefully
+ *          disconnect any peers on BLE, turn of LEDS, ensure that all pending flash operations
+ *          have completed, and so on.
+ *
+ * @param[in] reset_prepare_func  Function to be executed before a reset.
+ */
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func);
+
+/**@brief Function for setting the Device Manager application instance.
+ *
+ * @details This function allows to set the @ref dm_application_instance_t value that is returned by the 
+ *          Device Manager when the application registers using @ref dm_register.
+ *          If this function is not called, it is not be possible to share bonding information
+ *          from the application to the bootloader/DFU when entering DFU mode.
+ *
+ * @param[in] app_instance Value for the application instance in use.
+ */
+void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance);
+
+#endif // DFU_APP_HANDLER_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_bank_internal.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 dfu_bank_internal Device Firmware Update internal header for bank handling in DFU.
+ * @{     
+ *
+ * @brief Device Firmware Update Bank handling module interface.
+ *
+ * @details This header is intended for shared definition and functions between single and dual bank 
+ *         implementations used for DFU support. It is not supposed to be used for external access 
+ *         to the DFU module.
+ *  
+ */
+#ifndef DFU_BANK_INTERNAL_H__
+#define DFU_BANK_INTERNAL_H__
+
+#include <dfu_types.h>
+
+/**@brief States of the DFU state machine. */
+typedef enum
+{
+    DFU_STATE_INIT_ERROR,                                                           /**< State for: dfu_init(...) error. */
+    DFU_STATE_IDLE,                                                                 /**< State for: idle. */
+    DFU_STATE_PREPARING,                                                            /**< State for: preparing, indicates that the flash is being erased and no data packets can be processed. */
+    DFU_STATE_RDY,                                                                  /**< State for: ready. */
+    DFU_STATE_RX_INIT_PKT,                                                          /**< State for: receiving initialization packet. */
+    DFU_STATE_RX_DATA_PKT,                                                          /**< State for: receiving data packet. */
+    DFU_STATE_VALIDATE,                                                             /**< State for: validate. */
+    DFU_STATE_WAIT_4_ACTIVATE                                                       /**< State for: waiting for dfu_image_activate(). */
+} dfu_state_t;
+
+#define APP_TIMER_PRESCALER         0                                               /**< Value of the RTC1 PRESCALER register. */
+#define DFU_TIMEOUT_INTERVAL        APP_TIMER_TICKS(120000, APP_TIMER_PRESCALER)    /**< DFU timeout interval in units of timer ticks. */     
+
+#define IS_UPDATING_SD(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_SD)   /**< Macro for determining if a SoftDevice update is ongoing. */
+#define IS_UPDATING_BL(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_BL)   /**< Macro for determining if a Bootloader update is ongoing. */
+#define IS_UPDATING_APP(START_PKT)  ((START_PKT).dfu_update_mode & DFU_UPDATE_APP)  /**< Macro for determining if a Application update is ongoing. */
+#define IMAGE_WRITE_IN_PROGRESS()   (m_data_received > 0)                           /**< Macro for determining if an image write is in progress. */
+#define IS_WORD_SIZED(SIZE)         ((SIZE & (sizeof(uint32_t) - 1)) == 0)          /**< Macro for checking that the provided is word sized. */
+
+/**@cond NO_DOXYGEN */
+static uint32_t                     m_data_received;                                /**< Amount of received data. */
+/**@endcond */
+
+/**@brief     Type definition of function used for preparing of the bank before receiving of a
+ *            software image.
+ *
+ * @param[in] image_size  Size of software image being received.
+ */
+typedef void (*dfu_bank_prepare_t)(uint32_t image_size);
+
+/**@brief     Type definition of function used for handling clear complete of the bank before 
+ *            receiving of a software image.
+ */
+typedef void (*dfu_bank_cleared_t)(void);
+
+/**@brief    Type definition of function used for activating of the software image received.
+ *
+ * @return  NRF_SUCCESS If the image has been successfully activated any other NRF_ERROR code in
+ *          case of a failure.
+ */
+typedef uint32_t (*dfu_bank_activate_t)(void);
+
+/**@brief Structure for holding of function pointers for needed prepare and activate procedure for
+ *        the requested update procedure. 
+ */
+typedef struct
+{
+    dfu_bank_prepare_t  prepare;                                                    /**< Function pointer to the prepare function called on start of update procedure. */
+    dfu_bank_cleared_t  cleared;                                                    /**< Function pointer to the cleared function called after prepare function completes. */
+    dfu_bank_activate_t activate;                                                   /**< Function pointer to the activate function called on finalizing the update procedure. */
+} dfu_bank_func_t;
+
+#endif // DFU_BANK_INTERNAL_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_ble_svc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_ble_svc DFU BLE SVC 
+ * @{
+ *
+ * @brief DFU BLE SVC in bootloader. The DFU BLE SuperVisor Calls allow an application to execute
+ *        functions in the installed bootloader. 
+ *
+ * @details This module implements handling of SuperVisor Calls in the bootloader. 
+ *          SuperVisor Calls allow for an application to execute calls into the bootloader.
+ *          Currently, it is possible to exchange bonding information (like keys) from the 
+ *          application to a bootloader supporting DFU OTA using BLE, so the update process can be 
+ *          done through an already existing bond.
+ *
+ * @note The application must make sure that all SuperVisor Calls (SVC) are forwarded to the 
+ *       bootloader to ensure correct behavior. Forwarding of SVCs to the bootloader is 
+ *       done using the SoftDevice SVC @ref sd_softdevice_vector_table_base_set with the value 
+ *       present in @c NRF_UICR->BOOTLOADERADDR.
+ */
+ 
+#ifndef DFU_BLE_SVC_H__
+#define DFU_BLE_SVC_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+#include "ble_gap.h"
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "nrf_error_sdm.h"
+
+#define BOOTLOADER_SVC_BASE     0x0     /**< The number of the lowest SVC number reserved for the bootloader. */
+#define SYSTEM_SERVICE_ATT_SIZE 8       /**< Size of the system service attribute length including CRC-16 at the end. */  
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum BOOTLOADER_SVCS
+{
+    DFU_BLE_SVC_PEER_DATA_SET = BOOTLOADER_SVC_BASE,    /**< SVC number for the setting of peer data call. */
+    BOOTLOADER_SVC_LAST
+};
+
+/**@brief   DFU Peer data structure.
+ *
+ * @details This structure contains peer data needed for connection to a bonded device during DFU.
+ *          The peer data must be provided by the application to the bootloader during buttonless
+ *          update. See @ref dfu_ble_svc_peer_data_set. It contains bond information about the
+ *          desired DFU peer.
+ */
+typedef struct
+{
+    ble_gap_addr_t      addr;                                   /**< BLE GAP address of the device that initiated the DFU process. */
+    ble_gap_irk_t       irk;                                    /**< IRK of the device that initiated the DFU process if this device uses Private Resolvable Addresses. */
+    ble_gap_enc_key_t   enc_key;                                /**< Encryption key structure containing encrypted diversifier and LTK for re-establishing the bond. */
+    uint8_t             sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
+} dfu_ble_peer_data_t;
+
+/**@brief   SVC Function for setting peer data containing address, IRK, and LTK to establish bonded
+ *          connection in DFU mode.
+ *
+ * @param[in] p_peer_data  Pointer to the peer data containing keys for the connection.
+ *
+ * @retval NRF_ERROR_NULL If a NULL pointer was provided as argument.
+ * @retval NRF_SUCCESS    If the function completed successfully.
+ */
+SVCALL(DFU_BLE_SVC_PEER_DATA_SET, uint32_t, dfu_ble_svc_peer_data_set(dfu_ble_peer_data_t * p_peer_data));
+
+#endif // DFU_BLE_SVC_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_ble_svc_internal DFU BLE SVC internal
+ * @{
+ *
+ * @brief DFU BLE SVC internal functions in bootloader. The DFU BLE SuperVisor Calls allow an 
+ *        application to execute functions in the installed bootloader. This interface provides 
+ *        internal Bootloader DFU functions for retrieving data exchanged through SuperVisor Calls.
+ *
+ */
+
+#ifndef DFU_BLE_SVC_INTERNAL_H__
+#define DFU_BLE_SVC_INTERNAL_H__
+
+#include <stdint.h>
+#include "dfu_ble_svc.h"
+#include "ble_gap.h"
+
+/**@brief Internal bootloader/DFU function for retrieving peer data provided from application.
+ *
+ * @param[out] p_peer_data Peer data set by application to be used for DFU connection.
+ *
+ * @retval NRF_SUCCESS            If peer data is valid and can be used for connection.
+ * @retval NRF_ERROR_NULL         If p_peer_data is a NULL pointer.
+ * @retval NRF_ERROR_INVALID_DATA If peer data is not available or invalid.
+ */
+uint32_t dfu_ble_peer_data_get(dfu_ble_peer_data_t * p_peer_data);
+
+#endif // DFU_BLE_SVC_INTERNAL_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_init.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_init Init packet handling in DFU
+ * @{
+ *
+ * @brief Device Firmware Update module type and function declaration for init packet handling.
+ *
+ * @details This header contains basic functionality for performing safety checks on software 
+ *          updates for \nRFXX based devices. It provides a skeleton for pre-checking an init packet
+ *          to ensure the following image is compatible with this device. A safety check should 
+ *          always be performed to prevent accidental flashing of unsupported applications or a
+ *          wrong combination of application and SoftDevice.
+ *          The device information contains information such as:
+ *          - Device type (2 bytes), for example Heart Rate. The device type is a number defined by
+ *            the customer. It can be located in UICR or FICR.
+ *          - Device revision (2 bytes), for example major revision 1, minor revision 0. The device
+ *            revision is a number defined by the customer. It can be located in UICR or FICR.
+ *          - List of SoftDevices supported by this application, for example 
+ *              0x0049 = S110v6_0_0 
+ *              0xFFFE = S110 development (any SoftDevice accepted),
+ *          - CRC or hash of firmware image
+ *
+ * @note This module does not support security features such as image signing, but the corresponding
+ *       implementation allows for such extensions.
+ *       If the init packet is signed by a trusted source, it must be decrypted before it can be 
+ *       processed.
+ */
+
+#ifndef DFU_INIT_H__
+#define DFU_INIT_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+/**@brief Structure contained in an init packet. Contains information on device type, revision, and 
+ *        supported SoftDevices.
+ */
+typedef struct
+{
+    uint16_t device_type;                                                                   /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint16_t device_rev;                                                                    /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint32_t app_version;                                                                   /**< Application version for the image software. This field allows for additional checking, for example ensuring that a downgrade is not allowed. */
+    uint16_t softdevice_len;                                                                /**< Number of different SoftDevice revisions compatible with this application. The list of SoftDevice firmware IDs is defined in @ref softdevice. */
+    uint16_t softdevice[1];                                                                 /**< Variable length array of SoftDevices compatible with this application. The length of the array is specified in the length field. SoftDevice firmware id 0xFFFE indicates any SoftDevice. */
+} dfu_init_packet_t;
+
+/**@brief Structure holding basic device information settings.
+ */
+typedef struct
+{
+    uint16_t device_type;                                                                   /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint16_t device_rev;                                                                    /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+} dfu_device_info_t;
+
+/** The device info offset can be modified to place the device info settings at a different location.
+  * If the customer reserved UICR location is used for other application specific data, the offset
+  * must be updated to avoid collision with that data.
+  */
+/** [DFU UICR DEV offset] */
+#define UICR_CUSTOMER_DEVICE_INFO_OFFSET    0x0                                             /**< Device info offset inside the customer UICR reserved area. Customers may change this value to place the device information in a user-preferred location. */
+/** [DFU UICR DEV offset] */
+
+#define UICR_CUSTOMER_RESERVED_OFFSET       0x80                                            /**< Customer reserved area in the UICR. The area from UICR + 0x80 is reserved for customer usage. */
+#define DFU_DEVICE_INFO_BASE                (NRF_UICR_BASE + \
+                                             UICR_CUSTOMER_RESERVED_OFFSET + \
+                                             UICR_CUSTOMER_DEVICE_INFO_OFFSET)              /**< The device information base address inside of UICR. */
+#define DFU_DEVICE_INFO                     ((dfu_device_info_t *)DFU_DEVICE_INFO_BASE)     /**< The memory mapped structure for device information data. */
+
+#define DFU_DEVICE_TYPE_EMPTY               ((uint16_t)0xFFFF)                              /**< Mask indicating no device type is present in UICR. 0xFFFF is default flash pattern when not written with data. */
+#define DFU_DEVICE_REVISION_EMPTY           ((uint16_t)0xFFFF)                              /**< Mask indicating no device revision is present in UICR. 0xFFFF is default flash pattern when not written with data. */
+#define DFU_SOFTDEVICE_ANY                  ((uint16_t)0xFFFE)                              /**< Mask indicating that any SoftDevice is allowed for updating this application. Allows for easy development. Not to be used in production images. */
+
+
+/**@brief DFU prevalidate call for pre-checking the received init packet.
+ *
+ * @details  Pre-validation will safety check the firmware image to be transfered in second stage.
+ *           The function currently checks the device type, device revision, application firmware 
+ *           version, and supported SoftDevices. More checks should be added according to 
+ *           customer-specific requirements.
+ * 
+ * @param[in] p_init_data    Pointer to the init packet. If the init packet is encrypted or signed,
+ *                           it must first be decrypted before being checked.
+ * @param[in] init_data_len  Length of the init data.
+ *
+ * @retval NRF_SUCCESS              If the pre-validation succeeded, that means the image is 
+ *                                  supported by the device and it is considered to come from a 
+ *                                  trusted source (signing).
+ * @retval NRF_ERROR_INVALID_DATA   If the pre-validation failed, that means the image is not 
+ *                                  supported by the device or comes from an un-trusted source 
+ *                                  (signing).
+ * @retval NRF_ERROR_INVALID_LENGTH If the size of the init packet is not within the limits of 
+ *                                  the init packet handler.
+ */
+uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len);
+
+/**@brief DFU postvalidate call for post-checking the received image using the init packet.
+ *
+ * @details  Post-validation can verify the integrity check the firmware image received before 
+ *           activating the image.
+ *           Checks performed can be: 
+ *           - A simple CRC as shown in the corresponding implementation of this API in the file
+ *             dfu_init_template.c
+ *           - A hash for better verification of the image.
+ *           - A signature to ensure the image originates from a trusted source.
+ *           Checks are intended to be expanded for customer-specific requirements.
+ * 
+ * @param[in] p_image    Pointer to the received image. The init data provided in the call 
+ *                       \ref dfu_init_prevalidate will be used for validating the image.
+ * @param[in] image_len  Length of the image data.
+ *
+ * @retval NRF_SUCCESS             If the post-validation succeeded, that meant the integrity of the
+ *                                 image has been verified and the image originates from a trusted 
+ *                                 source (signing).
+ * @retval NRF_ERROR_INVALID_DATA  If the post-validation failed, that meant the post check of the 
+ *                                 image failed such as the CRC is not matching the image transfered
+ *                                 or the verification of the image fails (signing).
+ */
+uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len);
+
+#endif // DFU_INIT_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_init_template.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_init_template Template file with an DFU init packet handling example.
+ * @{
+ *
+ * @ingroup nrf_dfu
+ *
+ * @brief This file contains a template on how to implement DFU init packet handling.
+ *
+ * @details The template shows how device type and revision can be used for a safety check of the 
+ *          received image. It shows how validation can be performed in two stages:
+ *          - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches:
+ *                     - Device Type.
+ *                     - Device Revision.
+ *                     Installed SoftDevice.
+ *                     This template can be extended with additional checks according to needs.
+ *                     For example, such a check could be the origin of the image (trusted source) 
+ *                     based on a signature scheme.
+ *          - Stage 2: Post-check of the image after image transfer but before installing firmware.
+ *                     For example, such a check could be an integrity check in form of hashing or 
+ *                     verification of a signature.
+ *                     In this template, a simple CRC check is carried out.
+ *                     The CRC check can be replaced with other mechanisms, like signing.
+ *
+ * @note This module does not support security features such as image signing, but the 
+ *       implementation allows for such extension.
+ *       If the init packet is signed by a trusted source, it must be decrypted before it can be
+ *       processed.
+ */
+
+#include "dfu_init.h"
+#include <stdint.h>
+#include <string.h>
+#include <dfu_types.h>
+#include "nrf_error.h"
+#include "crc16.h"
+
+#define DFU_INIT_PACKET_EXT_LENGTH_MIN      2                       //< Minimum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a minimum value of two in order to hold a CRC. */
+#define DFU_INIT_PACKET_EXT_LENGTH_MAX      10                      //< Maximum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a maximum value of 10 in order to hold a CRC and any padded data on transport layer without overflow. */
+
+static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX];   //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */
+static uint8_t m_extended_packet_length;                            //< Length of the extended data received with init packet. */
+
+
+uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len)
+{
+    uint32_t i = 0;
+    
+    // In order to support signing or encryption then any init packet decryption function / library
+    // should be called from here or implemented at this location.
+
+    // Length check to ensure valid data are parsed.
+    if (init_data_len < sizeof(dfu_init_packet_t))
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    // Current template uses clear text data so they can be casted for pre-check.
+    dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data;
+
+    m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) -
+                               (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len];
+    if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN)
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    if (((uint32_t)p_init_data + init_data_len) < 
+        (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len])
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    memcpy(m_extended_packet,
+           &p_init_packet->softdevice[p_init_packet->softdevice_len],
+           m_extended_packet_length);
+
+/** [DFU init application version] */
+    // To support application versioning, this check should be updated.
+    // This template allows for any application to be installed. However, 
+    // customers can place a revision number at the bottom of the application 
+    // to be verified by the bootloader. This can be done at a location 
+    // relative to the application, for example the application start 
+    // address + 0x0100.
+/** [DFU init application version] */
+    
+    // First check to verify the image to be transfered matches the device type.
+    // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted.
+    if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) &&
+        (p_init_packet->device_type != DFU_DEVICE_INFO->device_type))
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+    
+    // Second check to verify the image to be transfered matches the device revision.
+    // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted.
+    if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) &&
+        (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev))
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    // Third check: Check the array of supported SoftDevices by this application.
+    //              If the installed SoftDevice does not match any SoftDevice in the list then an
+    //              error is returned.
+    while (i < p_init_packet->softdevice_len)
+    {
+        if (p_init_packet->softdevice[i]   == DFU_SOFTDEVICE_ANY ||
+            p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE))
+        {
+            return NRF_SUCCESS;
+        }
+    }
+    
+    // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA.
+    return NRF_ERROR_INVALID_DATA;
+}
+
+
+uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len)
+{
+#if NEED_CRC_CHECK /* disabled for now */
+    uint16_t image_crc;
+    uint16_t received_crc;
+    
+    // In order to support hashing (and signing) then the (decrypted) hash should be fetched and
+    // the corresponding hash should be calculated over the image at this location.
+    // If hashing (or signing) is added to the system then the CRC validation should be removed.
+
+    // calculate CRC from active block.
+    image_crc = crc16_compute(p_image, image_len, NULL);
+
+    // Decode the received CRC from extended data.    
+    received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]);
+
+    // Compare the received and calculated CRC.
+    if (image_crc != received_crc)
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+#endif /* NEED_CRC_CHECK */
+
+    return NRF_SUCCESS;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_transport.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_transport DFU transport API.
+ * @{     
+ *  
+ * @brief DFU transport module interface.
+ */
+ 
+#ifndef DFU_TRANSPORT_H__
+#define DFU_TRANSPORT_H__
+
+#include <stdint.h>
+
+/**@brief Function for starting the update of Device Firmware.
+ *
+ * @retval NRF_SUCCESS Operation success.   
+ */
+uint32_t dfu_transport_update_start(void);
+
+/**@brief Function for closing the transport layer.
+ *
+ * @retval NRF_SUCCESS Operation success.    
+ */
+uint32_t dfu_transport_close(void);
+
+#endif // DFU_TRANSPORT_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/dfu_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_dfu_types Types and definitions.
+ * @{
+ *
+ * @ingroup nrf_dfu
+ *
+ * @brief Device Firmware Update module type and definitions.
+ */
+
+#ifndef DFU_TYPES_H__
+#define DFU_TYPES_H__
+
+#include <stdint.h>
+#include "nrf_sdm.h"
+#include "nrf.h"
+#include "app_util.h"
+
+#define NRF_UICR_BOOT_START_ADDRESS     (NRF_UICR_BASE + 0x14)                                          /**< Register where the bootloader start address is stored in the UICR register. */
+
+#define CODE_REGION_1_START             SD_SIZE_GET(MBR_SIZE)                                           /**< This field should correspond to the size of Code Region 0, (which is identical to Start of Code Region 1), found in UICR.CLEN0 register. This value is used for compile safety, as the linker will fail if application expands into bootloader. Runtime, the bootloader will use the value found in UICR.CLEN0. */
+#define SOFTDEVICE_REGION_START         MBR_SIZE                                                        /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
+
+#ifdef NRF51
+#ifdef SIGNING
+#define BOOTLOADER_REGION_START         0x00039C00                                                    /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
+#define BOOTLOADER_SETTINGS_ADDRESS     0x0003D800                                                    /**< The field specifies the page location of the bootloader settings address. */
+#else
+#define BOOTLOADER_REGION_START         0x0003C000                                                      /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
+#define BOOTLOADER_SETTINGS_ADDRESS     0x0003FC00                                                      /**< The field specifies the page location of the bootloader settings address. */
+#endif
+
+#define CODE_PAGE_SIZE                  0x0400                                                          /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
+#elif NRF52
+#define BOOTLOADER_REGION_START         0x0007B000                                                      /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
+#define BOOTLOADER_SETTINGS_ADDRESS     0x0007F000                                                      /**< The field specifies the page location of the bootloader settings address. */
+#define CODE_PAGE_SIZE                  0x1000                                                          /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
+#else
+#error No target defined
+#endif
+
+#define DFU_REGION_TOTAL_SIZE           (BOOTLOADER_REGION_START - CODE_REGION_1_START)                 /**< Total size of the region between SD and Bootloader. */
+
+#define DFU_APP_DATA_RESERVED           0x0000                                                          /**< Size of Application Data that must be preserved between application updates. This value must be a multiple of page size. Page size is 0x400 (1024d) bytes, thus this value must be 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, etc. */
+#define DFU_BANK_PADDING                (DFU_APP_DATA_RESERVED % (2 * CODE_PAGE_SIZE))                  /**< Padding to ensure that image size banked is always page sized. */
+#define DFU_IMAGE_MAX_SIZE_FULL         (DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED)                 /**< Maximum size of an application, excluding save data from the application. */
+#define DFU_IMAGE_MAX_SIZE_BANKED       ((DFU_REGION_TOTAL_SIZE - \
+                                          DFU_APP_DATA_RESERVED - \
+                                          DFU_BANK_PADDING) / 2)                                        /**< Maximum size of an application, excluding save data from the application. */
+
+#define DFU_BL_IMAGE_MAX_SIZE           (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_REGION_START)         /**< Maximum size of a bootloader, excluding save data from the current bootloader. */
+
+#define DFU_BANK_0_REGION_START         CODE_REGION_1_START                                             /**< Bank 0 region start. */
+#define DFU_BANK_1_REGION_START         (DFU_BANK_0_REGION_START + DFU_IMAGE_MAX_SIZE_BANKED)           /**< Bank 1 region start. */
+
+#define EMPTY_FLASH_MASK                0xFFFFFFFF                                                      /**< Bit mask that defines an empty address in flash. */
+
+#define INVALID_PACKET                  0x00                                                            /**< Invalid packet identifies. */
+#define INIT_PACKET                     0x01                                                            /**< Packet identifies for initialization packet. */
+#define STOP_INIT_PACKET                0x02                                                            /**< Packet identifies for stop initialization packet. Used when complete init packet has been received so that the init packet can be used for pre validaiton. */
+#define START_PACKET                    0x03                                                            /**< Packet identifies for the Data Start Packet. */
+#define DATA_PACKET                     0x04                                                            /**< Packet identifies for a Data Packet. */
+#define STOP_DATA_PACKET                0x05                                                            /**< Packet identifies for the Data Stop Packet. */
+
+#define DFU_UPDATE_SD                   0x01                                                            /**< Bit field indicating update of SoftDevice is ongoing. */
+#define DFU_UPDATE_BL                   0x02                                                            /**< Bit field indicating update of bootloader is ongoing. */
+#define DFU_UPDATE_APP                  0x04                                                            /**< Bit field indicating update of application is ongoing. */
+
+#define DFU_INIT_RX                     0x00                                                            /**< Op Code identifies for receiving init packet. */
+#define DFU_INIT_COMPLETE               0x01                                                            /**< Op Code identifies for transmission complete of init packet. */
+
+// Safe guard to ensure during compile time that the DFU_APP_DATA_RESERVED is a multiple of page size.
+STATIC_ASSERT((((DFU_APP_DATA_RESERVED) & (CODE_PAGE_SIZE - 1)) == 0x00));
+
+/**@brief Structure holding a start packet containing update mode and image sizes.
+ */
+typedef struct
+{
+    uint8_t  dfu_update_mode;                                                                           /**< Packet type, used to identify the content of the received packet referenced by data packet. */
+    uint32_t sd_image_size;                                                                             /**< Size of the SoftDevice image to be transferred. Zero if no SoftDevice image will be transfered. */
+    uint32_t bl_image_size;                                                                             /**< Size of the Bootloader image to be transferred. Zero if no Bootloader image will be transfered. */
+    uint32_t app_image_size;                                                                            /**< Size of the application image to be transmitted. Zero if no Bootloader image will be transfered. */
+} dfu_start_packet_t;
+
+/**@brief Structure holding a bootloader init/data packet received.
+ */
+typedef struct
+{
+    uint32_t   packet_length;                                                                           /**< Packet length of the data packet. Each data is word size, meaning length of 4 is 4 words, not bytes. */
+    uint32_t * p_data_packet;                                                                           /**< Data Packet received. Each data is a word size entry. */
+} dfu_data_packet_t;
+
+/**@brief Structure for holding dfu update packet. Packet type indicate the type of packet.
+ */
+typedef struct
+{
+    uint32_t   packet_type;                                                                             /**< Packet type, used to identify the content of the received packet referenced by data packet. */
+    union
+    {
+        dfu_data_packet_t    data_packet;                                                               /**< Used when packet type is INIT_PACKET or DATA_PACKET. Packet contains data received for init or data. */
+        dfu_start_packet_t * start_packet;                                                              /**< Used when packet type is START_DATA_PACKET. Will contain information on software to be updtaed, i.e. SoftDevice, Bootloader and/or Application along with image sizes. */
+    } params;
+} dfu_update_packet_t;
+
+/**@brief DFU status error codes.
+*/
+typedef enum
+{
+    DFU_UPDATE_APP_COMPLETE,                                                                            /**< Status update of application complete.*/
+    DFU_UPDATE_SD_COMPLETE,                                                                             /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */
+    DFU_UPDATE_SD_SWAPPED,                                                                              /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */
+    DFU_UPDATE_BOOT_COMPLETE,                                                                           /**< Status update complete.*/
+    DFU_BANK_0_ERASED,                                                                                  /**< Status bank 0 erased.*/
+    DFU_TIMEOUT,                                                                                        /**< Status timeout.*/
+    DFU_RESET                                                                                           /**< Status Reset to indicate current update procedure has been aborted and system should reset. */
+} dfu_update_status_code_t;
+
+/**@brief Structure holding DFU complete event.
+*/
+typedef struct
+{
+    dfu_update_status_code_t status_code;                                                               /**< Device Firmware Update status. */
+    uint16_t                 app_crc;                                                                   /**< CRC of the recieved application. */
+    uint32_t                 sd_size;                                                                   /**< Size of the recieved SoftDevice. */
+    uint32_t                 bl_size;                                                                   /**< Size of the recieved BootLoader. */
+    uint32_t                 app_size;                                                                  /**< Size of the recieved Application. */
+    uint32_t                 sd_image_start;                                                            /**< Location in flash where the received SoftDevice image is stored. */
+} dfu_update_status_t;
+
+/**@brief Update complete handler type. */
+typedef void (*dfu_complete_handler_t)(dfu_update_status_t dfu_update_status);
+
+#endif // DFU_TYPES_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 memory_pool_internal Memory Pool Internal
+ * @{
+ * @ingroup memory_pool
+ *
+ * @brief Memory pool internal definitions
+ */
+ 
+#ifndef MEM_POOL_INTERNAL_H__
+#define MEM_POOL_INTERNAL_H__
+
+#define TX_BUF_SIZE       4u    /**< TX buffer size in bytes. */
+#define RX_BUF_SIZE       32u   /**< RX buffer size in bytes. */
+
+#define RX_BUF_QUEUE_SIZE 8u     /**< RX buffer element size. */
+ 
+#endif // MEM_POOL_INTERNAL_H__
+ 
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/crc16/crc16.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "crc16.h"
+#include <stdio.h>
+
+uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc)
+{
+    uint32_t i;
+    uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc;
+
+    for (i = 0; i < size; i++)
+    {
+        crc  = (unsigned char)(crc >> 8) | (crc << 8);
+        crc ^= p_data[i];
+        crc ^= (unsigned char)(crc & 0xff) >> 4;
+        crc ^= (crc << 8) << 4;
+        crc ^= ((crc & 0xff) << 4) << 1;
+    }
+
+    return crc;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/crc16/crc16.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 crc_compute CRC compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief    This module implements the CRC-16 calculation in the blocks.
+ */
+ 
+#ifndef CRC16_H__
+#define CRC16_H__
+
+#include <stdint.h>
+
+/**@brief Function for calculating CRC-16 in blocks.
+ *
+ * Feed each consecutive data block into this function, along with the current value of p_crc as 
+ * returned by the previous call of this function. The first call of this function should pass NULL 
+ * as the initial value of the crc in p_crc.
+ *
+ * @param[in] p_data The input data block for computation.
+ * @param[in] size   The size of the input data block in bytes.
+ * @param[in] p_crc  The previous calculated CRC-16 value or NULL if first call.  
+ *
+ * @return The updated CRC-16 value, based on the input supplied.
+ */
+uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc);
+
+#endif // CRC16_H__
+ 
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/experimental_section_vars/section_vars.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 SECTION_VARS_H__
+#define SECTION_VARS_H__
+
+#include "app_util.h"
+
+#if defined __ICC_ARM__
+
+// turn on language extensions for iar
+#pragma language=extended
+
+#endif
+
+/**
+ * @defgroup section_vars Section variables
+ * @ingroup app_common
+ * @{
+ * @brief Section variables.
+ */
+
+/**@brief Macro to delay macro expression of pragma
+ *
+ */
+#define NRF_PRAGMA(x) _Pragma(#x)
+
+
+/**@brief Macro to register section by name in code
+ *
+ * @param[in]   section_name    Name of the section to register
+ **/
+#if defined __CC_ARM
+
+// Not required by this compiler
+#define NRF_SECTION_VARS_REGISTER_SECTION(section_name)
+
+#elif defined __GNUC__
+
+// Not required by this compiler
+#define NRF_SECTION_VARS_REGISTER_SECTION(section_name)
+
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_REGISTER_SECTION(section_name) NRF_PRAGMA(section = ## #section_name )
+
+#else
+
+#error TODO
+
+#endif
+
+/*lint -save -e27 */
+
+/**@brief Macro for accessing start of a named data section by symbol 
+ *
+ * @details     The symbol that this macro resolves to is used to access the section 
+ *              by start address.
+ *
+ * @param[in]   section_name    Name of the section
+ */
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_START_SYMBOL(section_name)         section_name ## $$Base
+
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_START_SYMBOL(section_name)         __start_ ## section_name
+
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_START_SYMBOL(section_name)         __section_begin(#section_name)
+
+#else
+
+#error TODO
+
+#endif
+
+
+/**@brief Macro for accessing end of a named data section by symbol
+ *
+ * @details     The symbol that this macro resolves to is used to access the section
+ *              by end address.
+ *
+ * @param[in]   section_name    Name of the section    
+ */
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_END_SYMBOL(section_name)           section_name ## $$Limit
+
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_END_SYMBOL(section_name)           __stop_ ## section_name
+
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_END_SYMBOL(section_name)           __section_end(#section_name)
+
+#endif
+
+/*lint -restore */
+
+
+/**@brief Macro for accessing Length of a named section
+ *
+ * @details     This macro is used to get the size of a named section.
+ *
+ * @param[in]   section_name    Name of the section
+ */
+
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_LENGTH(section_name) \
+    ((uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name))
+
+#elif defined __GNUC__
+
+ #define NRF_SECTION_VARS_LENGTH(section_name) \
+    ((uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name))
+
+#elif defined __ICCARM__
+
+ #define NRF_SECTION_VARS_LENGTH(section_name) \
+    ((uint32_t)NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)NRF_SECTION_VARS_START_SYMBOL(section_name))
+
+#else
+
+#error TODO
+
+#endif
+      
+
+/**@brief Macro for accessing the start address of a named section
+ *
+ * param[in]    section_name    Name of the section to get the start address from
+ */
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_START_ADDR(section_name)       (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name)
+      
+#elif defined __GNUC__
+      
+#define NRF_SECTION_VARS_START_ADDR(section_name)       (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name)
+      
+#elif defined __ICCARM__
+      
+#define NRF_SECTION_VARS_START_ADDR(section_name)       (uint32_t)iar_ ## section_name ## _start
+
+#else
+      
+#error TODO
+      
+#endif
+
+      
+/*@brief Macro for accessing the end address of a named section
+ *
+ * @param[in]   section_name    Name of the section to get end address from
+ */
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_END_ADDR(section_name)         (uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name)
+      
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_END_ADDR(section_name)         (uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name)
+      
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_END_ADDR(section_name)         (uint32_t)iar_ ## section_name ## _end
+
+#else
+      
+#error TODO
+      
+#endif
+
+
+/**@brief Macro for declaring symbols for named sections
+ *
+ * @note    These external declarations of section specific symbols are required for the linker in GCC and Keil (not IAR)
+ *
+ * @param[in]   type_name       Name of the type stored in the section
+ * @param[in]   section_name    Name of the section
+ */
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name)      \
+    extern type_name* NRF_SECTION_VARS_START_SYMBOL(section_name);      \
+    extern void* NRF_SECTION_VARS_END_SYMBOL(section_name)
+
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name)      \
+    extern type_name* NRF_SECTION_VARS_START_SYMBOL(section_name);      \
+    extern void* NRF_SECTION_VARS_END_SYMBOL(section_name)
+
+#elif defined __ICCARM__
+
+// No symbol registration required for IAR      
+#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name)                              \
+    extern void*   iar_ ## section_name ## _start   = __section_begin(#section_name);            \
+    extern void*   iar_ ## section_name ## _end     = __section_end(#section_name)
+      
+#else
+      
+#error TODO
+
+#endif
+
+
+/**@brief Macro to add symbols to a named section
+ *
+ * @details     The symbols are placed in a named section. All calls to this macro
+ *              will result in symbols being placed in a contiguous manner in the named section. 
+ *              This macro ensures that the symbol is not removed because of optimization level.
+ *
+ * @warning     There is no guarantee for ordering of placement. If ordering is required
+ *
+ * @warning     The symbols added in the named section must be word aligned to
+ *              ensure that compilers do not pad the section during symbol placement.
+ *
+ * @param[in]   section_name    Name of the section
+ * @param[in]   type_def        Datatype of the symbol to place in the given section
+ */
+#if defined __CC_ARM
+    
+#define NRF_SECTION_VARS_ADD(section_name, type_def) \
+    static type_def __attribute__((section( #section_name ))) __attribute__((used))
+
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_ADD(section_name, type_def) \
+    static type_def __attribute__ ((section( #section_name ))) __attribute__ ((used))
+
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_ADD(section_name, type_def) \
+    __root type_def @ #section_name
+
+#else
+      
+#error    TODO
+      
+#endif    
+
+      
+/**@brief Macro to get symbol from named section
+ *
+ * @warning     The stored symbol can only be resolved using this macro if the 
+ *              type of the data is word aligned. The operation of acquiring 
+ *              the stored symbol relies on sizeof of the stored type, no 
+ *              padding can exist in the named section in between individual 
+ *              stored items or this macro will fail.
+ *
+ * @param[in]   i               Index of item in section
+ * @param[in]   type_name       Type name of item in section
+ * @param[in]   section_name    Name of the section
+ */
+      
+#if defined __CC_ARM
+
+#define NRF_SECTION_VARS_GET(i, type_name, section_name) \
+    (type_name*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(type_name))
+      
+#elif defined __GNUC__
+
+#define NRF_SECTION_VARS_GET(i, type_name, section_name) \
+    (type_name*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(type_name))
+      
+#elif defined __ICCARM__
+
+#define NRF_SECTION_VARS_GET(i, type_name, section_name) \
+      (type_name*)iar_ ## section_name ## _start + (i * sizeof(type_name))
+
+#else
+
+#error TODO
+
+#endif
+
+
+/**@brief Macro to get number of items in named section
+ *
+ * @param[in]   type_name       Type name of item in section
+ * @param[in]   section_name    Name of the section
+ */
+#define NRF_SECTION_VARS_COUNT(type_name, section_name) \
+    NRF_SECTION_VARS_LENGTH(section_name) / sizeof(type_name)
+
+/** @} */
+
+#endif // SECTION_VARS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,2090 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "fds.h"
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "fds_config.h"
+#include "fds_types_internal.h"
+#include "fstorage.h"
+#include "nrf_error.h"
+#include "app_util.h"
+
+
+/** Our fstorage configuration.
+ *  The other fields will be assigned automatically during compilation. */
+FS_SECTION_VARS_ADD(fs_config_t fs_config) = { .cb = fs_callback, .num_pages = FDS_MAX_PAGES };
+
+static uint32_t const fds_page_tag_swap[]   = {FDS_PAGE_TAG_WORD_0_SWAP, FDS_PAGE_TAG_WORD_1,
+                                               FDS_PAGE_TAG_WORD_2,      FDS_PAGE_TAG_WORD_3};
+
+static uint32_t const fds_page_tag_valid[]  = {FDS_PAGE_TAG_WORD_0_VALID, FDS_PAGE_TAG_WORD_1,
+                                               FDS_PAGE_TAG_WORD_2,       FDS_PAGE_TAG_WORD_3};
+
+static uint32_t const fds_page_tag_gc       = FDS_PAGE_TAG_WORD_3_GC;
+
+static fds_tl_t const m_fds_tl_invalid      = { .type = FDS_TYPE_ID_INVALID,
+                                                .length_words = 0xFFFF };
+
+/**@brief Internal status flags. */
+static uint8_t           volatile m_flags;       
+
+static uint8_t                    m_users;
+static fds_cb_t                   m_cb_table[FDS_MAX_USERS];
+
+/**@brief The last record ID. Setup page by page_scan() during pages_init(). */
+static fds_record_id_t            m_last_rec_id;
+
+/**@brief The internal queues. */
+static fds_cmd_queue_t            m_cmd_queue;   
+static fds_chunk_queue_t          m_chunk_queue;
+
+/**@brief Holds the state of pages. Setup by fds_init(). */
+static fds_page_t                 m_pages[FDS_MAX_PAGES];
+static bool                       m_swap_page_avail = false;
+
+static fds_gc_data_t              m_gc;
+static uint16_t                   m_gc_runs;
+
+static uint8_t          volatile  m_counter;
+
+
+static void app_notify(ret_code_t       result,
+                       fds_cmd_id_t     cmd,
+                       fds_record_id_t  record_id,
+                       fds_record_key_t record_key)
+{
+    for (uint8_t user = 0; user < FDS_MAX_USERS; user++)
+    {
+        if (m_cb_table[user] != NULL)
+        {
+            m_cb_table[user](result, cmd, record_id, record_key);
+        }
+    }
+}
+
+
+static void atomic_counter_inc()
+{
+    CRITICAL_SECTION_ENTER();
+    m_counter++;
+    CRITICAL_SECTION_EXIT();
+}
+
+
+static void atomic_counter_dec()
+{
+    CRITICAL_SECTION_ENTER();
+    m_counter--;
+    CRITICAL_SECTION_EXIT();
+}
+
+
+static bool atomic_counter_is_zero()
+{
+    bool ret;
+    CRITICAL_SECTION_ENTER();
+    ret = (m_counter == 0);
+    CRITICAL_SECTION_EXIT();
+    return ret;
+}
+
+
+static void flag_set(fds_flags_t flag)
+{
+    CRITICAL_SECTION_ENTER();
+    m_flags |= flag;
+    CRITICAL_SECTION_EXIT();
+}
+
+
+static void flag_clear(fds_flags_t flag)
+{
+    CRITICAL_SECTION_ENTER();
+    m_flags &= ~(flag);
+    CRITICAL_SECTION_EXIT();
+}
+
+
+static bool flag_is_set(fds_flags_t flag)
+{
+    bool ret;
+    CRITICAL_SECTION_ENTER();
+    ret = (m_flags & flag);
+    CRITICAL_SECTION_EXIT();
+    return ret;
+}
+
+
+/**@brief Function to check if a header has valid information. */
+static __INLINE bool header_is_valid(fds_header_t const * const p_header)
+{
+    return ((p_header->tl.type     != FDS_TYPE_ID_INVALID) &&
+            (p_header->ic.instance != FDS_INSTANCE_ID_INVALID));
+}
+
+
+static bool address_within_page_bounds(uint32_t const * const p_addr)
+{
+    return (p_addr >= fs_config.p_start_addr) &&
+           (p_addr <= fs_config.p_end_addr) &&
+           (is_word_aligned(p_addr));
+}
+
+
+/**@brief Internal function to identify the page type. */
+static fds_page_type_t page_identify(uint16_t page_number)
+{
+    uint32_t const * const p_page_addr = m_pages[page_number].start_addr;
+
+    uint32_t const word0 = *(p_page_addr);
+    uint32_t const word1 = *(p_page_addr + 1);
+    uint32_t const word2 = *(p_page_addr + 2);
+    uint32_t const word3 = *(p_page_addr + 3);
+
+    if (word1 != FDS_PAGE_TAG_WORD_1)
+    {
+        return FDS_PAGE_UNDEFINED;
+    }
+
+    if (word2 != FDS_PAGE_TAG_WORD_2)
+    {
+        return FDS_PAGE_UNDEFINED;
+    }
+
+    if (word3 == FDS_PAGE_TAG_WORD_3)
+    {
+        if (word0 == FDS_PAGE_TAG_WORD_0_SWAP)
+        {
+            return FDS_PAGE_SWAP;
+        }
+
+        if (word0 == FDS_PAGE_TAG_WORD_0_VALID)
+        {
+            return FDS_PAGE_VALID;
+        }
+    }
+    else if (word3 == FDS_PAGE_TAG_WORD_3_GC)
+    {
+        if (word0 == FDS_PAGE_TAG_WORD_0_SWAP || word0 == FDS_PAGE_TAG_WORD_0_VALID)
+        {
+            return FDS_PAGE_GC;
+        }
+    }
+
+    return FDS_PAGE_UNDEFINED;
+}
+
+
+static uint16_t page_by_addr(uint32_t const * const p_addr)
+{
+    if (p_addr == NULL)
+    {
+        return 0;
+    }
+
+    // Compute the BYTES offset from the beginning of the first page.
+    uint32_t const byte_offset = (uint32_t)p_addr - (uint32_t)m_pages[0].start_addr;
+
+// See nrf.h.
+#if defined (NRF51)
+    return byte_offset >> 10; // Divide by page size (1024).
+#elif defined (NRF52)
+    return byte_offset >> 12; // Divide by page size (4096).
+#else
+    #error "Device family must be defined. See nrf.h."
+#endif
+}
+
+
+// NOTE: depends on m_pages.write_offset to function.
+static bool page_has_space(uint16_t page, fds_length_t length_words)
+{
+    if (page >= FDS_MAX_PAGES)
+    {
+        return false;
+    }
+
+    CRITICAL_SECTION_ENTER();
+    length_words +=  m_pages[page].write_offset;
+    length_words +=  m_pages[page].words_reserved;
+    CRITICAL_SECTION_EXIT();
+
+    return (length_words < FS_PAGE_SIZE_WORDS);
+}
+
+
+/**@brief This function scans a page to determine how many words have
+ *        been written to it. This information is used to set the page
+ *        write offset during initialization (mount). Additionally, this
+ *        function will update the last known record ID as it proceeds.
+ */
+static void page_scan(uint16_t page, uint16_t volatile * words_written)
+{
+    uint32_t const * p_addr = (m_pages[page].start_addr + FDS_PAGE_TAG_SIZE);
+
+    *words_written = FDS_PAGE_TAG_SIZE;
+
+    // A corrupt TL might cause problems.
+    while ((p_addr < m_pages[page].start_addr + FS_PAGE_SIZE_WORDS) &&
+           (*p_addr != FDS_ERASED_WORD))
+    {
+        fds_header_t const * const p_header = (fds_header_t*)p_addr;
+
+        /** Note: DO NOT check for the validity of the header using
+         *  header_is_valid() here. If an header has an invalid type (0x0000)
+         *  or a missing instance (0xFFFF) then we WANT to skip it.
+         */
+
+         // Update the last known record id.
+         if (p_header->id > m_last_rec_id)
+         {
+            m_last_rec_id = p_header->id;
+         }
+
+         // Jump to the next record.
+         p_addr         += (FDS_HEADER_SIZE + p_header->tl.length_words);
+         *words_written += (FDS_HEADER_SIZE + p_header->tl.length_words);
+    }
+}
+
+
+static bool page_is_empty(uint16_t page)
+{
+    uint32_t const * const p_addr = m_pages[page].start_addr;
+
+    for (uint16_t i = 0; i < FS_PAGE_SIZE_WORDS; i++)
+    {
+        if (*(p_addr + i) != FDS_ERASED_WORD)
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+static ret_code_t page_id_from_virtual_id(uint16_t vpage_id, uint16_t * p_page_id)
+{
+    for (uint16_t i = 0; i < FDS_MAX_PAGES; i++)
+    {
+        if (m_pages[i].vpage_id == vpage_id)
+        {
+            *p_page_id = i;
+            return NRF_SUCCESS;
+        }
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static ret_code_t page_from_virtual_id(uint16_t vpage_id, fds_page_t ** p_page)
+{
+    for (uint16_t i = 0; i < FDS_MAX_PAGES; i++)
+    {
+        if (m_pages[i].vpage_id == vpage_id)
+        {
+            *p_page = &m_pages[i];
+            return NRF_SUCCESS;
+        }
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static uint32_t record_id_new()
+{
+    return ++m_last_rec_id;
+}
+
+
+/**@brief Tags a page as swap, i.e., reserved for GC. */
+static ret_code_t page_tag_write_swap(uint16_t page)
+{
+    return fs_store(&fs_config,
+                    m_pages[page].start_addr,
+                    (uint32_t const *)&fds_page_tag_swap,
+                    FDS_PAGE_TAG_SIZE);
+}
+
+
+/**@brief Tags a page as valid, i.e, ready for storage. */
+static ret_code_t page_tag_write_valid(uint16_t page)
+{
+    return fs_store(&fs_config,
+                    m_pages[page].start_addr,
+                    (uint32_t const *)&fds_page_tag_valid,
+                    FDS_PAGE_TAG_SIZE);
+}
+
+
+/**@brief Tags a valid page as being garbage collected. */
+static ret_code_t page_tag_write_gc(uint16_t page)
+{
+    return fs_store(&fs_config,
+                    m_pages[page].start_addr + 3,
+                    (uint32_t const *)&fds_page_tag_gc,
+                    1 /*Words*/);
+}
+
+
+/**@brief Given a page and a record, finds the next valid record. */
+static ret_code_t scan_next_valid(uint16_t page, uint32_t const ** p_record)
+{
+    uint32_t const * p_next_rec = (*p_record);
+
+    if (p_next_rec == NULL)
+    {
+        // This if the first invocation on this page, start from the beginning.
+        p_next_rec = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE;
+    }
+    else
+    {
+        // Jump to the next record.
+        p_next_rec += (FDS_HEADER_SIZE + ((fds_header_t*)(*p_record))->tl.length_words);
+    }
+
+    // Scan until we find a valid record or until the end of the page.
+
+    /** README: We might seek until the write_offset is reached, but it might not
+     *  known at this point. */
+    while ((p_next_rec < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) &&
+           (*p_next_rec != FDS_ERASED_WORD)) // Did we jump to an erased word?
+    {
+        fds_header_t const * const p_header = (fds_header_t*)p_next_rec;
+
+        if (header_is_valid(p_header))
+        {
+            // Bingo!
+            *p_record = p_next_rec;
+            return NRF_SUCCESS;
+        }
+        else
+        {
+            // The item is not valid, jump to the next.
+            p_next_rec += (FDS_HEADER_SIZE + (p_header->tl.length_words));
+        }
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static ret_code_t seek_record(fds_record_desc_t * const p_desc)
+{
+    uint32_t const * p_record;
+    uint16_t         page;
+    bool             seek_all_pages = false;
+
+    if ((p_desc->ptr_magic == FDS_MAGIC_HWORD) &&
+        (p_desc->gc_magic  == m_gc_runs))
+    {
+        // No need to seek the file.
+        return NRF_SUCCESS;
+    }
+
+    /** The pointer in the descriptor is not initialized, or GC
+     *  has been run since the last time it was retrieved.
+     *  We must seek the record again. */
+
+    // Obtain the physical page ID.
+    if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS)
+    {
+        page = 0;
+        seek_all_pages = true;
+    }
+
+    do {
+        // Let's find the address from where we should start seeking the record.
+        p_record = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE;
+
+        /** Seek for a record with matching ID.
+         *  We might get away with seeking to the page write offset, if it is known. */
+
+        while ((p_record < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) &&
+               (*p_record != FDS_ERASED_WORD))
+        {
+            fds_header_t const * const p_header = (fds_header_t*)p_record;
+
+            if ((p_header->id != p_desc->record_id) ||
+                (!header_is_valid(p_header)))
+            {
+                // ID doesnt't match or the record has been cleared. Jump to the next record.
+                p_record += FDS_HEADER_SIZE + p_header->tl.length_words;
+            }
+            else
+            {
+                // Update the pointer in the descriptor.
+                p_desc->p_rec     = p_record;
+                p_desc->ptr_magic = FDS_MAGIC_HWORD;
+                p_desc->gc_magic  = m_gc_runs;
+
+                return NRF_SUCCESS;
+            }
+        }
+    } while (seek_all_pages ? page++ < FDS_MAX_PAGES : 0);
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static ret_code_t find_record(fds_type_id_t     const * const p_type,
+                              fds_instance_id_t const * const p_inst,
+                              fds_record_desc_t       * const p_desc,
+                              fds_find_token_t        * const p_token)
+{
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    // Here we distinguish between the first invocation and the and the others.
+    if ((p_token->magic != FDS_MAGIC_WORD) ||
+        !address_within_page_bounds(p_token->p_addr)) // Is the address is really okay?
+    {
+        // Initialize the token.
+        p_token->magic    = FDS_MAGIC_WORD;
+        p_token->vpage_id = 0;
+        p_token->p_addr   = NULL;
+    }
+    else
+    {
+        // Look past the last record address.
+         p_token->p_addr += (FDS_HEADER_SIZE + ((fds_header_t*)p_token->p_addr)->tl.length_words);
+    }
+
+    // Begin (or resume) searching for a record.
+    for (; p_token->vpage_id < FDS_MAX_PAGES; p_token->vpage_id++)
+    {
+        uint16_t page = 0;
+
+        // Obtain the physical page ID.
+        page_id_from_virtual_id(p_token->vpage_id, &page);
+
+        if (m_pages[page].page_type != FDS_PAGE_VALID)
+        {
+            // Skip this page.
+            continue;
+        }
+
+        if (p_token->p_addr == NULL)
+        {
+            // If it's the first time the function is run, initialize the pointer.
+            p_token->p_addr = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE;
+        }
+
+        // Seek a valid record on this page, starting from the address stored in the token.
+        while ((p_token->p_addr < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) &&
+               (*p_token->p_addr != FDS_ERASED_WORD)) // Did we jump to an erased word?
+        {
+            fds_header_t const * const p_header = (fds_header_t*)p_token->p_addr;
+
+            if (header_is_valid(p_header))
+            {
+                // A valid record was found, check its header for a match.
+                bool item_match = false;
+
+                if (p_type != NULL)
+                {
+                    if (p_header->tl.type == *p_type)
+                    {
+                        item_match = true;
+                    }
+                }
+
+                if (p_inst != NULL)
+                {
+                    if (p_header->ic.instance == *p_inst)
+                    {
+                        item_match = (p_type == NULL) ? true : item_match && true;
+                    }
+                    else
+                    {
+                        item_match = false;
+                    }
+                }
+
+                if (item_match)
+                {
+                    // We found the record! Update the descriptor.
+                    p_desc->vpage_id  = m_pages[page].vpage_id;
+                    p_desc->record_id = p_header->id;
+
+                    p_desc->p_rec     = p_token->p_addr;
+                    p_desc->ptr_magic = FDS_MAGIC_HWORD;
+                    p_desc->gc_magic  = m_gc_runs;
+
+                    return NRF_SUCCESS;
+                }
+            }
+            // Jump to the next record.
+            p_token->p_addr += (FDS_HEADER_SIZE + (p_header->tl.length_words));
+        }
+
+        /** We have seeked an entire page. Set the address in the token to NULL
+         *  so that it will be set again on the next iteration. */
+        p_token->p_addr = NULL;
+    }
+
+    /** If we couldn't find the record, zero the token structure
+     *  so that it can be reused. */
+    p_token->magic = 0x00;
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static void gc_init()
+{
+    // Set which pages to GC.
+    for (uint16_t i = 0; i < FDS_MAX_PAGES; i++)
+    {
+        m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_VALID);
+    }
+}
+
+
+static void gc_reset()
+{
+    m_gc.state       = BEGIN;
+    m_gc.cur_page    = 0;
+    m_gc.p_scan_addr = NULL;
+}
+
+
+static void gc_set_state(fds_gc_state_t new_state)
+{
+    m_gc.state = new_state;
+}
+
+
+static ret_code_t gc_get_next_page(uint16_t * const next_page)
+{
+    for (uint16_t i = 0; i < FDS_MAX_PAGES; i++)
+    {        
+        if (m_gc.do_gc_page[i])
+        {
+            uint16_t records_open;
+
+            CRITICAL_SECTION_ENTER();
+            records_open = m_pages[i].records_open;
+            CRITICAL_SECTION_EXIT();
+
+            // Do not attempt to GC this page anymore.
+            m_gc.do_gc_page[i] = false;
+
+            // Only GC pages with no open records.
+            if (records_open == 0)
+            {
+                *next_page = i;
+                return NRF_SUCCESS;
+            }   
+        }
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+static ret_code_t gc_page()
+{
+    ret_code_t ret;
+
+    ret = gc_get_next_page(&m_gc.cur_page);
+
+    // No pages left to GC. GC has terminated. Reset GC data.
+    if (ret != NRF_SUCCESS)
+    {    
+        gc_reset();
+
+        return COMMAND_COMPLETED;
+    }
+
+    // Prepare to GC the page.
+    gc_set_state(GC_PAGE);
+
+    // Flag the page as being garbage collected.
+    ret = page_tag_write_gc(m_gc.cur_page);
+
+    if (ret != NRF_SUCCESS)
+    {
+        return ret;
+    }
+
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t gc_copy_record()
+{
+    ret_code_t fs_ret;
+
+    // We have found a record to copy.
+    fds_record_t const * const p_record = (fds_record_t*)m_gc.p_scan_addr;
+
+    gc_set_state(COPY_RECORD);
+
+    // Copy the item to swap.
+    fs_ret = fs_store(&fs_config,
+                      m_pages[m_gc.swap_page].start_addr + m_pages[m_gc.swap_page].write_offset,
+                      (uint32_t*)p_record,
+                      FDS_HEADER_SIZE + p_record->header.tl.length_words);
+
+    if (fs_ret != NRF_SUCCESS)
+    {
+        // Oops :(
+        // This is an error. Can we recover?
+    }
+
+    // Remember to update the swap page write offset.
+    m_pages[m_gc.swap_page].write_offset += (FDS_HEADER_SIZE + p_record->header.tl.length_words);
+
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t gc_ready_swap_page()
+{
+    ret_code_t fs_ret;
+
+    /** A page has been scanned through. All valid records found were copied to swap.
+     *  The swap page can now be flagged as a valid page. */
+    gc_set_state(READY_SWAP);
+
+    fs_ret = page_tag_write_valid(m_gc.swap_page);
+    if (fs_ret != NRF_SUCCESS)
+    {
+        return fs_ret;
+    }
+
+    /** Do not update the page type in the internal page structure (m_pages)
+     *  right away. (why?) */
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t gc_seek_record()
+{
+    // Let's find a valid record which has not been copied yet.
+    if (scan_next_valid(m_gc.cur_page, &m_gc.p_scan_addr) == NRF_SUCCESS)
+    {
+        /** The record is guaranteed to fit in the destination page,
+         *  so we don't need to check its size. */
+        return gc_copy_record();
+    }
+    else
+    {
+        /** No more (uncopied) records left on this page.
+         *  The swap page can now be marked as a valid page. */
+        return gc_ready_swap_page();
+    }
+}
+
+
+static ret_code_t gc_new_swap_page()
+{
+    ret_code_t fs_ret;
+    uint16_t   vpage_id;
+
+    gc_set_state(NEW_SWAP);
+
+    // Save the swap page virtual page ID.
+    vpage_id = m_pages[m_gc.swap_page].vpage_id;
+
+    /** The swap page has been marked as valid in Flash. We copy the GC'ed page
+     *  write_offset and virtual page ID. */
+    m_pages[m_gc.swap_page].page_type      = FDS_PAGE_VALID;
+    m_pages[m_gc.swap_page].vpage_id       = m_pages[m_gc.cur_page].vpage_id;
+    m_pages[m_gc.swap_page].words_reserved = m_pages[m_gc.cur_page].words_reserved;
+
+    // The new swap page is now the page we just GC.
+    m_gc.swap_page = m_gc.cur_page;
+
+    // Update the write_offset, words_reserved and vpage_id fields for the new swap page.
+    m_pages[m_gc.swap_page].page_type      = FDS_PAGE_SWAP;
+    m_pages[m_gc.swap_page].vpage_id       = vpage_id;
+    m_pages[m_gc.swap_page].write_offset   = FDS_PAGE_TAG_SIZE;
+    m_pages[m_gc.swap_page].words_reserved = 0;
+
+    /** Finally, erase the new swap page. Remember we still have to flag this
+     *  new page as swap, but we'll wait the callback for this operation to do so. */
+    fs_ret = fs_erase(&fs_config,
+                      (uint32_t*)m_pages[m_gc.swap_page].start_addr,
+                      FS_PAGE_SIZE_WORDS);
+
+    if (fs_ret != NRF_SUCCESS)
+    {
+        return fs_ret;
+    }
+
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t gc_new_swap_page_init()
+{
+    ret_code_t fs_ret;
+
+    gc_set_state(INIT_SWAP);
+
+    fs_ret = page_tag_write_swap(m_gc.swap_page);
+    if (fs_ret != NRF_SUCCESS)
+    {
+        return fs_ret;
+    }
+
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t gc_execute(uint32_t result)
+{
+    // TODO: Handle resuming GC.
+
+    ret_code_t ret;
+
+    if (result != NRF_SUCCESS)
+    {
+        // An operation failed. Report to the application.
+        return result;
+    }
+
+    switch (m_gc.state)
+    {
+        case BEGIN:
+        {
+            // Increment the number of times the GC has been run.
+            m_gc_runs++;
+            // Sets up a list of pages to GC.
+            gc_init();
+            // Go !
+            ret = gc_page();
+        } break;
+
+        case GC_PAGE:
+            /** A page has been successfully flagged as being GC.
+             *  Look for valid records to copy. */
+            ret = gc_seek_record();
+            break;
+
+        case COPY_RECORD:
+            /** A record has been copied to swap.
+             *  Look for more records to copy. */
+            ret = gc_seek_record();
+            break;
+
+        case READY_SWAP:
+            /** The swap page has been flagged as 'valid' (ready).
+             *  Let's prepare a new swap page. */
+            ret = gc_new_swap_page();
+            break;
+
+        case NEW_SWAP:
+            // A new swap page has been prepared. Let's flag it as swap.
+            ret = gc_new_swap_page_init();
+            break;
+
+        case INIT_SWAP:
+            /** The swap was flagged as swap in flash. Let's compress another page.
+             *  Be sure to update the address where to scan from. */
+            m_gc.p_scan_addr = NULL;
+            ret = gc_page();
+            break;
+
+        default:
+            // Should really not happen.
+            ret = NRF_ERROR_INTERNAL;
+            break;
+    }
+
+    return ret;
+}
+
+
+/**@brief Function for initializing the command queue. */
+static void queues_init(void)
+{
+    memset(&m_cmd_queue,   0, sizeof(fds_cmd_queue_t));
+    memset(&m_chunk_queue, 0, sizeof(fds_chunk_queue_t));
+}
+
+
+void cmd_queue_next(fds_cmd_t ** pp_cmd)
+{
+    if (*pp_cmd != &m_cmd_queue.cmd[FDS_CMD_QUEUE_SIZE - 1])
+    {
+        (*pp_cmd)++;
+        return;
+    }
+
+    *pp_cmd = &m_cmd_queue.cmd[0];
+}
+
+
+void chunk_queue_next(fds_record_chunk_t ** pp_chunk)
+{
+    if ((*pp_chunk) != &m_chunk_queue.chunk[FDS_CHUNK_QUEUE_SIZE - 1])
+    {
+        (*pp_chunk)++;
+        return;
+    }
+
+    *pp_chunk = &m_chunk_queue.chunk[0];
+}
+
+
+/**@brief Advances one position in the command queue. Returns true if the queue is not empty. */
+static bool cmd_queue_advance(void)
+{
+    // Reset the current element.
+    memset(&m_cmd_queue.cmd[m_cmd_queue.rp], 0, sizeof(fds_cmd_t));
+
+    CRITICAL_SECTION_ENTER();
+    if (m_cmd_queue.count != 0)
+    {
+        // Advance in the queue, wrapping around if necessary.
+        m_cmd_queue.rp = (m_cmd_queue.rp + 1) % FDS_CMD_QUEUE_SIZE;
+        m_cmd_queue.count--;
+    }
+    CRITICAL_SECTION_EXIT();
+
+    return m_cmd_queue.count != 0;
+}
+
+
+/**@brief Returns the current chunk, and advances to the next in the queue. */
+static bool chunk_queue_get_and_advance(fds_record_chunk_t ** pp_chunk)
+{
+    bool chunk_popped = false;
+
+    CRITICAL_SECTION_ENTER();
+    if (m_chunk_queue.count != 0)
+    {
+        // Point to the current chunk and advance the queue.
+        *pp_chunk = &m_chunk_queue.chunk[m_chunk_queue.rp];
+
+        m_chunk_queue.rp = (m_chunk_queue.rp + 1) % FDS_CHUNK_QUEUE_SIZE;
+        m_chunk_queue.count--;
+
+        chunk_popped = true;
+    }
+    CRITICAL_SECTION_EXIT();
+
+    return chunk_popped;
+}
+
+
+static bool chunk_queue_skip(uint8_t num_op)
+{
+    bool chunk_skipped = false;
+
+    CRITICAL_SECTION_ENTER();
+    if (num_op <= m_chunk_queue.count)
+    {
+        m_chunk_queue.count -= num_op;
+        chunk_skipped = true;
+    }
+    CRITICAL_SECTION_EXIT();
+
+    return chunk_skipped;
+}
+
+
+/**@brief Reserves resources on both queues. */
+static ret_code_t queue_reserve(uint8_t               num_cmd,
+                                uint8_t               num_chunks,
+                                fds_cmd_t          ** pp_cmd,
+                                fds_record_chunk_t ** pp_chunk)
+{
+    uint8_t cmd_index;
+    uint8_t chunk_index;
+
+    // This is really just being safe.
+    if (pp_cmd == NULL || ((pp_chunk == NULL) && (num_chunks != 0)))
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if (num_cmd == 0)
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    CRITICAL_SECTION_ENTER();
+
+    // Ensure there is enough space in the queues.
+    if ((m_cmd_queue.count   > FDS_CMD_QUEUE_SIZE - num_cmd) ||
+        (m_chunk_queue.count > FDS_CHUNK_QUEUE_SIZE - num_chunks))
+    {
+        CRITICAL_SECTION_EXIT();
+        return NRF_ERROR_BUSY;
+    }
+
+    // Find the write position in the commands queue.
+    cmd_index  = m_cmd_queue.count;
+    cmd_index += m_cmd_queue.rp;
+    cmd_index  = cmd_index % FDS_CMD_QUEUE_SIZE;
+
+    *pp_cmd = &m_cmd_queue.cmd[cmd_index];
+    m_cmd_queue.count += num_cmd;
+
+    /* If no operations are associated with the command, such as is the case 
+     * for initialization and compression, pp_chunk can be NULL. */
+    if (num_chunks != 0)
+    {
+        chunk_index  = m_chunk_queue.count;
+        chunk_index += m_chunk_queue.rp;
+        chunk_index  = chunk_index % FDS_CHUNK_QUEUE_SIZE;
+
+        *pp_chunk = &m_chunk_queue.chunk[chunk_index];
+        m_chunk_queue.count += num_chunks;
+    }
+
+    CRITICAL_SECTION_EXIT();
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Cancel the reservation on resources on queues. */
+static void queue_reserve_cancel(uint8_t num_cmd, uint8_t num_chunks)
+{
+    CRITICAL_SECTION_ENTER();
+    m_cmd_queue.count   -= num_cmd;
+    m_chunk_queue.count -= num_chunks;
+    CRITICAL_SECTION_EXIT();
+}
+
+
+static void pages_init(uint16_t * const p_pages_avail,
+                       bool     * const p_write_page_tag,
+                       bool     * const p_resume_comp)
+{
+    *p_pages_avail    = 0;
+    *p_write_page_tag = false;
+    *p_resume_comp    = false;
+
+    /** Scan pages and setup page data.
+     *  This function does NOT perform write operations in flash. */
+    for (uint16_t i = 0; i < FDS_MAX_PAGES; i++)
+    {
+        // Initialize page data. Note that start_addr must be set BEFORE invoking page_identify().
+        m_pages[i].start_addr     = fs_config.p_start_addr + (i * FS_PAGE_SIZE_WORDS);
+        m_pages[i].write_offset   = FDS_PAGE_TAG_SIZE;
+        m_pages[i].vpage_id       = i;
+        m_pages[i].records_open   = 0;
+        m_pages[i].words_reserved = 0;
+
+        m_pages[i].page_type      = page_identify(i);
+
+        switch (m_pages[i].page_type)
+        {
+            case FDS_PAGE_UNDEFINED:
+            {
+                if (page_is_empty(i))
+                {
+                    /* We have found an erased page, which can be initialized.
+                     * This will require a write in flash. */
+                    m_pages[i].page_type = FDS_PAGE_ERASED;
+                    *p_write_page_tag = true;
+                }
+            } break;
+
+            case FDS_PAGE_VALID:
+            {
+                /** If a page is valid, we update its write offset.
+                 *  Additionally, page_scan will update the last known record ID. */
+                page_scan(i, &m_pages[i].write_offset);
+                (*p_pages_avail)++;
+            } break;
+
+            case FDS_PAGE_SWAP:
+            {
+                m_gc.swap_page    = i;
+                m_swap_page_avail = true;
+            } break;
+
+            case FDS_PAGE_GC:
+            {
+                /** There is an ongoing garbage collection.
+                 *  We should resume the operation, which we don't yet. */
+                m_gc.cur_page   = i;
+                m_gc.state      = GC_PAGE;
+                *p_resume_comp  = true;
+            } break;
+
+            default:
+                break;
+        }
+    }
+}
+
+
+// NOTE: Adds FDS_HEADER_SIZE automatically.
+static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * vpage_id)
+{
+    bool     space_reserved  = false;
+    uint16_t total_len_words = length_words + FDS_HEADER_SIZE;
+
+    if (total_len_words >= FS_PAGE_SIZE_WORDS - FDS_PAGE_TAG_SIZE)
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    for (uint16_t page = 0; page < FDS_MAX_PAGES; page++)
+    {
+        if ((m_pages[page].page_type == FDS_PAGE_VALID) &&
+            (page_has_space(page, total_len_words)))
+        {
+            space_reserved = true;
+            *vpage_id      = m_pages[page].vpage_id;
+
+            CRITICAL_SECTION_ENTER();
+            m_pages[page].words_reserved += total_len_words;
+            CRITICAL_SECTION_EXIT();
+            
+            break;
+        }
+    }
+
+    return space_reserved ? NRF_SUCCESS : NRF_ERROR_NO_MEM;
+}
+
+
+static bool chunk_is_aligned(fds_record_chunk_t const * const p_chunk, uint8_t num_parts)
+{
+    for (uint8_t i = 0; i < num_parts; i++)
+    {
+        if (!is_word_aligned(p_chunk[i].p_data))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+static ret_code_t init_execute(uint32_t result, uint32_t const * p_page_addr)
+{
+    uint16_t   cur_page;
+    bool       page_tag_written = false;
+
+    if (result != NRF_SUCCESS)
+    {
+        // Oops. Error.
+        return result;
+    }
+
+    // Here we just distinguish between the first invocation and the others.
+    cur_page = p_page_addr == NULL ? 0 : page_by_addr(p_page_addr) + 1;
+
+    if (cur_page == FDS_MAX_PAGES)
+    {
+        // We have finished. We'd need to set some flags.
+        flag_set(FDS_FLAG_INITIALIZED);
+        flag_clear(FDS_FLAG_INITIALIZING);
+
+        return COMMAND_COMPLETED;
+    }
+
+    while (cur_page < FDS_MAX_PAGES && !page_tag_written)
+    {
+        if (m_pages[cur_page].page_type == FDS_PAGE_ERASED)
+        {
+            page_tag_written = true;
+
+            if (m_swap_page_avail)
+            {
+                if (page_tag_write_valid(cur_page) != NRF_SUCCESS)
+                {
+                    // Oops. Error.
+                }
+                // Update the page type.
+                m_pages[cur_page].page_type = FDS_PAGE_VALID;
+            }
+            else
+            {
+                if (page_tag_write_swap(cur_page) != NRF_SUCCESS)
+                {
+                    // Oops. Error.
+                }
+                // Update the page type.
+                m_pages[cur_page].page_type = FDS_PAGE_SWAP;
+
+                /** Update compression data. We set this information in init_pages
+                 *  if it is available, otherwise, we should set it here. */
+                m_swap_page_avail = true;
+                m_gc.swap_page = cur_page;
+            }
+        }
+
+        cur_page++;
+    }
+
+    if (!page_tag_written)
+    {
+        if (m_swap_page_avail)
+        {
+            return COMMAND_COMPLETED;
+        }
+        else
+        {
+            // There is no empty space to use as swap.
+            // Notify user that no compression is available?
+        }
+    }
+
+    return COMMAND_EXECUTING;
+}
+
+
+/**@brief Function to execute write and update commands.
+ *
+ */
+static ret_code_t store_execute(uint32_t result, fds_cmd_t * const p_cmd)
+{
+    ret_code_t           fs_ret;
+    fds_record_chunk_t * p_chunk = NULL;
+    fds_page_t         * p_page  = NULL;
+    uint32_t           * p_write_addr;
+
+    // Using virtual page IDs allows other operations to be queued even if GC has been requested.
+    page_from_virtual_id(p_cmd->vpage_id, &p_page);
+
+    if (result != NRF_SUCCESS)
+    {
+        // The previous operation has failed, update the page data.
+        p_page->write_offset   += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+        p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+
+        return result;
+    }
+
+    // Compute the write address (just syntatic sugar).
+    p_write_addr = (uint32_t*)(p_page->start_addr + p_page->write_offset);
+
+    // Execute the operation.
+    switch (p_cmd->op_code)
+    {
+        case FDS_OP_WRITE_TL:
+        {
+            fs_ret = fs_store(&fs_config,
+                              p_write_addr + FDS_WRITE_OFFSET_TL,
+                              (uint32_t*)&p_cmd->record_header.tl,
+                              FDS_HEADER_SIZE_TL /*Words*/);
+
+            // Set the next operation to be executed.
+            p_cmd->op_code = FDS_OP_WRITE_ID;
+
+        } break;
+
+        case FDS_OP_WRITE_ID:
+        {
+            fs_ret = fs_store(&fs_config,
+                              p_write_addr + FDS_WRITE_OFFSET_ID,
+                              (uint32_t*)&p_cmd->record_header.id,
+                              FDS_HEADER_SIZE_ID /*Words*/);
+
+            p_cmd->op_code = FDS_OP_WRITE_CHUNK;
+
+        } break;
+
+        case FDS_OP_WRITE_CHUNK:
+        {
+            // Decrement the number of chunks left to write.
+            p_cmd->num_chunks--;
+
+            // Retrieve the chunk to be written.
+            chunk_queue_get_and_advance(&p_chunk);
+
+            fs_ret = fs_store(&fs_config,
+                              p_write_addr + p_cmd->chunk_offset,
+                              p_chunk->p_data,
+                              p_chunk->length_words);
+
+            // Accumulate the offset.
+            p_cmd->chunk_offset += p_chunk->length_words;
+
+            if (p_cmd->num_chunks == 0)
+            {
+                /** We have written all the record chunks; we'll write
+                 *  IC last as a mean to 'validate' the record. */
+                p_cmd->op_code = FDS_OP_WRITE_IC;
+            }
+
+        } break;
+
+        case FDS_OP_WRITE_IC:
+        {
+            fs_ret = fs_store(&fs_config,
+                              p_write_addr + FDS_WRITE_OFFSET_IC,
+                              (uint32_t*)&p_cmd->record_header.ic,
+                              FDS_HEADER_SIZE_IC /*Words*/);
+
+            // This is the final operation.
+            p_cmd->op_code = FDS_OP_DONE;
+
+        } break;
+
+        case FDS_OP_DONE:
+        {
+            // We have successfully written down the IC. The command has completed successfully.
+            p_page->write_offset   += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+            p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+
+            return COMMAND_COMPLETED;
+
+        };
+
+        default:
+            fs_ret = NRF_ERROR_INTERNAL;
+            break;
+    }
+
+    // If fs_store did not succeed, the command has failed.
+    if (fs_ret != NRF_SUCCESS)
+    {
+        /** We're not going to receive a callback from fstorage
+         *  so we update the page data right away. */
+        p_page->write_offset   += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+        p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA));
+
+        // We should propagate the error from fstorage.
+        return fs_ret;
+    }
+
+    // An operation has successfully been executed. Wait for the callback.
+    return COMMAND_EXECUTING;
+}
+
+
+static ret_code_t clear_execute(ret_code_t result, fds_cmd_t * const p_cmd)
+{
+    ret_code_t        ret;
+    fds_record_desc_t desc;
+
+    // This must persist across calls.
+    static fds_find_token_t tok;
+
+    if (result != NRF_SUCCESS)
+    {
+        // A previous operation has failed. Propagate the error.
+        return result;
+    }
+
+    switch (p_cmd->op_code)
+    {
+        case FDS_OP_CLEAR_TL:
+        {
+            // We were provided a descriptor for the record.
+            desc.vpage_id  = p_cmd->vpage_id;
+            desc.record_id = p_cmd->record_header.id;
+
+            /** Unfortunately, we always seek the record in this case,
+             *  because we don't buffer an entire record descriptor in the
+             *  fds_cmd_t structure. Keep in mind though, that we will
+             *  seek one page at most. */
+            if (seek_record(&desc) != NRF_SUCCESS)
+            {
+                // The record never existed, or it is already cleared.
+                ret = NRF_ERROR_NOT_FOUND;
+            }
+            else
+            {
+                // Copy the record key, so that it may be returned in the callback.
+                p_cmd->record_header.tl.type     = ((fds_header_t*)desc.p_rec)->tl.type;
+                p_cmd->record_header.ic.instance = ((fds_header_t*)desc.p_rec)->ic.instance;
+
+                ret = fs_store(&fs_config,
+                               desc.p_rec,
+                               (uint32_t*)&m_fds_tl_invalid,
+                               FDS_HEADER_SIZE_TL);
+            }
+
+            p_cmd->op_code = FDS_OP_DONE;
+
+        } break;
+
+        case FDS_OP_CLEAR_INSTANCE:
+        {
+            if (find_record(NULL, &p_cmd->record_header.ic.instance,
+                            &desc, &tok) != NRF_SUCCESS)
+            {
+                // No more records to be found.
+                p_cmd->op_code = FDS_OP_DONE;
+
+                // Zero the token, so that we may reuse it.
+                memset(&tok, 0, sizeof(fds_find_token_t));
+
+                /** We won't receive a callback, since no flash operation
+                 *  was initiated. The command has finished. */
+                ret = COMMAND_COMPLETED;
+            }
+            else
+            {
+                ret = fs_store(&fs_config,
+                               desc.p_rec,
+                               (uint32_t*)&m_fds_tl_invalid,
+                               FDS_HEADER_SIZE_TL);
+            }
+        } break;
+
+        case FDS_OP_DONE:
+        {
+            /** The last operation completed successfully.
+             *  The command has finished. Return. */
+            ret = COMMAND_COMPLETED;
+        } break;
+
+        default:
+            ret = NRF_ERROR_INVALID_DATA;
+            break;
+    }
+
+    // Await for the operation result.
+    return ret;
+}
+
+
+static ret_code_t cmd_queue_process(void)
+{
+    ret_code_t        ret;
+    fds_cmd_t * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+
+    switch (p_cmd->id)
+    {
+        case FDS_CMD_INIT:
+            ret = init_execute(NRF_SUCCESS, NULL);
+            break;
+
+        case FDS_CMD_WRITE:
+        case FDS_CMD_UPDATE:
+            ret = store_execute(NRF_SUCCESS, p_cmd);
+            break;
+
+        case FDS_CMD_CLEAR:
+        case FDS_CMD_CLEAR_INST:
+            ret = clear_execute(NRF_SUCCESS, p_cmd);
+            break;
+
+        case FDS_CMD_GC:
+            ret = gc_execute(NRF_SUCCESS);
+            break;
+
+        default:
+            ret = NRF_ERROR_FORBIDDEN;
+            break;
+    }
+
+    if ((ret == COMMAND_EXECUTING) || (ret == COMMAND_COMPLETED))
+    {
+        return NRF_SUCCESS;
+    }
+
+    // This is an error.
+    return ret;
+}
+
+
+static ret_code_t cmd_queue_process_start(void)
+{
+    bool start_processing = false;
+
+    if (!flag_is_set(FDS_FLAG_PROCESSING))
+    {
+        flag_set(FDS_FLAG_PROCESSING);
+        start_processing = true;
+    }
+
+    if (!start_processing)
+    {
+        // We are awaiting a callback, so there is no need to manually start queue processing.
+        return NRF_SUCCESS;
+    }
+
+    return cmd_queue_process();
+}
+
+
+static void fs_callback(uint8_t           op_code,
+                        uint32_t          result,
+                        uint32_t  const * p_data,
+                        fs_length_t       length)
+{
+    ret_code_t         ret;
+    fds_cmd_t        * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+    fds_record_key_t   record_key;
+
+    switch (p_cmd->id)
+    {
+        case FDS_CMD_INIT:
+            ret = init_execute(result, p_data);
+            break;
+
+        case FDS_CMD_WRITE:
+        case FDS_CMD_UPDATE:
+            ret = store_execute(result, p_cmd);
+            break;
+
+        case FDS_CMD_CLEAR:
+        case FDS_CMD_CLEAR_INST:
+            ret = clear_execute(result, p_cmd);
+            break;
+
+        case FDS_CMD_GC:
+            ret = gc_execute(result);
+            break;
+
+        default:
+            // Should not happen.
+            ret = NRF_ERROR_INTERNAL;
+            break;
+    }
+
+    if (ret == COMMAND_EXECUTING /*=NRF_SUCCESS*/)
+    {
+        /** The current command is still being processed.
+         *  The command queue does not need to advance. */
+        return;
+    }
+
+    // Initialize the fds_record_key_t structure needed for the callback.
+    record_key.type     = p_cmd->record_header.tl.type;
+    record_key.instance = p_cmd->record_header.ic.instance;
+
+    // The command has either completed or an operation (and thus the command) has failed.
+    if (ret == COMMAND_COMPLETED)
+    {
+        // The command has completed successfully. Notify the application.
+        app_notify(NRF_SUCCESS, p_cmd->id, p_cmd->record_header.id, record_key);
+    }
+    else
+    {
+        /** An operation has failed. This is fatal for the execution of a command.
+         *  Skip other operations associated with the current command.
+         *  Notify the user of the failure.  */
+        chunk_queue_skip(p_cmd->num_chunks);
+        app_notify(ret /*=result*/, p_cmd->id, p_cmd->record_header.id, record_key);
+    }
+
+    // Advance the command queue, and if there is still something in the queue, process it.
+    if (cmd_queue_advance())
+    {
+        /** Only process the queue if there are no pending commands being queued, since they
+         *  will begin to process the queue on their own. Be sure to clear
+         *  the flag FDS_FLAG_PROCESSING though ! */
+        if (atomic_counter_is_zero())
+        {
+            cmd_queue_process();
+        }
+        else
+        {
+            flag_clear(FDS_FLAG_PROCESSING);
+        }
+    }
+    else
+    {
+        /** No more elements in the queue. Clear the FDS_FLAG_PROCESSING flag,
+         *  so that new commands can start the queue processing. */
+        flag_clear(FDS_FLAG_PROCESSING);
+    }
+}
+
+
+ret_code_t fds_init()
+{
+    ret_code_t   fs_ret;
+    fds_cmd_t  * p_cmd;
+    uint16_t     pages_avail;
+    bool         write_page_tag;
+    bool         resume_compression;
+
+    fds_record_key_t const dummy_key = {.type     = FDS_TYPE_ID_INVALID,
+                                        .instance = FDS_INSTANCE_ID_INVALID};
+
+    if (flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        // Notify immediately.
+        app_notify(NRF_SUCCESS, FDS_CMD_INIT, 0 /*unused*/, dummy_key /*unused*/);
+        return NRF_SUCCESS;
+    }
+
+    if (flag_is_set(FDS_FLAG_INITIALIZING))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    fs_ret = fs_init();
+    if (fs_ret != NRF_SUCCESS)
+    {
+        // fs_init() failed, propagate the error.
+        return fs_ret;
+    }
+
+    queues_init();
+
+    /** Initialize the last known record to zero.
+     *  Its value will be updated by page_scan() called in pages_init(). */
+    m_last_rec_id = 0;
+
+    // Initialize the page table containing all info on pages (address, type etc).
+    pages_init(&pages_avail, &write_page_tag, &resume_compression);
+
+    if (pages_avail == 0 && !write_page_tag)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    /** This flag means fds_init() has been called. However,
+     *  the module is NOT yet initialized. */
+    flag_set(FDS_FLAG_INITIALIZING);
+
+    if (resume_compression)
+    {
+        return NRF_SUCCESS;
+    }
+
+    if (write_page_tag)
+    {
+        if (queue_reserve(FDS_CMD_QUEUE_SIZE_INIT, 0, &p_cmd, NULL) != NRF_SUCCESS)
+        {
+            // Should never happen.
+            return NRF_ERROR_BUSY;
+        }
+
+        // Initialize the command in the queue.
+        p_cmd->id = FDS_CMD_INIT;
+
+        return cmd_queue_process_start();
+    }
+    else
+    {
+        /* No flash operation is necessary for initialization.
+         * We can notify the application immediately. */
+        flag_set  (FDS_FLAG_INITIALIZED);
+        flag_clear(FDS_FLAG_INITIALIZING);
+        app_notify(NRF_SUCCESS, FDS_CMD_INIT, 0 /*unused*/, dummy_key /*unused*/);
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t fds_open(fds_record_desc_t * const p_desc,
+                    fds_record_t      * const p_record)
+{
+    uint16_t page;
+
+    if (p_desc == NULL || p_record == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS)
+    {
+        // Should not happen.
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    // Seek the record if necessary.
+    if (seek_record(p_desc) == NRF_SUCCESS)
+    {
+        if (header_is_valid((fds_header_t*)p_desc->p_rec))
+        {
+            CRITICAL_SECTION_ENTER();
+            m_pages[page].records_open++;
+            CRITICAL_SECTION_EXIT();
+
+            p_record->header = *((fds_header_t*)p_desc->p_rec);
+            p_record->p_data = (p_desc->p_rec + FDS_HEADER_SIZE);
+
+            return NRF_SUCCESS;
+        }
+    }
+
+    /** The record could not be found.
+     *  It either never existed or it has been cleared. */
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+ret_code_t fds_close(fds_record_desc_t const * const p_desc)
+{
+    uint16_t page;
+
+    if (p_desc == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS)
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    CRITICAL_SECTION_ENTER();
+    m_pages[page].records_open--;
+    CRITICAL_SECTION_EXIT();
+
+    return NRF_SUCCESS;
+}
+
+
+static ret_code_t write_enqueue(fds_record_desc_t        * const p_desc,
+                                fds_record_key_t                 key,
+                                uint8_t                          num_chunks,
+                                fds_record_chunk_t               chunks[],
+                                fds_write_token_t  const * const p_tok,
+                                bool                             do_update)
+{
+    ret_code_t           ret;
+    fds_cmd_t          * p_cmd;
+    fds_record_chunk_t * p_chunk = NULL;
+    uint16_t             vpage_id;
+    uint16_t             length_words = 0;
+    uint8_t              cmd_queue_elems;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if ((key.type     == FDS_TYPE_ID_INVALID) ||
+        (key.instance == FDS_INSTANCE_ID_INVALID))
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    if (!chunk_is_aligned(chunks, num_chunks))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    cmd_queue_elems = do_update ? FDS_CMD_QUEUE_SIZE_UPDATE : FDS_CMD_QUEUE_SIZE_WRITE;
+
+    // Reserve space on both queues, and obtain pointers to the first elements reserved.
+    ret = queue_reserve(cmd_queue_elems,
+                        num_chunks,
+                        &p_cmd,
+                        &p_chunk);
+
+    if (ret != NRF_SUCCESS)
+    {
+        return ret;
+    }
+
+    // No space was previously reserved for this operation.
+    if (p_tok == NULL)
+    {
+        // Compute the total length of the record.
+        for (uint8_t i = 0; i < num_chunks; i++)
+        {
+            length_words += chunks[i].length_words;
+        }
+
+        /** Find a page where we can write the data. Reserve the space necessary
+         *  to write the metadata as well. */
+        ret = write_space_reserve(length_words, &vpage_id);
+        if (ret != NRF_SUCCESS)
+        {
+            // If there is no space available, cancel the queue reservation.
+            queue_reserve_cancel(cmd_queue_elems, num_chunks);
+            return ret;
+        }
+    }
+    else
+    {
+        length_words = p_tok->length_words;
+        vpage_id     = p_tok->vpage_id;
+    }
+
+    // Initialize the command.
+    p_cmd->id           = do_update ? FDS_CMD_UPDATE : FDS_CMD_WRITE;
+    p_cmd->op_code      = FDS_OP_WRITE_TL;
+    p_cmd->num_chunks   = num_chunks;
+    p_cmd->chunk_offset = FDS_WRITE_OFFSET_DATA;
+    p_cmd->vpage_id     = vpage_id;
+
+    // Fill in the header information.
+    p_cmd->record_header.id              = record_id_new();
+    p_cmd->record_header.tl.type         = key.type;
+    p_cmd->record_header.tl.length_words = length_words;
+    p_cmd->record_header.ic.instance     = key.instance;
+    p_cmd->record_header.ic.checksum     = 0;
+
+    // Buffer the record chunks in the queue.
+    for (uint8_t i = 0; i < num_chunks; i++)
+    {
+        p_chunk->p_data       = chunks[i].p_data;
+        p_chunk->length_words = chunks[i].length_words;
+        chunk_queue_next(&p_chunk);
+    }
+
+    if (do_update)
+    {
+        // Clear
+        cmd_queue_next(&p_cmd);
+        p_cmd->id      = FDS_CMD_CLEAR;
+        p_cmd->op_code = FDS_OP_CLEAR_TL;
+
+        p_cmd->vpage_id         = p_desc->vpage_id;
+        p_cmd->record_header.id = p_desc->record_id;
+    }
+
+    // Initialize the record descriptor, if provided.
+    if (p_desc != NULL)
+    {
+        p_desc->vpage_id  = vpage_id;
+        // Don't invoke record_id_new() again.
+        p_desc->record_id = p_cmd->record_header.id;
+    }
+
+    return cmd_queue_process_start();
+}
+
+
+ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words)
+{
+    uint16_t vpage_id;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if (p_tok == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    // Reserve space on the page. write_space_reserve() accounts for the header.
+    if (write_space_reserve(length_words, &vpage_id) == NRF_SUCCESS)
+    {
+        p_tok->vpage_id     = vpage_id;
+        p_tok->length_words = length_words;
+
+        return NRF_SUCCESS;
+    }
+
+    return NRF_ERROR_NO_MEM;
+}
+
+
+ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok)
+{
+    fds_page_t * p_page;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if (p_tok == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    if (page_from_virtual_id(p_tok->vpage_id, &p_page) != NRF_SUCCESS)
+    {
+        // Could not find the virtual page. This shouldn't happen.
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    if ((p_page->words_reserved - p_tok->length_words) < 0)
+    {
+        /** We are trying to cancel a reservation for more words than how many are
+         *  currently reserved on the page. This is shouldn't happen. */
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    // Free the space which had been reserved.
+    p_page->words_reserved -= p_tok->length_words;
+
+    // Clean the token.
+    p_tok->vpage_id     = 0;
+    p_tok->length_words = 0;
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t fds_write(fds_record_desc_t  * const p_desc,
+                     fds_record_key_t           key,
+                     uint8_t                    num_chunks,
+                     fds_record_chunk_t         chunks[])
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = write_enqueue(p_desc, key, num_chunks, chunks, NULL, false /*not an update*/);
+    atomic_counter_dec();
+    return ret;
+}
+
+
+ret_code_t fds_write_reserved(fds_write_token_t  const * const p_tok,
+                              fds_record_desc_t        * const p_desc,
+                              fds_record_key_t                 key,
+                              uint8_t                          num_chunks,
+                              fds_record_chunk_t               chunks[])
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = write_enqueue(p_desc, key, num_chunks, chunks, p_tok, false /*not an update*/);
+    atomic_counter_dec();
+    return ret;
+}
+
+
+static ret_code_t clear_enqueue(fds_record_desc_t * const p_desc)
+{
+    ret_code_t   ret;
+    fds_cmd_t  * p_cmd;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if (p_desc == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    ret = queue_reserve(FDS_CMD_QUEUE_SIZE_CLEAR, 0, &p_cmd, NULL);
+
+    if (ret != NRF_SUCCESS)
+    {
+        return ret;
+    }
+
+    // Initialize the command.
+    p_cmd->id        = FDS_CMD_CLEAR;
+    p_cmd->op_code   = FDS_OP_CLEAR_TL;
+
+    p_cmd->record_header.id = p_desc->record_id;
+    p_cmd->vpage_id         = p_desc->vpage_id;
+
+    return cmd_queue_process_start();
+}
+
+
+ret_code_t fds_clear(fds_record_desc_t * const p_desc)
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = clear_enqueue(p_desc);
+    atomic_counter_dec();
+    return ret;
+}
+
+
+static ret_code_t clear_by_instance_enqueue(fds_instance_id_t instance)
+{
+    ret_code_t   ret;
+    fds_cmd_t  * p_cmd;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    ret  = queue_reserve(FDS_CMD_QUEUE_SIZE_CLEAR, 0, &p_cmd, NULL);
+
+    if (ret != NRF_SUCCESS)
+    {
+        return ret;
+    }
+
+    p_cmd->id      = FDS_CMD_CLEAR_INST;
+    p_cmd->op_code = FDS_OP_CLEAR_INSTANCE;
+
+    p_cmd->record_header.ic.instance = instance;
+
+    return cmd_queue_process_start();
+}
+
+ret_code_t fds_clear_by_instance(fds_instance_id_t instance)
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = clear_by_instance_enqueue(instance);
+    atomic_counter_dec();
+    return ret;
+}
+
+
+ret_code_t fds_update(fds_record_desc_t  * const p_desc,
+                      fds_record_key_t           key,
+                      uint8_t                    num_chunks,
+                      fds_record_chunk_t         chunks[])
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = write_enqueue(p_desc, key, num_chunks, chunks, NULL, true /*update*/);
+    atomic_counter_dec();
+    return ret;
+}
+
+
+static ret_code_t gc_enqueue()
+{
+    ret_code_t  ret;
+    fds_cmd_t * p_cmd;
+
+    if (!flag_is_set(FDS_FLAG_INITIALIZED))
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    ret = queue_reserve(FDS_CMD_QUEUE_SIZE_GC, 0, &p_cmd, NULL);
+    if (ret != NRF_SUCCESS)
+    {
+        return ret;
+    }
+
+    p_cmd->id = FDS_CMD_GC;
+
+    // Set compression parameters.
+    m_gc.state = BEGIN;
+
+    return cmd_queue_process_start();
+}
+
+
+ret_code_t fds_gc()
+{
+    ret_code_t ret;
+    atomic_counter_inc();
+    ret = gc_enqueue();
+    atomic_counter_dec();
+    return ret;   
+}
+
+
+ret_code_t fds_find(fds_type_id_t             type,
+                    fds_instance_id_t         instance,
+                    fds_record_desc_t * const p_desc,
+                    fds_find_token_t  * const p_token)
+{
+    if (p_desc == NULL || p_token == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    return find_record(&type, &instance, p_desc, p_token);
+}
+
+
+ret_code_t fds_find_by_type(fds_type_id_t             type,
+                            fds_record_desc_t * const p_desc,
+                            fds_find_token_t  * const p_token)
+{
+    if (p_desc == NULL || p_token == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    return find_record(&type, NULL, p_desc, p_token);
+}
+
+
+ret_code_t fds_find_by_instance(fds_instance_id_t         instance,
+                                fds_record_desc_t * const p_desc,
+                                fds_find_token_t  * const p_token)
+{
+    if (p_desc == NULL || p_token == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    return find_record(NULL, &instance, p_desc, p_token);
+}
+
+
+ret_code_t fds_register(fds_cb_t cb)
+{
+    if (m_users == FDS_MAX_USERS)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    m_cb_table[m_users] = cb;
+    m_users++;
+
+    return NRF_SUCCESS;
+}
+
+
+bool fds_descriptor_match(fds_record_desc_t const * const p_desc1,
+                          fds_record_desc_t const * const p_desc2)
+{
+    if ((p_desc1 == NULL) || (p_desc2 == NULL))
+    {
+        return false;
+    }
+
+    return (p_desc1->record_id == p_desc2->record_id);
+}
+
+
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
+                                      fds_record_id_t           record_id)
+{
+    if (p_desc == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    p_desc->record_id = record_id;
+    p_desc->vpage_id  = FDS_VPAGE_ID_UNKNOWN;
+
+    return NRF_SUCCESS;
+}
+
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
+                                   fds_record_id_t         * const p_record_id)
+{
+    if (p_desc == NULL || p_record_id == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    *p_record_id = p_desc->record_id;
+
+    return NRF_SUCCESS;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 FDS_H__
+#define FDS_H__
+
+/**
+ * @defgroup flash_data_storage Flash Data Storage
+ * @ingroup app_common
+ * @{
+ * @brief Flash Data Storage (FDS).
+ *
+ * @details Flash Data Storage (FDS) is a minimalistic filesystem for the on-chip flash.
+ *          It can be used to manipulate @e records, which consist of a piece of data, made up
+ *          of one or more chunks, and an associated key pair. 
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+
+/**@brief */
+#define SIZEOF_WORDS(val)       (sizeof(val) / 4)
+
+/**@brief Reserved type key used to flag cleared records.
+ *        May not be used as a record key by the application. */
+#define FDS_TYPE_ID_INVALID     (0x0000)
+/**@brief Reserved instance key used to check for missing or corrupted metadata.
+ *        May not be used as a record key by the application. */
+#define FDS_INSTANCE_ID_INVALID (0xFFFF)
+
+
+typedef uint32_t fds_record_id_t;
+typedef uint16_t fds_type_id_t;
+typedef uint16_t fds_length_t;
+typedef uint16_t fds_instance_id_t;
+typedef uint16_t fds_checksum_t;
+
+
+/**@brief A piece of a record metadata, keeping information about one of its keys (type) and its
+ *        lenght, expressed in 4 byte words. */
+typedef struct 
+{
+    fds_type_id_t type;           /**< The record type ID. */
+    fds_length_t  length_words;   /**< Length of the record's data, in 4 byte words. */
+} fds_tl_t;
+
+
+/**@brief A piece of a record metadata, keeping information about one of its keys (instance) and
+ *        its checksum. */
+typedef struct
+{
+    fds_instance_id_t instance;       /**< The record instance ID. */
+    fds_checksum_t    checksum;       /**< Checksum of the entire record, including the metadata. */
+} fds_ic_t;
+
+
+/**@brief The record metadata. */
+typedef struct
+{
+    fds_tl_t        tl;     /**< See @ref fds_tl_t. */
+    fds_ic_t        ic;     /**< See @ref fds_ic_t. */
+    fds_record_id_t id;     /**< The unique record ID (32 bits). */
+} fds_header_t;
+
+
+typedef fds_header_t fds_record_header_t;
+
+/**@brief The record descriptor structure, used to manipulate a record.
+ * @note  This structure is meant to be opaque to the user, who does not need to access
+ *        any of its fields.
+ * @note    This structure does not need special initialization.
+ * @warning Do not reuse the same descriptor for different records. If you do, be sure to set
+ *          its fields to zero. */
+typedef struct
+{
+    uint32_t         record_id;     /**< The unique record ID. */
+    uint32_t const * p_rec;         /**< The last known record address in flash. */
+    uint16_t         vpage_id;      /**< The virtual page ID in which the record is stored. */
+    uint16_t         gc_magic;      /**< Number of times the GC algorithm has been run. */
+    uint16_t         ptr_magic;     /**< Used to verify the validity of p_rec. */
+} fds_record_desc_t;
+
+
+/**@brief The record key, used to lookup records.
+ * @note  The uniqueness of either field is not enforced by the system. */
+typedef struct
+{
+    uint16_t type;
+    uint16_t instance;
+} fds_record_key_t;
+
+
+/**@brief Structure used for reading a record back from flash memory. */
+typedef struct
+{
+    // TODO: the header should be a pointer.
+    fds_header_t         header;        /**< The record header (metadata), as stored in flash. */
+    uint32_t     const * p_data;        /**< The record data. */
+} fds_record_t;
+
+
+/**@brief A record chunk, containing a piece of data to be stored in a record.
+ *
+ * @note  p_data must be aligned on a (4 bytes) word boundary.
+ */
+typedef struct
+{
+    void         const * p_data;           /**< Pointer to the data to store. Must be word aligned. */
+    fds_length_t         length_words;     /**< Length of data pointed by p_data, in 4 byte words. */
+} fds_record_chunk_t;
+
+
+/**@brief A token to a reserved space in flash, created by @ref fds_reserve.
+ *        Use @ref fds_write_reserved to write the record in the reserved space,
+ *        or @ref fds_reserve_cancel to cancel the reservation.
+ */
+typedef struct
+{
+    uint16_t            vpage_id;       /**< The virtual ID of the page where space was reserved. */
+    fds_length_t        length_words;   /**< The amount of space reserved, in 4 byte words. */
+} fds_write_token_t;
+
+
+/**@brief A token to keep information about the progress of @ref fds_find, @ref fds_find_by_type
+ *        and @ref fds_find_by_instance operations.
+ * @note  This structure is meant to be opaque to the user, who does not need to access any of its
+ *        fields.
+ * @note  The token does not need special initialization.
+ * @warning Do not reuse the same token to search for different records. If you do, be sure to set
+ *          its fields to zero. */
+typedef struct
+{
+    uint32_t const * p_addr;
+    uint32_t         magic;
+    uint16_t         vpage_id;
+} fds_find_token_t;
+
+
+typedef enum
+{
+    FDS_CMD_NONE,       /**< No command. */
+    FDS_CMD_INIT,       /**< Module initialization commnad. Used in @ref fds_init */
+    FDS_CMD_WRITE,      /**< Write command. Used in @ref fds_write and @ref fds_write_reserved. */
+    FDS_CMD_UPDATE,     /**< Update command. Used in @ref fds_update. */
+    FDS_CMD_CLEAR,      /**< Clear record command. Used in @ref fds_clear and @ref fds_update. */
+    FDS_CMD_CLEAR_INST, /**< Clear instance command. Used in @ref fds_clear_by_instance. */
+    FDS_CMD_GC          /**< Garbage collection. Used in @ref fds_gc. */
+} fds_cmd_id_t;
+
+ 
+/**@brief Flash data storage callback function.
+ *
+ * @param result     Result of the command.
+ * @param cmd        The command associated with the callback.
+ * @param record_id  The unique ID of the record associated with the callback.
+ * @param record_key The key pair of the record associated with the callback.
+ */
+typedef void (*fds_cb_t)(ret_code_t       result,
+                         fds_cmd_id_t     cmd,
+                         fds_record_id_t  record_id,
+                         fds_record_key_t record_key);
+
+
+/**@brief       Function to register a callback for the module events.
+ * @details     The maximum amount of callback which can be registered can be configured by
+ *              changing the FDS_MAX_USERS macro in fds_config.h.
+ * 
+ * @param[in]   cb The callback function.
+ *
+ *
+ * @retval      NRF_SUCCESS      Success.
+ * @retval      NRF_ERROR_NO_MEM Error. Maximum number of registered callbacks reached.
+ */
+ret_code_t fds_register(fds_cb_t cb);
+
+
+/**@brief Function to initialize the module.
+ *
+ * @details This function initializes the module and installs the filesystem, if it is not
+ *          installed yet.
+ *
+ * @note    This function is asynchronous. Completion is reported with a callback through the
+ *          registered event handler. To be able to receive such callback, be sure to call
+ *          @ref fds_register before calling @ref fds_init.
+ *
+ * @retval  NRF_SUCCESS                 Success. The command was queued.
+ * @retval  NRF_ERROR_INVALID_STATE     Error. The module is currently undergoing initialization.
+ * @retval  NRF_ERROR_NO_MEM            Error. Insufficient space to install the filesystem, or
+ *                                      insufficient resources to perform the installation.
+ */
+ret_code_t fds_init(void);
+
+
+/**@brief Function to write a record to flash.
+ *
+ * @details This function can be used to write a record to flash. A record data consists of
+ *          multiple chunks and is supplied to the function as an array of fds_record_chunk_t
+ *          structures. The maximum lenght of a record data may not exceed the size of one flash
+ *          page minus FDS_HEADER_SIZE words.
+ *            
+ * @note This function is asynchronous, therefore, completion is reported with a callback
+ *       through the registered event handler.
+ *
+ * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
+ *       internally, it must be kept in memory by the application until the callback for the
+ *       command has been received, i.e., the command completed.
+ *
+ * @param[out] p_desc     The record descriptor. It may be NULL.
+ * @param[in]  key        The record key pair.
+ * @param[in]  num_chunks The number of elements in the chunks array.
+ * @param[in]  chunks     An array of chunks making up the record data.
+ *
+ * @retval NRF_SUCCESS               Success. The command was queued.
+ * @retval NRF_ERROR_INVALID_STATE   Error. The module is not initialized.
+ * @retval NRF_ERROR_INVALID_DATA    Error. The key contains an invalid type or instance.
+ * @retval NRF_ERROR_INVALID_ADDR    Error. The record data is not aligned on a 4 byte boundary.
+ * @retval NRF_ERROR_INVALID_LENGTH  Error. The record length exceeds the maximum lenght.
+ * @retval NRF_ERROR_BUSY            Error. Insufficient internal resources to queue the operation.
+ * @retval NRF_ERROR_NO_MEM          Error. No flash space available to store the record.
+ */
+ret_code_t fds_write(fds_record_desc_t * const p_desc,
+                     fds_record_key_t          key,
+                     uint8_t                   num_chunks,
+                     fds_record_chunk_t        chunks[]);
+
+
+/**@brief Function to reserve space for a record.
+ *
+ * @details This function can be used to reserve flash space to store a record, which can be
+ *          later written down using @ref fds_write_reserved. It is possible to cancel a
+ *          reservation by using @ref fds_reserve_cancel.
+ *
+ * @param[out] p_tok        A token which can be used to write a record in the reserved space
+ *                          using @ref fds_write_reserved.
+ * @param[in]  length_words The lenght of the record data, in 4 byte words.
+ *
+ * @retval  NRF_SUCCESS             Success. Flash space was successfully reserved.
+ * @retval  NRF_ERROR_NULL          Error. p_tok is NULL.
+ * @retval  NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval  NRF_ERROR_NO_MEM        Error. Insufficient space.
+ */
+ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words);
+
+
+/**@brief Function to cancel a space reservation.
+ *
+ * @param[in] p_tok The token produced by @ref fds_reserve, identifying the reservation to cancel.
+ *
+ * @retval NRF_SUCCESS             Success. The reservation was canceled.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. p_tok is NULL.
+ * @retval NRF_ERROR_INVALID_DATA  Error. p_tok contains invalid data.
+ */
+ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok);
+
+
+/**@brief Function to write a record to flash, the space for which has been previously reserved
+ *        using @ref fds_reserve.
+ *
+ * @details This function behaves similarly to @ref fds_write, with the exception that it never
+ *          fails with NRF_ERROR_NO_MEM.
+ *
+ * @note This function is asynchronous, therefore, completion is reported with a callback
+ *       through the registered event handler.
+ *
+ * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
+ *       internally, it must be kept in memory by the application until the callback for the
+ *       command has been received, i.e., the command completed.
+ *
+ * @param[in]  p_tok      The token return by @ref fds_reserve.
+ * @param[out] p_desc     The record descriptor. It may be NULL.
+ * @param[in]  key        The record key pair.
+ * @param[in]  num_chunks The number of elements in the chunks array.
+ * @param[in]  chunks     An array of chunks making up the record data.
+ *
+ * @retval NRF_SUCCESS               Success. The command was queued.
+ * @retval NRF_ERROR_INVALID_STATE   Error. The module is not initialized.
+ * @retval NRF_ERROR_INVALID_DATA    Error. The key contains an invalid type or instance.
+ * @retval NRF_ERROR_INVALID_ADDR    Error. The record data is not aligned on a 4 byte boundary.
+ * @retval NRF_ERROR_INVALID_LENGTH  Error. The record length exceeds the maximum lenght.
+ * @retval NRF_ERROR_BUSY            Error. Insufficient internal resources to queue the operation.
+ */
+ret_code_t fds_write_reserved(fds_write_token_t  const * const p_tok,
+                              fds_record_desc_t        * const p_desc,
+                              fds_record_key_t                 key,
+                              uint8_t                          num_chunks,
+                              fds_record_chunk_t               chunks[]);
+
+
+/**@brief Function to clear a record.
+ *
+ * @details Clearing a record has the effect of preventing the system from retrieving the record
+ *          descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
+ *          functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
+ *          a record which has been cleared. Clearing a record does not free the space it occupies
+ *          in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
+ *
+ * @note    This function is asynchronous, therefore, completion is reported with a callback
+ *          through the registered event handler.
+ *
+ * @param[in] p_desc The descriptor of the record to clear.
+ *
+ * @retval NRF_SUCCESS             Success. The command was queued.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. p_desc is NULL.
+ * @retval NRF_ERROR_BUSY          Error. Insufficient internal resources to queue the operation.
+ */
+ret_code_t fds_clear(fds_record_desc_t * const p_desc);
+
+
+/**@brief Function to clear all records with a given instance.
+ *
+ * @details Clearing a record has the effect of preventing the system from retrieving the record
+ *          descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
+ *          functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
+ *          a record which has been cleared. Clearing a record does not free the space it occupies
+ *          in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
+ *
+ * @note This function is asynchronous, therefore, completion is reported with a callback
+ *       through the registered event handler. Only one callback will be issued. The record
+ *       instance ID in the key parameter of the callback will contain the instance ID passed as
+ *       parameter to this function. The record ID parameter will be zero, and the type ID equal
+ *       to FDS_TYPE_ID_INVALID.
+ *
+ * @param[in] instance The instance ID of the records to clear.
+ *
+ * @retval NRF_SUCCESS             Success. The command was queued.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. p_desc is NULL.
+ * @retval NRF_ERROR_BUSY          Error. Insufficient internal resources to queue the operation.
+ */
+ret_code_t fds_clear_by_instance(fds_instance_id_t instance);
+
+
+/**@brief Function to update an existing record.
+ *
+ * @details Updating a record writes a new record with the given key and data in flash, and then
+ *          clears the old record.
+ *
+ * @note This function is asynchronous, therefore, completion is reported with a callback
+ *       through the registered event handler. Two callbacks will be issued, one to signal that
+ *       the updated record has been written down, and another to signal that the old one has been
+ *       cleared.
+ *       
+ * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
+ *       internally, it must be kept in memory by the application until the callback for the
+ *       command has been received, i.e., the command completed.
+ * 
+ * @param[in, out] p_desc The descriptor of the record to update. The descriptor of the updated
+ *                        record, after the function has returned with NRF_SUCCESS.
+ * @param[in] key         The record new key pair.
+ * @param[in] num_chunks  The number of elements in the chunks array.
+ * @param[in] chunks      An array of chunks making up the record new data.
+ *
+ * @retval NRF_SUCCESS               Success. The command was queued.
+ * @retval NRF_ERROR_INVALID_STATE   Error. The module is not initialized.
+ * @retval NRF_ERROR_INVALID_DATA    Error. The key contains an invalid type or instance.
+ * @retval NRF_ERROR_INVALID_ADDR    Error. The record data is not aligned on a 4 byte boundary.
+ * @retval NRF_ERROR_INVALID_LENGTH  Error. The record length exceeds the maximum lenght.
+ * @retval NRF_ERROR_BUSY            Error. Insufficient internal resources to queue the operation.
+ * @retval NRF_ERROR_NO_MEM          Error. No flash space available to store the record.
+ */
+ret_code_t fds_update(fds_record_desc_t  * const p_desc,
+                      fds_record_key_t           key,
+                      uint8_t                    num_chunks,
+                      fds_record_chunk_t         chunks[]);
+
+
+/**@brief Function to search for records with a given key pair.
+ *
+ * @details Because types are not unique, to search for the next record with the given key call
+ *          the function again and supply the same fds_find_token_t structure to resume searching
+ *          from the last record found.
+ *
+ * @param[in]  type     The record type ID.
+ * @param[in]  instance The record instance ID.
+ * @param[out] p_desc   The descriptor of the record found.
+ * @param[out] p_token  A token containing information about the progress of the operation.
+ *
+ * @retval NRF_SUCCESS             Success. A record was found.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. Either p_desc or p_token are NULL.
+ * @retval NRF_ERROR_NOT_FOUND     Error. No record with the given key pair was found.
+ */
+ret_code_t fds_find(fds_type_id_t             type, 
+                    fds_instance_id_t         instance, 
+                    fds_record_desc_t * const p_desc,
+                    fds_find_token_t  * const p_token);
+
+
+/**@brief Function to search for records with a given type.
+ *
+ * @details Because types are not unique, to search for the next record with the given key call
+ *          the function again and supply the same fds_find_token_t structure to resume searching
+ *          from the last record found.
+ *
+ * @param[in]  type    The type ID in the record key.
+ * @param[out] p_desc  The descriptor of the record found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval NRF_SUCCESS             Success. A record was found.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. Either p_desc or p_token are NULL.
+ * @retval NRF_ERROR_NOT_FOUND     Error. No record with the given type was found.
+ */
+ ret_code_t fds_find_by_type(fds_type_id_t             type,
+                             fds_record_desc_t * const p_desc,
+                             fds_find_token_t  * const p_token);
+
+
+/**@brief Function to search for records with a given instance.
+ *
+ * @details Because types are not unique, to search for the next record with the given key call
+ *          the function again and supply the same fds_find_token_t structure to resume searching
+ *          from the last record found.
+ *
+ * @param[in]  instance The instance ID in the record key.
+ * @param[out] p_desc   The descriptor of the record found.
+ * @param[out] p_token  A token containing information about the progress of the operation.
+ *
+ * @retval NRF_SUCCESS             Success. A record was found.
+ * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
+ * @retval NRF_ERROR_NULL          Error. Either p_desc or p_token are NULL.
+ * @retval NRF_ERROR_NOT_FOUND     Error. No record with the given instance was found.
+ */
+ret_code_t fds_find_by_instance(fds_instance_id_t         instance,
+                                fds_record_desc_t * const p_desc,
+                                fds_find_token_t  * const p_token);
+
+
+/**@brief Function to open a record for reading.
+ *
+ * @details Function to read a record which has been written to flash. This function initializes
+ *          a fds_record_t structure which can be used to access the record data as well as
+ *          its associated metadata. The pointers provided in the fds_record_t structure are
+ *          pointers to flash memory. Opening a record with @ref fds_open prevents the garbage
+ *          collection to run on the flash page in which record is stored, therefore the contents
+ *          of the memory pointed by the fds_record_t p_data field is guaranteed to remain
+ *          unmodified, as long as the record is kept open.
+ *
+ * @note When you are done reading a record, close it using @ref fds_close so that successive
+ *       garbage collections can reclaim space on the page where the record is stored, if necessary.
+ *
+ * @param[in]  p_desc   The descriptor of the record to open.
+ * @param[out] p_record The record data and metadata, as stored in flash.
+ *
+ * @retval NRF_SUCCESS            Success. The record was opened.
+ * @retval NRF_ERROR_NOT_FOUND    Error. The record was not found. It may have been cleared, or it
+ *                                may have not been written yet.
+ * @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
+ * @retval NRF_ERROR_NULL         Error. Either p_desc or p_record are NULL.
+ */
+ret_code_t fds_open(fds_record_desc_t * const p_desc,
+                    fds_record_t      * const p_record);
+
+
+/**@brief Function to close a record, after its contents have been read.
+ *
+ * @details Closing a record allows garbage collection to be run on the page in which the
+ *          record being closed is stored (if no other records remain open on that page).
+ *
+ * @note Closing a record, does NOT invalidate its descriptor, which can be safely supplied to
+ *       all functions which accept a descriptor as a parameter.
+ *
+ * @param[in] p_desc The descriptor of the record to close.
+ *
+ * @retval NRF_SUCCESS            Success. The record was closed.
+ * @retval NRF_ERROR_NULL         Error. p_desc is NULL.
+ * @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
+ */
+ret_code_t fds_close(fds_record_desc_t const * const p_desc);
+
+
+/**@brief Function to perform a garbage collection.
+ *
+ * @details Garbage collection reclaims the flash space occupied by records which have been cleared
+ *          using @ref fds_clear.
+ *
+ * @note    This function is asynchronous, therefore, completion is reported with a callback
+ *          through the registered event handler.
+ */
+ret_code_t fds_gc(void);
+
+
+/**@brief Function to compare two record descriptors.
+ *
+ * @param[in] p_desc_one First descriptor.
+ * @param[in] p_desc_two Second descriptor.
+ *
+ * @retval true  If the descriptors identify the same record.
+ * @retval false Otherwise.
+ */
+bool fds_descriptor_match(fds_record_desc_t const * const p_desc_one,
+                          fds_record_desc_t const * const p_desc_two);
+
+
+/**@brief Function to obtain a descriptor from a record ID.
+ *
+ * @details This function can be used to reconstruct a descriptor from a record ID, such as the
+ *          one passed to the callback function.
+ *
+ * @warning This function does not check if a record with the given record ID exists or not. If a
+ *          non-existing record ID is supplied, the resulting descriptor will cause other functions
+ *          to fail when used as parameter.
+ *
+ * @param[out] p_desc    The descriptor of the record with given record ID.
+ * @param[in]  record_id The record ID for which to provide a descriptor.
+ *
+ * @retval NRF_SUCCESS         Success.
+ * @retval NRF_ERROR_NULL      Error. p_desc is NULL.
+ */
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
+                                      fds_record_id_t           record_id);
+
+/**@brief Function to obtain a record ID from a record descriptor.
+ *
+ * @details This function can be used to extract a record ID from a descriptor. It may be used
+ *          in the callback function to determine which record the callback is associated to, if
+ *          you have its descriptor.
+ *
+ * @warning This function does not check the record descriptor sanity. If the descriptor is
+ *          uninitialized, or has been tampered with, the resulting record ID may be invalid.
+ *
+ * @param[in]  p_desc      The descriptor from which to extract the record ID.
+ * @param[out] p_record_id The record ID contained in the given descriptor.
+ *
+ * @retval NRF_SUCCESS    Success.
+ * @retval NRF_ERROR_NULL Error. Either p_desc is NULL or p_record_id is NULL.
+ */
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
+                                   fds_record_id_t         * const p_record_id);
+
+/** @} */
+                                         
+#endif // FDS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds_config.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 FDS_CONFIG_H__
+#define FDS_CONFIG_H__
+
+ /**
+ * @file fds_config.h
+ *
+ * @addtogroup flash_data_storage
+ * @{
+ */
+
+/**@brief Configures the size of the internal queue. */
+#define FDS_CMD_QUEUE_SIZE          (8)
+/**@brief Determines how many @ref fds_record_chunk_t structures can be buffered at any time. */
+#define FDS_CHUNK_QUEUE_SIZE        (8)
+
+/**@brief Configures the number of physical flash pages to use. Out of the total, one is reserved
+ *        for garbage collection, hence, two pages is the minimum: one for the application data
+ *        and one for the system. */
+#define FDS_MAX_PAGES               (2)
+/**@brief Configures the maximum number of callbacks which can be registred. */
+#define FDS_MAX_USERS               (10)
+
+/** Page tag definitions. */
+#define FDS_PAGE_TAG_WORD_0_SWAP    (0xA5A5A5A5)
+#define FDS_PAGE_TAG_WORD_0_VALID   (0xA4A4A4A4)
+#define FDS_PAGE_TAG_WORD_1         (0xAABBCCDD)
+#define FDS_PAGE_TAG_WORD_2         (0xAABB01DD) /**< Includes version. */
+#define FDS_PAGE_TAG_WORD_3         (0x1CEB00DA)
+#define FDS_PAGE_TAG_WORD_3_GC      (0x1CEB00D8)
+
+/** @} */
+
+#endif // FDS_CONFIG_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fds/fds_types_internal.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 FDS_TYPES_INTERNAL__
+#define FDS_TYPES_INTERNAL__
+
+#include "fds.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_soc.h"
+
+
+#define COMMAND_EXECUTING           (NRF_SUCCESS)
+#define COMMAND_COMPLETED           (0x1234)
+//#define COMMAND_FAILED            (0x1236)
+
+#define FDS_MAGIC_HWORD             (0xF11E)
+#define FDS_MAGIC_WORD              (0x15ABE11A)
+#define FDS_ERASED_WORD             (0xFFFFFFFF)
+
+#define FDS_PAGE_TAG_SIZE           (4) /**< Page tag size, in 4 byte words. */
+
+#define FDS_VPAGE_ID_UNKNOWN        (0xFFFF)
+
+#define FDS_WRITE_OFFSET_TL         (0) /**< Offset of TL from the record base address, in 4 byte words. */
+#define FDS_WRITE_OFFSET_IC         (1) /**< Offset of IC from the record base address, in 4 byte words. */
+#define FDS_WRITE_OFFSET_ID         (2) /**< Offset of ID from the record base address, in 4 byte words. */
+#define FDS_WRITE_OFFSET_DATA       (3) /**< Offset of the data (chunks) from the record base address, in 4 byte words. */
+
+#define FDS_HEADER_SIZE_TL          (1) /**< Size of the TL part of the header, in 4 byte words. */
+#define FDS_HEADER_SIZE_ID          (1) /**< Size of the IC part of the header, in 4 byte words. */
+#define FDS_HEADER_SIZE_IC          (1) /**< Size of the IC part of the header, in 4 byte words. */
+#define FDS_HEADER_SIZE             (3) /**< Size of the whole header, in 4 byte words. */
+
+#define FDS_CMD_QUEUE_SIZE_INIT     (1)
+#define FDS_CMD_QUEUE_SIZE_WRITE    (1)
+#define FDS_CMD_QUEUE_SIZE_CLEAR    (1)
+#define FDS_CMD_QUEUE_SIZE_UPDATE   (2)
+#define FDS_CMD_QUEUE_SIZE_GC       (1)
+
+
+static uint8_t m_nested_critical;
+
+/** Macros to enable and disable application interrupts. */
+#define CRITICAL_SECTION_ENTER()    //sd_nvic_critical_region_enter(&m_nested_critical)
+#define CRITICAL_SECTION_EXIT()     //sd_nvic_critical_region_exit ( m_nested_critical)
+
+/**@brief Page types. */
+typedef enum
+{
+    FDS_PAGE_UNDEFINED, /**< Undefined page type. */
+    FDS_PAGE_ERASED,    /**< Page is erased. */
+    FDS_PAGE_VALID,     /**< Page is ready for storage. */
+    FDS_PAGE_SWAP,      /**< Page is reserved for GC. */
+    FDS_PAGE_GC         /**< Page is being garbage collected. */
+} fds_page_type_t;
+
+
+typedef enum
+{
+    FDS_OP_NONE         = 0x00, /**< No operation. */
+    FDS_OP_WRITE_TL,            /**< Write the type and length. */
+    FDS_OP_WRITE_ID,            /**< Write the record ID. */
+    FDS_OP_WRITE_CHUNK,         /**< Write the record value.  */
+    FDS_OP_WRITE_IC,            /**< Write the instance and checksum. */
+    FDS_OP_CLEAR_TL,
+    FDS_OP_CLEAR_INSTANCE,
+    FDS_OP_DONE,
+} fds_opcode_t;
+
+
+typedef enum
+{
+    FDS_FLAG_INITIALIZING       = (1 << 0),  /**< TODO: Not really needed atm? */
+    FDS_FLAG_INITIALIZED        = (1 << 1),  /**< Flag indicating that flash data storage has been initialized. */
+    FDS_FLAG_PROCESSING         = (1 << 2),  /**< Flag indicating that queue is being processed. */
+    FDS_FLAG_CAN_GC             = (1 << 3),  /**< Flag indicating that fds can regain data by performing garbage collection. */
+} fds_flags_t;
+
+
+typedef struct
+{
+    uint32_t const    * start_addr;
+    uint16_t            vpage_id;             /**< The page logical ID. */
+    uint16_t volatile   write_offset;         /**< The page write offset, in 4 bytes words. */
+    uint16_t volatile   words_reserved;       /**< The amount of words reserved by fds_write_reserve() on this page. */
+    uint16_t volatile   records_open;
+    fds_page_type_t     page_type        : 4; /**< The page type. */
+} fds_page_t;
+
+
+typedef struct
+{
+    fds_cmd_id_t        id            : 4;    /**< The ID of the command. */
+    fds_opcode_t        op_code       : 4;
+    uint8_t             num_chunks;           /**< Number of operations this command has left in the operation queue. */
+    uint16_t            chunk_offset;         /**< Offset used for writing the record value(s), in 4 byte words. */
+    uint16_t            vpage_id;             /**< The virtual page ID where we reserved the flash space for this command. */
+    fds_record_header_t record_header;
+} fds_cmd_t;
+
+
+/**@brief   Defines command queue, an element is free if the op_code field is not invalid.
+ *
+ * @details Defines commands enqueued for flash access. At any point in time, this queue has one or
+ *          more flash access operations pending if the count field is not zero. When the queue is
+ *          not empty, the rp (read pointer) field points to the flash access command in progress
+ *          or, if none is in progress, the command to be requested next. The queue implements a
+ *          simple first in first out algorithm. Data addresses are assumed to be resident. 
+ */
+typedef struct
+{
+    fds_cmd_t          cmd[FDS_CMD_QUEUE_SIZE];        /**< Array to maintain flash access operation details. */
+    uint8_t   volatile rp;                             /**< The index of the command being executed. */
+    uint8_t   volatile count;                          /**< Number of elements in the queue. */
+} fds_cmd_queue_t;
+
+
+typedef struct
+{
+    fds_record_chunk_t          chunk[FDS_CHUNK_QUEUE_SIZE];
+    uint8_t            volatile rp;
+    uint8_t            volatile count;
+} fds_chunk_queue_t;
+
+
+typedef enum
+{
+    NONE,
+    BEGIN,
+    RESUME,
+    GC_PAGE,
+    COPY_RECORD,
+    READY_SWAP,
+    NEW_SWAP,
+    INIT_SWAP
+} fds_gc_state_t;
+
+
+typedef struct
+{
+    uint16_t         cur_page;
+    uint16_t         swap_page;
+    uint32_t const * p_scan_addr;
+    fds_gc_state_t   state;
+    bool             do_gc_page[FDS_MAX_PAGES];
+} fds_gc_data_t;
+
+#endif // FDS_TYPES_INTERNAL__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "fstorage.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include "fstorage_config.h"
+#include "nrf_error.h"
+#include "nrf_soc.h"
+
+
+#define FS_FLAG_INIT                (1 << 0)    /**< fstorage has been initialized. */
+#define FS_FLAG_PROCESSING          (1 << 1)    /**< fstorage is executing queued flash operations. */
+#define FS_FLAG_FLASH_REQ_PENDING   (1 << 2)    /**< fstorage is waiting for a flash operation initiated by another module to complete. */
+
+
+/**@brief Macro invocation that registers section fs_data.
+ *
+ * @details Required for compilation.
+ */
+NRF_SECTION_VARS_REGISTER_SECTION(fs_data);
+
+
+/**@brief Macro invocation that declares symbols used to find the beginning and end of the section fs_data.
+ *
+ * @details Required for compilation.
+ */
+NRF_SECTION_VARS_REGISTER_SYMBOLS(fs_config_t, fs_data);
+
+
+/**@defgroup Section vars helper macros.
+ *
+ * @details Macros used to manipulate registered section variables.
+ */
+ /**@brief Get section variable with fstorage configuration by index. */
+#define FS_SECTION_VARS_GET(i)          NRF_SECTION_VARS_GET(i, fs_config_t, fs_data)
+ /**@brief Get the number of registered section variables. */
+#define FS_SECTION_VARS_COUNT           NRF_SECTION_VARS_COUNT(fs_config_t, fs_data)
+ /**@brief Get the start address of the registered section variables. */
+#define FS_SECTION_VARS_START_ADDR      NRF_SECTION_VARS_START_ADDR(fs_data)
+ /**@brief Get the end address of the registered section variables. */
+#define FS_SECTION_VARS_END_ADDR        NRF_SECTION_VARS_END_ADDR(fs_data)
+
+/** @} */
+
+
+/**@brief The command queue element.
+ *
+ * @details Encapsulate details of a command requested to this module.
+ */
+typedef struct
+{
+    fs_config_t const * p_config;           /**< The configuration of the user who requested the operation. */
+    uint8_t             op_code;            /**< Operation code. */
+    uint32_t const *    p_src;              /**< Pointer to the data to be written to flash. The data must be kept in memory until the operation has finished. */
+    uint32_t const *    p_addr;             /**< Destination of the data in flash. */
+    fs_length_t         length_words;       /**< Length of the operation */
+    fs_length_t         offset;             /**< Offset of the operation if operation is done in chunks */
+} fs_cmd_t;
+
+
+/**@brief Structure that defines the command queue
+ *
+ * @details This queue holds flash operations requested to the module. 
+ *          The data to be written must be kept in memory until the write operation is completed,
+ *          i.e., a callback indicating completion is received by the application.
+ */
+typedef struct
+{
+    uint8_t     rp;                         /**< The current element being processed. */
+    uint8_t     count;                      /**< Number of elements in the queue. */
+    fs_cmd_t    cmd[FS_CMD_QUEUE_SIZE];     /**< Array to maintain flash access operation details. */
+} fs_cmd_queue_t;
+
+
+static uint8_t          m_flags;            /**< FStorage status flags. */
+static fs_cmd_queue_t   m_cmd_queue;        /**< Flash operation request queue. */
+static uint16_t         m_retry_count = 0;  /**< Number of times a single flash operation was retried. */
+
+
+// Function prototypes
+static ret_code_t queue_process(void);
+static ret_code_t queue_process_impl(void);
+static void app_notify(uint32_t result, fs_cmd_t const * p_cmd);
+
+
+/**@brief Macro to check that the configuration is non-NULL and within
+*         valid section variable memory bounds.
+ *
+ * @param[in]   config    Configuration to check.
+ */
+#define FS_CHECK_CONFIG(config) \
+    ((FS_SECTION_VARS_START_ADDR < config) && (config < FS_SECTION_VARS_END_ADDR))
+
+
+/**@brief Function to check that the configuration is non-NULL and within
+*         valid section variable memory bounds.
+ *
+ * @param[in]   config    Configuration to check.
+ */
+static bool check_config(fs_config_t const * const config)
+{
+    if (config == NULL)
+    {
+        return false;
+    }
+
+    if ((FS_SECTION_VARS_START_ADDR <= (uint32_t)config) && ((uint32_t)config < FS_SECTION_VARS_END_ADDR))
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+/**@brief Function to initialize the queue. */
+static void queue_init(void)
+{
+    memset(&m_cmd_queue, 0, sizeof(fs_cmd_queue_t));
+}
+
+
+/**@brief Function to reset a queue item to its default values.
+ *
+ * @param	index	Index of the queue element.
+ */
+static void cmd_reset(uint32_t index)
+{
+    memset(&m_cmd_queue.cmd[index], 0, sizeof(fs_cmd_t));
+}
+
+
+/**@brief Function to enqueue flash access command
+ *
+ * @param[in]   config      Registered configuration.
+ * @param[in]   op_code     Operation code.
+ * @param[in]   address     Destination of the data.
+ * @param[in]   p_src       Source of data or NULL if n/a.
+ * @param[in]   length      Length of the data, in 4 byte words.
+ *
+ * @retval NRF_SUCCESS      Success. Command enqueued.
+ * @retval NRF_ERROR_NO_MEM Error. Queue is full.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+static ret_code_t cmd_enqueue(fs_config_t      const * p_config,
+                              uint8_t                  op_code,
+                              uint32_t         const * p_addr,
+                              uint32_t         const * p_src,
+                              fs_length_t              length_words)
+{
+    fs_cmd_t * p_cmd;
+    uint8_t    write_pos;
+
+    if (m_cmd_queue.count == FS_CMD_QUEUE_SIZE - 1)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    write_pos = (m_cmd_queue.rp + m_cmd_queue.count) % FS_CMD_QUEUE_SIZE;
+
+    p_cmd = &m_cmd_queue.cmd[write_pos];
+
+    p_cmd->p_config     = p_config;
+    p_cmd->op_code      = op_code;
+    p_cmd->p_src        = p_src;
+    p_cmd->p_addr       = p_addr;
+    p_cmd->length_words = length_words;
+
+    m_cmd_queue.count++;
+
+    return queue_process();
+}
+
+
+/**@brief Function to consume queue item and notify the return value of the operation.
+ *
+ * @details This function will report the result and remove the command from the queue after
+ *          notification.
+ */
+static void cmd_consume(uint32_t result, const fs_cmd_t * p_cmd)
+{
+    // Consume the current item on the queue.
+    uint8_t rp = m_cmd_queue.rp;
+
+    m_cmd_queue.count--;
+    if (m_cmd_queue.count == 0)
+    {
+        // There are no elements left. Stop processing the queue.
+        m_flags &= ~FS_FLAG_PROCESSING;
+    }
+
+    if (++(m_cmd_queue.rp) == FS_CMD_QUEUE_SIZE)
+    {
+        m_cmd_queue.rp = 0;
+    }
+
+    // Notify upon successful operation.
+    app_notify(result, p_cmd);
+
+    // Reset the queue element.
+    cmd_reset(rp);
+}
+
+
+/**@brief Function to store data to flash.
+ *
+ * @param[in]   p_cmd   The queue element associated with the operation.
+ *
+ * @retval NRF_SUCCESS  Success. The request was sent to the SoftDevice.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+static __INLINE uint32_t store_execute(fs_cmd_t const * const p_cmd)
+{
+    // Write in chunks if write-size is larger than FS_MAX_WRITE_SIZE.
+    fs_length_t const length = ((p_cmd->length_words - p_cmd->offset) < FS_MAX_WRITE_SIZE_WORDS) ?
+        (p_cmd->length_words - p_cmd->offset) : FS_MAX_WRITE_SIZE_WORDS;
+
+    return sd_flash_write((uint32_t*)p_cmd->p_addr + p_cmd->offset /* destination */,
+                          (uint32_t*)p_cmd->p_src + p_cmd->offset  /* source */,
+                          length);
+}
+
+
+/**@brief Function to erase a page.
+ *
+ * @param[in]   p_cmd   The queue element associated with the operation.
+ *
+ * @retval NRF_SUCCESS  Success. The request was sent to the SoftDevice.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+static __INLINE uint32_t erase_execute(fs_cmd_t const * const p_cmd)
+{
+    // Erase the page.
+    return sd_flash_page_erase((uint32_t)(p_cmd->p_addr + p_cmd->offset) / FS_PAGE_SIZE);
+}
+
+
+/**@brief Function to process the current element in the queue and return the result.
+ *
+ * @retval NRF_SUCCESS          Success.
+ * @retval NRF_ERROR_FORBIDDEN  Error. Undefined command.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+static uint32_t queue_process_impl(void)
+{
+    uint32_t ret;
+    
+    fs_cmd_t const * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+
+    switch (p_cmd->op_code)
+    {
+        case FS_OP_STORE:
+            ret = store_execute(p_cmd);
+            break;
+
+        case FS_OP_ERASE:
+            ret = erase_execute(p_cmd);
+            break;
+
+        case FS_OP_NONE:
+            ret = NRF_SUCCESS;
+            break;
+
+        default:
+            ret = NRF_ERROR_FORBIDDEN;
+            break;
+    }
+
+    return ret;
+}
+
+
+/**@brief Starts processing the queue if there are no pending flash operations
+ *        for which we are awaiting a callback.
+ */
+static ret_code_t queue_process(void)
+{
+    ret_code_t ret = NRF_SUCCESS;
+
+    /** If the queue is not being processed, and there are still
+     *  some elements in it, then start processing. */
+    if ( !(m_flags & FS_FLAG_PROCESSING) &&
+          (m_cmd_queue.count > 0))
+    {
+        m_flags |= FS_FLAG_PROCESSING;
+
+        ret = queue_process_impl();
+
+        /** There is ongoing flash-operation which was not
+         *  initiated by fstorage. */
+        if (ret == NRF_ERROR_BUSY)
+        {
+            // Wait for a system callback.
+            m_flags |= FS_FLAG_FLASH_REQ_PENDING;
+
+            // Stop processing the queue.
+            m_flags &= ~FS_FLAG_PROCESSING;
+
+            ret = NRF_SUCCESS;
+        }
+        else if (ret != NRF_SUCCESS)
+        {
+            // Another error has occurred.
+            app_notify(ret, &m_cmd_queue.cmd[m_cmd_queue.rp]);
+        }
+    }
+
+    // If we are already processing the queue, return immediately.
+    return ret;
+}
+
+
+/**@brief Flash operation success callback handler.
+ *
+ * @details     This function updates read/write pointers.
+ *              This function resets retry count.
+ */
+static __INLINE void on_operation_success(void)
+{
+    fs_cmd_t * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+
+    m_retry_count = 0;
+
+    switch (p_cmd->op_code)
+    {
+        case FS_OP_STORE:
+            // Update the offset on successful write.
+            p_cmd->offset += FS_MAX_WRITE_SIZE_WORDS;
+            break;
+
+        case FS_OP_ERASE:
+            // Update the offset to correspond to the page that has been erased.
+            p_cmd->offset += FS_PAGE_SIZE_WORDS;
+            break;
+    }
+
+    // If offset is equal to or larger than length, then the operation has finished.
+    if (p_cmd->offset >= p_cmd->length_words)
+    {
+        cmd_consume(NRF_SUCCESS, p_cmd);
+    }
+
+    queue_process();
+}
+
+
+/**@brief Flash operation failure callback handler.
+ *
+ * @details Function to keep track of retries and notify failures.
+ */
+static __INLINE void on_operation_failure(uint32_t sys_evt)
+{
+    const fs_cmd_t * p_cmd;
+    
+    if (++m_retry_count > FS_CMD_MAX_RETRIES)
+    {
+        p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
+        cmd_consume(NRF_ERROR_TIMEOUT, p_cmd);
+    }
+
+    queue_process();
+}
+
+
+/**@brief Function to notify users.
+ *
+ * @param[in]   result      Result of the flash operation.
+ * @param[in]   p_cmd       The command associated with the callback.
+ */
+static void app_notify(uint32_t result, fs_cmd_t const * const p_cmd)
+{
+    p_cmd->p_config->cb(p_cmd->op_code, result, p_cmd->p_addr, p_cmd->length_words);
+}
+
+
+ret_code_t fs_init(void)
+{
+    uint16_t   lowest_index = 0;
+    uint16_t   lowest_order = 0xFFFF;
+    uint32_t * current_end  = (uint32_t*)FS_PAGE_END_ADDR;
+    uint32_t   num_left     = FS_SECTION_VARS_COUNT;
+
+    queue_init();
+
+    /** Assign pages to registered users, beginning with the ones with the lowest
+     *  order, which will be assigned pages with the lowest memory address. */
+    do
+    {
+        fs_config_t * p_config;
+        for (uint16_t i = 0; i < FS_SECTION_VARS_COUNT; i++)
+        {
+            p_config = FS_SECTION_VARS_GET(i);
+
+            // Skip the ones which have the end-address already set.
+            if (p_config->p_end_addr != NULL)
+                continue;
+
+            if (p_config->page_order < lowest_order)
+            {
+                lowest_order = p_config->page_order;
+                lowest_index = i;
+            }
+        }
+
+        p_config = FS_SECTION_VARS_GET(lowest_index);
+
+        p_config->p_end_addr   = current_end;
+        p_config->p_start_addr = p_config->p_end_addr - (p_config->num_pages * FS_PAGE_SIZE_WORDS);
+
+        current_end  = p_config->p_start_addr;
+        lowest_order = 0xFFFF;
+
+    } while ( --num_left > 0 );
+
+    m_flags |= FS_FLAG_INIT;
+
+    return NRF_SUCCESS;
+}
+
+
+ret_code_t fs_store(fs_config_t const *       p_config,
+                    uint32_t    const *       p_addr,
+                    uint32_t    const * const p_data,
+                    fs_length_t               length_words)
+{
+    if ((m_flags & FS_FLAG_INIT) == 0)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if (!check_config(p_config))
+    {
+        return NRF_ERROR_FORBIDDEN;
+    }
+
+    if (!is_word_aligned(p_addr))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    // Check that the erase operation is on pages owned by this user (configuration).
+    if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    return cmd_enqueue(p_config, FS_OP_STORE, p_addr, p_data, length_words);
+}
+
+
+ret_code_t fs_erase(fs_config_t const *       p_config,
+                    uint32_t          * const p_addr,
+                    fs_length_t const         length_words)
+{
+    if ((m_flags & FS_FLAG_INIT) == 0)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    if (!check_config(p_config))
+    {
+        return NRF_ERROR_FORBIDDEN;
+    }
+
+    /** Check that the address is aligned on a page boundary and the length to erase
+     *  is a multiple of the page size. */
+    if (((uint32_t)p_addr & (FS_PAGE_SIZE - 1)) ||
+        (length_words     & (FS_PAGE_SIZE_WORDS - 1)))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    // Check that the erase operation is on pages owned by this user (configuration).
+    if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr))
+    {
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    return cmd_enqueue(p_config, FS_OP_ERASE, p_addr, NULL, length_words);
+}
+
+
+/**@brief Function to handle system events from the SoftDevice.
+ *
+ * @details     This function should be dispatched system events if any of the modules used by
+ *              the application rely on FStorage. Examples include @ref Peer Manager and
+ *              @ref Flash Data Storage.
+ *
+ * @param[in]   sys_evt     System Event received.
+ */
+void fs_sys_event_handler(uint32_t sys_evt)
+{
+    if (m_flags & FS_FLAG_PROCESSING)
+    {
+        /** A flash operation was initiated by this module.
+         *  Handle its result. */
+        switch (sys_evt)
+        {
+            case NRF_EVT_FLASH_OPERATION_SUCCESS:
+                on_operation_success();
+                break;
+
+            case NRF_EVT_FLASH_OPERATION_ERROR:
+                on_operation_failure(sys_evt);
+                break;
+        }
+    }
+    else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING))
+    {
+        /** A flash operation was initiated outside this module.
+         *  We have now receveid a callback which indicates it has
+         *  finished. Clear the FS_FLAG_FLASH_REQ_PENDING flag. */
+         m_flags &= ~FS_FLAG_FLASH_REQ_PENDING;
+
+         // Resume processing the queue, if necessary.
+         queue_process();
+    }
+}
+
+
+// Just for testing out section vars (across many compilers).
+void fs_debug_print()
+{
+    printf("fs start address: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_START_ADDR);
+    printf("fs end address: 0x%08lx\r\n",   (unsigned long)FS_SECTION_VARS_END_ADDR);
+    printf("Num items: 0x%08lx\r\n",        (unsigned long)FS_SECTION_VARS_COUNT);
+    printf("===== ITEMS %lu =====\r\n",     (unsigned long)FS_SECTION_VARS_COUNT);
+
+    for(int i = 0; i < FS_SECTION_VARS_COUNT; i++)
+    {
+        fs_config_t* config = FS_SECTION_VARS_GET(i);
+        printf( "Address: 0x%08lx, CB: 0x%08lx\r\n",
+                (unsigned long)config, (unsigned long)config->cb );
+    }
+    printf("\r\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 FS_H__
+#define FS_H__
+
+ /** @file
+ *
+ * @defgroup fstorage FStorage
+ * @{
+ * @ingroup app_common
+ * @brief Module which provides low level functionality to store data to flash.
+ *
+ */
+
+
+#include <stdint.h>
+#include "section_vars.h"
+#include "fstorage_config.h"
+#include "sdk_errors.h"
+
+
+typedef uint16_t fs_length_t;
+
+
+typedef enum
+{
+    FS_OP_NONE          = 0,
+    FS_OP_STORE         = 1,
+    FS_OP_ERASE         = 2
+} fs_oper_t;
+
+
+/**@brief Callback for flash operations.
+ *
+ * @param[in]   op_code         Flash access operation code.
+ * @param[in]   result          Result of the operation.
+ * @param[in]   data            Pointer to resulting data (or NULL if not in use).
+ * @param[in]   length_words    Length of data in words.
+ */
+typedef void (*fs_cb_t)(uint8_t             op_code,
+                        uint32_t            result,
+                        uint32_t    const * p_data,
+                        fs_length_t         length_words);
+
+
+/**@brief Function prototype for a callback handler.
+ *
+ * @details This function is expected to be implemented by the module that 
+ *          registers for fstorage usage. Its usage is described
+ *          in the function pointer type fs_cb_t.
+ *
+ * @param[in]   op_code         Flash operation code.
+ * @param[in]   result          Result of the flash operation.
+ * @param[in]   p_data          Pointer to the resulting data (or NULL if not in use).
+ * @param[in]   length_words    Length of data in words.
+ */
+static void fs_callback(uint8_t             op_code,
+                        uint32_t            result,
+                        uint32_t    const * p_data,
+                        fs_length_t         length_words);
+
+
+/**@brief Flash storage config variable.
+ *
+ * @details     The fstorage module will update the start_addr and end_address according to 
+ *              ordering rules and the number of pages requested by the fstorage module user.
+ */
+typedef struct
+{
+    const fs_cb_t   cb;               /**< Callback to run when flash operation has completed. */
+    const uint8_t   num_pages;        /**< The number of pages to reserve for flash storage. */
+    const uint8_t   page_order;       /**< The order used to allocate pages. */
+    uint32_t      * p_start_addr;     /**< Pointer to the start address of the allocated flash storage. Set by running @ref fs_init. */
+    uint32_t *      p_end_addr;       /**< Pointer to the end address of the allcoated flash storage. Set by running @ref fs_init. */
+} fs_config_t;
+
+
+/**@brief Macro for registering of flash storage configuration variable.
+ *
+ * @details This macro is expected to be invoked in the code unit that that require
+ *          flash storage. Invoking this places the registered configuration variable
+ *          in a section named "fs_data" that the fstorage module uses during initialization
+ *          and regular operation.
+ */
+#define FS_SECTION_VARS_ADD(type_def) NRF_SECTION_VARS_ADD(fs_data, type_def)
+
+
+/**@brief Function to initialize FStorage.
+ *
+ * @details     This function allocates flash data pages according to the
+ *              number requested in the config variable. The data used to initialize.
+ *              the fstorage is section placed variables in the data section "fs_data".
+ */
+ret_code_t fs_init(void);
+
+
+/**@brief Function to store data in flash.
+ *
+ * @warning The data to be written to flash has to be kept in memory until the operation has
+ *          terminated, i.e., a callback is received.
+ *
+ * @param[in]   p_config        Const pointer to configiguration of module user that requests a store operation.
+ * @param[in]   p_addr          Write address of store operation.
+ * @param[in]   p_data          Pointer to the data to store.
+ * @param[in]   length_words    Length of the data to store.
+ *
+ * @retval NRF_SUCCESS                  Success. Command queued.
+ * @retval NRF_ERROR_INVALID_STATE      Error. The module is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR       Error. Data is unaligned or invalid configuration.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+ret_code_t fs_store(fs_config_t const *       p_config,
+                    uint32_t    const *       p_addr,
+                    uint32_t    const * const p_data,
+                    fs_length_t               length_words);
+
+
+/** Function to erase a page in flash.
+ *
+ * @note        The erase address must be aligned on a page boundary. The length in words must be 
+ *              equivalent to the page size.
+ *
+ * @param[in]   p_config        Pointer to the configuration of the user that requests the operation.
+ * @param[in]   p_addr          Address of page to erase (the same as first word in the page).
+ * @param[in]   length_words    Length (in 4 byte words) of the area to erase.
+ *
+ * @retval NRF_SUCCESS                  Success. Command queued.
+ * @retval NRF_ERROR_INVALID_STATE      Error. The module is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR       Error. Data is unaligned or invalid configuration.
+ * @retval Any error returned by the SoftDevice flash API.
+ */
+ret_code_t fs_erase(fs_config_t const *       p_config,
+                    uint32_t          * const p_addr,
+                    fs_length_t               length_words);
+
+
+/**@brief Function to call to handle events from the SoftDevice
+ *
+ * @param   sys_evt     System event from the SoftDevice
+ */
+void fs_sys_event_handler(uint32_t sys_evt);
+
+/** @} */
+
+#endif // FS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage_config.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 FS_CONFIG_H__
+#define FS_CONFIG_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+/**
+ * @defgroup fstorage_config FStorage configuration
+ * @ingroup fstorage
+ * @{
+ * @brief FStorage configuration.
+ */
+
+
+/**@brief Macro for max number of operations in the fs cmd queue.
+ */
+#define FS_CMD_QUEUE_SIZE   (8)
+
+
+/**@brief Macro for max number of retries for a flash command before it notifies as failed.
+ */
+#define FS_CMD_MAX_RETRIES  (3)
+
+
+/**@brief Macro for the content of a flash address that has not been written to.
+ */
+#define FS_EMPTY_MASK       (0xFFFFFFFF)
+
+
+/**@brief Macro for flash page size according to chip family
+ */
+#if defined (NRF51)
+    #define FS_PAGE_SIZE    (1024)
+#elif defined (NRF52)
+    #define FS_PAGE_SIZE    (4096)
+#else
+    #error "Device family must be defined. See nrf.h."
+#endif
+
+
+/*@brief Macro for flash page size according to chip family
+*/
+#define FS_PAGE_SIZE_WORDS  (FS_PAGE_SIZE/4)
+
+
+/**@brief Static inline function that provides last page address
+ *
+ * @note    If there is a bootloader present the bootloader address read from UICR
+ *          will act as the page beyond the end of the available flash storage
+ */
+static __INLINE uint32_t fs_flash_page_end_addr()
+{
+    uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
+    return  ((bootloader_addr != FS_EMPTY_MASK) ?
+             bootloader_addr : NRF_FICR->CODESIZE * FS_PAGE_SIZE);
+}
+
+
+/**@brief Macro for last page address
+ *
+ * @note    If there is a bootloader present the bootloader address read from UICR
+ *          will act as the page beyond the end of the available flash storage
+ */
+#define FS_PAGE_END_ADDR  fs_flash_page_end_addr()
+
+
+/**@brief Macro to describe the write
+ *
+ */
+#if defined (NRF51)
+    #define FS_MAX_WRITE_SIZE_WORDS	    (256)
+#elif defined (NRF52)
+    #define FS_MAX_WRITE_SIZE_WORDS     (1024)
+#else
+    #error "Device family must be defined. see nrf.h"
+#endif
+
+/** @} */
+
+#endif // FS_CONFIG_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/fstorage/fstorage_nosd.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/hci/hci_mem_pool.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "hci_mem_pool.h"
+#include "hci_mem_pool_internal.h"
+#include <stdbool.h>
+#include <stdio.h>
+
+/**@brief RX buffer element instance structure. 
+ */
+typedef struct 
+{
+    uint8_t  rx_buffer[RX_BUF_SIZE];                                /**< RX buffer memory array. */  
+    uint32_t length;                                                /**< Length of the RX buffer memory array. */
+} rx_buffer_elem_t;
+
+/**@brief RX buffer queue element instance structure. 
+ */
+typedef struct 
+{
+    rx_buffer_elem_t * p_buffer;                                    /**< Pointer to RX buffer element. */
+    uint32_t           free_window_count;                           /**< Free space element count. */
+    uint32_t           free_available_count;                        /**< Free area element count. */
+    uint32_t           read_available_count;                        /**< Read area element count. */
+    uint32_t           write_index;                                 /**< Write position index. */                                      
+    uint32_t           read_index;                                  /**< Read position index. */                                                                            
+    uint32_t           free_index;                                  /**< Free position index. */                                                                                                                  
+} rx_buffer_queue_t;
+
+static bool              m_is_tx_allocated;                         /**< Boolean value to determine if the TX buffer is allocated. */
+static rx_buffer_elem_t  m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
+static rx_buffer_queue_t m_rx_buffer_queue;                         /**< RX buffer queue element instance. */
+
+
+uint32_t hci_mem_pool_open(void)
+{
+    m_is_tx_allocated                      = false;    
+    m_rx_buffer_queue.p_buffer             = m_rx_buffer_elem_queue;
+    m_rx_buffer_queue.free_window_count    = RX_BUF_QUEUE_SIZE;
+    m_rx_buffer_queue.free_available_count = 0;
+    m_rx_buffer_queue.read_available_count = 0;
+    m_rx_buffer_queue.write_index          = 0;    
+    m_rx_buffer_queue.read_index           = 0;        
+    m_rx_buffer_queue.free_index           = 0;            
+    
+    return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_close(void)
+{    
+    return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
+{
+    static uint8_t tx_buffer[TX_BUF_SIZE];  
+
+    uint32_t err_code;
+    
+    if (pp_buffer == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+    
+    if (!m_is_tx_allocated)
+    {        
+            m_is_tx_allocated = true;
+            *pp_buffer        = tx_buffer;
+            err_code          = NRF_SUCCESS;
+    }
+    else
+    {
+        err_code              = NRF_ERROR_NO_MEM;
+    }
+    
+    return err_code;
+}
+
+
+uint32_t hci_mem_pool_tx_free(void)
+{
+    m_is_tx_allocated = false;
+    
+    return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
+{
+    uint32_t err_code; 
+
+    if (pp_buffer == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }    
+    *pp_buffer = NULL;
+    
+    if (m_rx_buffer_queue.free_window_count != 0)
+    {    
+        if (length <= RX_BUF_SIZE)
+        {    
+            --(m_rx_buffer_queue.free_window_count);            
+            ++(m_rx_buffer_queue.read_available_count);            
+
+            *pp_buffer                    = 
+                    m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
+
+            m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
+
+            // @note: Adjust the write_index making use of the fact that the buffer size is of 
+            // power of two and two's complement arithmetic. For details refer example to book 
+            // "Making embedded systems: Elicia White".
+            m_rx_buffer_queue.write_index = 
+                    (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
+            
+            err_code                      = NRF_SUCCESS;
+        }
+        else
+        {
+            err_code = NRF_ERROR_DATA_SIZE;    
+        }        
+    }
+    else
+    {
+        err_code = NRF_ERROR_NO_MEM;    
+    }
+    
+    return err_code;
+}
+
+
+uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
+{
+    uint32_t err_code;
+    uint32_t consume_index;
+    uint32_t start_index;
+    
+    if (m_rx_buffer_queue.free_available_count != 0)
+    {
+        // Find the buffer that has been freed -
+        // Start at read_index minus free_available_count and then increment until read index.
+        err_code      = NRF_ERROR_INVALID_ADDR;
+        consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & 
+                        (RX_BUF_QUEUE_SIZE - 1u);
+        start_index   = consume_index;
+        
+        do
+        {
+            if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
+            {
+                m_rx_buffer_queue.free_index ^= (1u << consume_index);
+                err_code = NRF_SUCCESS;
+                break;
+            }
+            else
+            {
+                consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
+            }
+        }
+        while (consume_index != m_rx_buffer_queue.read_index);
+
+        while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && 
+                (m_rx_buffer_queue.free_available_count != 0))
+        {
+            --(m_rx_buffer_queue.free_available_count);
+            ++(m_rx_buffer_queue.free_window_count);            
+            start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
+        }
+    }
+    else
+    {
+        err_code = NRF_ERROR_NO_MEM;
+    }
+        
+    return err_code;    
+}
+
+
+uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
+{
+    // @note: Adjust the write_index making use of the fact that the buffer size is of power
+    // of two and two's complement arithmetic. For details refer example to book 
+    // "Making embedded systems: Elicia White".
+    const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u);
+    m_rx_buffer_queue.p_buffer[index].length = length;    
+    
+    return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
+{
+    uint32_t err_code;
+    
+    if ((pp_buffer == NULL) || (p_length == NULL))
+    {
+        return NRF_ERROR_NULL;
+    }
+    
+    if (m_rx_buffer_queue.read_available_count != 0)
+    {
+        --(m_rx_buffer_queue.read_available_count);
+        ++(m_rx_buffer_queue.free_available_count);        
+        
+        *pp_buffer                   = 
+            m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
+        *p_length                    = 
+            m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
+        
+        // @note: Adjust the write_index making use of the fact that the buffer size is of power
+        // of two and two's complement arithmetic. For details refer example to book 
+        // "Making embedded systems: Elicia White".            
+        m_rx_buffer_queue.read_index = 
+            (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 
+        
+        err_code                     = NRF_SUCCESS;
+    }
+    else
+    {
+        err_code                     = NRF_ERROR_NO_MEM;        
+    }
+    
+    return err_code;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/hci/hci_mem_pool.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 memory_pool Memory pool
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Memory pool implementation
+ *
+ * Memory pool implementation, based on circular buffer data structure, which supports asynchronous 
+ * processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers.
+ * The memory managed by the pool is allocated from static storage instead of heap. The internal 
+ * design of the circular buffer implementing the RX memory layout is illustrated in the picture 
+ * below. 
+ *
+ * @image html memory_pool.png "Circular buffer design"
+ *
+ * The expected call order for the RX APIs is as follows:
+ * - hci_mem_pool_rx_produce
+ * - hci_mem_pool_rx_data_size_set
+ * - hci_mem_pool_rx_extract
+ * - hci_mem_pool_rx_consume
+ *
+ * @warning If the above mentioned expected call order is violated the end result can be undefined.
+ *
+ * \par Component specific configuration options
+ *
+ * The following compile time configuration options are available to suit various implementations:
+ * - TX_BUF_SIZE TX buffer size in bytes. 
+ * - RX_BUF_SIZE RX buffer size in bytes. 
+ * - RX_BUF_QUEUE_SIZE RX buffer element size.
+ */
+ 
+#ifndef HCI_MEM_POOL_H__
+#define HCI_MEM_POOL_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+/**@brief Function for opening the module.
+ *
+ * @retval NRF_SUCCESS          Operation success. 
+ */
+uint32_t hci_mem_pool_open(void);
+
+/**@brief Function for closing the module.
+ *
+ * @retval NRF_SUCCESS          Operation success. 
+ */
+uint32_t hci_mem_pool_close(void);
+
+/**@brief Function for allocating requested amount of TX memory.
+ *
+ * @param[out] pp_buffer        Pointer to the allocated memory.
+ *
+ * @retval NRF_SUCCESS          Operation success. Memory was allocated.
+ * @retval NRF_ERROR_NO_MEM     Operation failure. No memory available for allocation.
+ * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.  
+ */
+uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer);
+ 
+/**@brief Function for freeing previously allocated TX memory.
+ *
+ * @note Memory management follows the FIFO principle meaning that free() order must match the 
+ *       alloc(...) order, which is the reason for omitting exact memory block identifier as an 
+ *       input parameter.
+ *
+ * @retval NRF_SUCCESS          Operation success. Memory was freed.
+ */
+uint32_t hci_mem_pool_tx_free(void);
+ 
+/**@brief Function for producing a free RX memory block for usage.
+ *
+ * @note Upon produce request amount being 0, NRF_SUCCESS is returned.   
+ *
+ * @param[in]  length           Amount, in bytes, of free memory to be produced.
+ * @param[out] pp_buffer        Pointer to the allocated memory.
+ *
+ * @retval NRF_SUCCESS          Operation success. Free RX memory block produced.
+ * @retval NRF_ERROR_NO_MEM     Operation failure. No suitable memory available for allocation.
+ * @retval NRF_ERROR_DATA_SIZE  Operation failure. Request size exceeds limit.  
+ * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.   
+ */
+uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer);
+
+/**@brief Function for setting the length of the last produced RX memory block.
+ *
+ * @warning If call to this API is omitted the end result is that the following call to 
+ *          mem_pool_rx_extract will return incorrect data in the p_length output parameter.
+ *
+ * @param[in]  length           Amount, in bytes, of actual memory used.
+ *
+ * @retval NRF_SUCCESS          Operation success. Length was set.
+ */
+uint32_t hci_mem_pool_rx_data_size_set(uint32_t length);
+ 
+/**@brief Function for extracting a packet, which has been filled with read data, for further 
+ * processing.
+ *
+ * @param[out] pp_buffer        Pointer to the packet data.
+ * @param[out] p_length         Length of packet data in bytes.  
+ *
+ * @retval NRF_SUCCESS          Operation success. 
+ * @retval NRF_ERROR_NO_MEM     Operation failure. No packet available to extract.
+ * @retval NRF_ERROR_NULL       Operation failure. NULL pointer supplied.    
+ */
+uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length);
+ 
+/**@brief Function for freeing previously extracted packet, which has been filled with read data.
+ *
+ * @param[in] p_buffer             Pointer to consumed buffer.
+ *
+ * @retval NRF_SUCCESS             Operation success. 
+ * @retval NRF_ERROR_NO_MEM        Operation failure. No packet available to free. 
+ * @retval NRF_ERROR_INVALID_ADDR  Operation failure. Not a valid pointer. 
+ */
+uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer);
+ 
+#endif // HCI_MEM_POOL_H__
+ 
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/scheduler/app_scheduler.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "app_scheduler.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+
+/**@brief Structure for holding a scheduled event header. */
+typedef struct
+{
+    app_sched_event_handler_t handler;          /**< Pointer to event handler to receive the event. */
+    uint16_t                  event_data_size;  /**< Size of event data. */
+} event_header_t;
+
+STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
+
+static event_header_t * m_queue_event_headers;  /**< Array for holding the queue event headers. */
+static uint8_t        * m_queue_event_data;     /**< Array for holding the queue event data. */
+static volatile uint8_t m_queue_start_index;    /**< Index of queue entry at the start of the queue. */
+static volatile uint8_t m_queue_end_index;      /**< Index of queue entry at the end of the queue. */
+static uint16_t         m_queue_event_size;     /**< Maximum event size in queue. */
+static uint16_t         m_queue_size;           /**< Number of queue entries. */
+
+/**@brief Function for incrementing a queue index, and handle wrap-around.
+ *
+ * @param[in]   index   Old index.
+ *
+ * @return      New (incremented) index.
+ */
+static __INLINE uint8_t next_index(uint8_t index)
+{
+    return (index < m_queue_size) ? (index + 1) : 0;
+}
+
+
+static __INLINE uint8_t app_sched_queue_full()
+{
+  uint8_t tmp = m_queue_start_index;
+  return next_index(m_queue_end_index) == tmp;
+}
+
+/**@brief Macro for checking if a queue is full. */
+#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
+
+
+static __INLINE uint8_t app_sched_queue_empty()
+{
+  uint8_t tmp = m_queue_start_index;
+  return m_queue_end_index == tmp;
+}
+
+/**@brief Macro for checking if a queue is empty. */
+#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
+
+
+uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
+{
+    uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);
+
+    // Check that buffer is correctly aligned
+    if (!is_word_aligned(p_event_buffer))
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    // Initialize event scheduler
+    m_queue_event_headers = p_event_buffer;
+    m_queue_event_data    = &((uint8_t *)p_event_buffer)[data_start_index];
+    m_queue_end_index     = 0;
+    m_queue_start_index   = 0;
+    m_queue_event_size    = event_size;
+    m_queue_size          = queue_size;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t app_sched_event_put(void                    * p_event_data,
+                             uint16_t                  event_data_size,
+                             app_sched_event_handler_t handler)
+{
+    uint32_t err_code;
+
+    if (event_data_size <= m_queue_event_size)
+    {
+        uint16_t event_index = 0xFFFF;
+
+        CRITICAL_REGION_ENTER();
+
+        if (!APP_SCHED_QUEUE_FULL())
+        {
+            event_index       = m_queue_end_index;
+            m_queue_end_index = next_index(m_queue_end_index);
+        }
+
+        CRITICAL_REGION_EXIT();
+
+        if (event_index != 0xFFFF)
+        {
+            // NOTE: This can be done outside the critical region since the event consumer will
+            //       always be called from the main loop, and will thus never interrupt this code.
+            m_queue_event_headers[event_index].handler = handler;
+            if ((p_event_data != NULL) && (event_data_size > 0))
+            {
+                memcpy(&m_queue_event_data[event_index * m_queue_event_size],
+                       p_event_data,
+                       event_data_size);
+                m_queue_event_headers[event_index].event_data_size = event_data_size;
+            }
+            else
+            {
+                m_queue_event_headers[event_index].event_data_size = 0;
+            }
+
+            err_code = NRF_SUCCESS;
+        }
+        else
+        {
+            err_code = NRF_ERROR_NO_MEM;
+        }
+    }
+    else
+    {
+        err_code = NRF_ERROR_INVALID_LENGTH;
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for reading the next event from specified event queue.
+ *
+ * @param[out]  pp_event_data       Pointer to pointer to event data.
+ * @param[out]  p_event_data_size   Pointer to size of event data.
+ * @param[out]  p_event_handler     Pointer to event handler function pointer.
+ *
+ * @return      NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty.
+ */
+static uint32_t app_sched_event_get(void                     ** pp_event_data,
+                                    uint16_t *                  p_event_data_size,
+                                    app_sched_event_handler_t * p_event_handler)
+{
+    uint32_t err_code = NRF_ERROR_NOT_FOUND;
+
+    if (!APP_SCHED_QUEUE_EMPTY())
+    {
+        uint16_t event_index;
+
+        // NOTE: There is no need for a critical region here, as this function will only be called
+        //       from app_sched_execute() from inside the main loop, so it will never interrupt
+        //       app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be
+        //       an atomic operation.
+        event_index         = m_queue_start_index;
+        m_queue_start_index = next_index(m_queue_start_index);
+
+        *pp_event_data     = &m_queue_event_data[event_index * m_queue_event_size];
+        *p_event_data_size = m_queue_event_headers[event_index].event_data_size;
+        *p_event_handler   = m_queue_event_headers[event_index].handler;
+
+        err_code = NRF_SUCCESS;
+    }
+
+    return err_code;
+}
+
+
+void app_sched_execute(void)
+{
+    void                    * p_event_data;
+    uint16_t                  event_data_size;
+    app_sched_event_handler_t event_handler;
+
+    // Get next event (if any), and execute handler
+    while ((app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS))
+    {
+        event_handler(p_event_data, event_data_size);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/scheduler/app_scheduler.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_scheduler Scheduler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The scheduler is used for transferring execution from the interrupt context to the main
+ *        context.
+ *
+ * @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
+ *          when using the Scheduler.
+ *
+ * @section app_scheduler_req Requirements:
+ *
+ * @subsection main_context_logic Logic in main context:
+ *
+ *   - Define an event handler for each type of event expected.
+ *   - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
+ *     application main loop.
+ *   - Call app_sched_execute() from the main loop each time the application wakes up because of an
+ *     event (typically when sd_app_evt_wait() returns).
+ *
+ * @subsection int_context_logic Logic in interrupt context:
+ *
+ *   - In the interrupt handler, call app_sched_event_put()
+ *     with the appropriate data and event handler. This will insert an event into the
+ *     scheduler's queue. The app_sched_execute() function will pull this event and call its
+ *     handler in the main context.
+ *
+ * @if (PERIPHERAL)
+ * For an example usage of the scheduler, see the implementations of
+ * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
+ * @endif
+ *
+ * @image html scheduler_working.jpg The high level design of the scheduler
+ */
+
+#ifndef APP_SCHEDULER_H__
+#define APP_SCHEDULER_H__
+
+#include <stdint.h>
+#include "app_error.h"
+#include "app_util.h"
+
+#define APP_SCHED_EVENT_HEADER_SIZE 8       /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the scheduler buffer.
+ *
+ * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
+ *                         that can be scheduled for execution).
+ *
+ * @return    Required scheduler buffer size (in bytes).
+ */
+#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE)                                                 \
+            (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
+            
+/**@brief Scheduler event handler type. */
+typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
+
+/**@brief Macro for initializing the event scheduler.
+ *
+ * @details It will also handle dimensioning and allocation of the memory buffer required by the
+ *          scheduler, making sure the buffer is correctly aligned.
+ *
+ * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
+ *                         that can be scheduled for execution).
+ *
+ * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ *       several times as long as it is from the same location, e.g. to do a reinitialization).
+ */
+#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE)                                                     \
+    do                                                                                             \
+    {                                                                                              \
+        static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)),     \
+                                               sizeof(uint32_t))];                                 \
+        uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF);             \
+        APP_ERROR_CHECK(ERR_CODE);                                                                 \
+    } while (0)
+
+/**@brief Function for initializing the Scheduler.
+ *
+ * @details It must be called before entering the main loop.
+ *
+ * @param[in]   max_event_size   Maximum size of events to be passed through the scheduler.
+ * @param[in]   queue_size       Number of entries in scheduler queue (i.e. the maximum number of
+ *                               events that can be scheduled for execution).
+ * @param[in]   p_evt_buffer   Pointer to memory buffer for holding the scheduler queue. It must
+ *                               be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
+ *                               must be aligned to a 4 byte boundary.
+ *
+ * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
+ *       allocate the scheduler buffer, and also align the buffer correctly.
+ *
+ * @retval      NRF_SUCCESS               Successful initialization.
+ * @retval      NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
+ *                                        boundary).
+ */
+uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
+
+/**@brief Function for executing all scheduled events.
+ *
+ * @details This function must be called from within the main loop. It will execute all events
+ *          scheduled since the last time it was called.
+ */
+void app_sched_execute(void);
+
+/**@brief Function for scheduling an event.
+ *
+ * @details Puts an event into the event queue.
+ *
+ * @param[in]   p_event_data   Pointer to event data to be scheduled.
+ * @param[in]   event_size   Size of event data to be scheduled.
+ * @param[in]   handler        Event handler to receive the event.
+ *
+ * @return      NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t app_sched_event_put(void *                    p_event_data,
+                             uint16_t                  event_size,
+                             app_sched_event_handler_t handler);
+
+#ifdef APP_SCHEDULER_WITH_PAUSE
+/**@brief A function to pause the scheduler.
+ *
+ * @details When the scheduler is paused events are not pulled from the scheduler queue for
+ *          processing. The function can be called multiple times. To unblock the scheduler the
+ *          function @ref app_sched_resume has to be called the same number of times.
+ */
+void app_sched_pause(void);
+
+/**@brief A function to resume a scheduler.
+ *
+ * @details To unblock the scheduler this function has to be called the same number of times as
+ *          @ref app_sched_pause function.
+ */
+void app_sched_resume(void);
+#endif
+#endif // APP_SCHEDULER_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/timer/app_timer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_timer Application Timer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Application timer functionality.
+ *
+ * @details This module enables the application to create multiple timer instances based on the RTC1
+ *          peripheral. Checking for time-outs and invokation of user time-out handlers is performed
+ *          in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0).
+ *          Both interrupt handlers are running in APP_LOW priority level.
+ *
+ * @details When calling app_timer_start() or app_timer_stop(), the timer operation is just queued,
+ *          and the software interrupt is triggered. The actual timer start/stop operation is
+ *          executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW,
+ *          if the application code calling the timer function is running in APP_LOW or APP_HIGH,
+ *          the timer operation will not be performed until the application handler has returned.
+ *          This will be the case, for example, when stopping a timer from a time-out handler when not using
+ *          the scheduler.
+ *
+ * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the
+ *          @ref app_scheduler should be used or not. Even if the scheduler is 
+ *          not used, app_timer.h will include app_scheduler.h, so when
+ *          compiling, app_scheduler.h must be available in one of the compiler include paths.
+ */
+
+#ifndef APP_TIMER_H__
+#define APP_TIMER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "app_error.h"
+#include "app_util.h"
+#include "compiler_abstraction.h"
+
+#define APP_TIMER_CLOCK_FREQ         32768                      /**< Clock frequency of the RTC timer used to implement the app timer module. */
+#define APP_TIMER_MIN_TIMEOUT_TICKS  5                          /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */
+
+#define APP_TIMER_NODE_SIZE          32                         /**< Size of app_timer.timer_node_t (used to allocate data). */
+#define APP_TIMER_USER_OP_SIZE       24                         /**< Size of app_timer.timer_user_op_t (only for use inside APP_TIMER_BUF_SIZE()). */
+#define APP_TIMER_USER_SIZE          8                          /**< Size of app_timer.timer_user_t (only for use inside APP_TIMER_BUF_SIZE()). */
+#define APP_TIMER_INT_LEVELS         3                          /**< Number of interrupt levels from where timer operations may be initiated (only for use inside APP_TIMER_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the application timer data structures.
+ *
+ * @param[in]  OP_QUEUE_SIZE   Size of queues holding timer operations that are pending execution.
+ *                             Note that due to the queue implementation, this size must be one more
+ *                             than the size that is actually needed.
+ *
+ * @return     Required application timer buffer size (in bytes).
+ */
+#define APP_TIMER_BUF_SIZE(OP_QUEUE_SIZE)                                              \
+    (                                                                                              \
+        (                                                                                          \
+            APP_TIMER_INT_LEVELS                                                                   \
+            *                                                                                      \
+            (APP_TIMER_USER_SIZE + ((OP_QUEUE_SIZE) + 1) * APP_TIMER_USER_OP_SIZE)                 \
+        )                                                                                          \
+    )
+
+/**@brief Convert milliseconds to timer ticks.
+ *
+ * This macro uses 64-bit integer arithmetic, but as long as the macro parameters are
+ *       constants (i.e. defines), the computation will be done by the preprocessor.
+ * 
+ * When using this macro, ensure that the 
+ *         values provided as input result in an output value that is supported by the
+ *         @ref app_timer_start function. For example, when the ticks for 1 ms is needed, the
+ *         maximum possible value of PRESCALER must be 6, when @ref APP_TIMER_CLOCK_FREQ is 32768.
+ *         This will result in a ticks value as 5. Any higher value for PRESCALER will result in a
+ *         ticks value that is not supported by this module.
+ *
+ * @param[in]  MS          Milliseconds.
+ * @param[in]  PRESCALER   Value of the RTC1 PRESCALER register (must be the same value that was
+ *                         passed to APP_TIMER_INIT()). 
+ *
+ * @return     Number of timer ticks.
+ */
+#define APP_TIMER_TICKS(MS, PRESCALER)\
+            ((uint32_t)ROUNDED_DIV((MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, ((PRESCALER) + 1) * 1000))
+
+typedef struct app_timer_t { uint32_t data[CEIL_DIV(APP_TIMER_NODE_SIZE, sizeof(uint32_t))]; } app_timer_t;
+
+/**@brief Timer ID type.
+ * Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
+typedef app_timer_t * app_timer_id_t;
+
+/**
+ * @brief Create a timer identifier and statically allocate memory for the timer.
+ *
+ * @param timer_id Name of the timer identifier variable that will be used to control the timer.
+ */
+#define APP_TIMER_DEF(timer_id)                                  \
+    static app_timer_t timer_id##_data = { {0} };                  \
+    static const app_timer_id_t timer_id = &timer_id##_data
+
+
+/**@brief Application time-out handler type. */
+typedef void (*app_timer_timeout_handler_t)(void * p_context);
+
+/**@brief Type of function for passing events from the timer module to the scheduler. */
+typedef uint32_t (*app_timer_evt_schedule_func_t) (app_timer_timeout_handler_t timeout_handler,
+                                                   void *                      p_context);
+
+/**@brief Timer modes. */
+typedef enum
+{
+    APP_TIMER_MODE_SINGLE_SHOT,                 /**< The timer will expire only once. */
+    APP_TIMER_MODE_REPEATED                     /**< The timer will restart each time it expires. */
+} app_timer_mode_t;
+
+/**@brief Initialize the application timer module.
+ *
+ * @details This macro handles dimensioning and allocation of the memory buffer required by the timer,
+ *          making sure that the buffer is correctly aligned. It will also connect the timer module
+ *          to the scheduler (if specified).
+ *
+ * @note    This module assumes that the LFCLK is already running. If it is not, the module will 
+ *          be non-functional, since the RTC will not run. If you do not use a SoftDevice, you 
+ *          must start the LFCLK manually. See the rtc_example's lfclk_config() function 
+ *          for an example of how to do this. If you use a SoftDevice, the LFCLK is started on 
+ *          SoftDevice init. 
+ *
+ *
+ * @param[in]  PRESCALER        Value of the RTC1 PRESCALER register. This will decide the
+ *                              timer tick rate. Set to 0 for no prescaling.
+ * @param[in]  OP_QUEUES_SIZE   Size of queues holding timer operations that are pending execution.
+ * @param[in]  SCHEDULER_FUNC   Pointer to scheduler event handler
+ *
+ * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ *       several times as long as it is from the same location, for example, to do a re-initialization).
+ */
+/*lint -emacro(506, APP_TIMER_INIT) */ /* Suppress "Constant value Boolean */
+#define APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE, SCHEDULER_FUNC)                                  \
+    do                                                                                             \
+    {                                                                                              \
+        static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((OP_QUEUES_SIZE) + 1),           \
+                                               sizeof(uint32_t))];                                 \
+        uint32_t ERR_CODE = app_timer_init((PRESCALER),                                            \
+                                           (OP_QUEUES_SIZE) + 1,                                   \
+                                           APP_TIMER_BUF,                                          \
+                                           SCHEDULER_FUNC);                                        \
+        APP_ERROR_CHECK(ERR_CODE);                                                                 \
+    } while (0)
+
+
+
+/**@brief Function for initializing the timer module.
+ *
+ * Normally, initialization should be done using the APP_TIMER_INIT() macro, because that macro will both
+ *       allocate the buffers needed by the timer module (including aligning the buffers correctly)
+ *       and take care of connecting the timer module to the scheduler (if specified).
+ *
+ * @param[in]  prescaler           Value of the RTC1 PRESCALER register. Set to 0 for no prescaling.
+ * @param[in]  op_queues_size      Size of queues holding timer operations that are pending
+ *                                 execution. Note that due to the queue implementation, this size must
+ *                                 be one more than the size that is actually needed.
+ * @param[in]  p_buffer            Pointer to memory buffer for internal use in the app_timer
+ *                                 module. The size of the buffer can be computed using the
+ *                                 APP_TIMER_BUF_SIZE() macro. The buffer must be aligned to a
+ *                                 4 byte boundary.
+ * @param[in]  evt_schedule_func   Function for passing time-out events to the scheduler. Point to
+ *                                 app_timer_evt_schedule() to connect to the scheduler. Set to NULL
+ *                                 to make the timer module call the time-out handler directly from
+ *                                 the timer interrupt handler.
+ *
+ * @retval     NRF_SUCCESS               If the module was initialized successfully.
+ * @retval     NRF_ERROR_INVALID_PARAM   If a parameter was invalid (buffer not aligned to a 4 byte
+ *                                       boundary or NULL).
+ */
+uint32_t app_timer_init(uint32_t                      prescaler, 
+                        uint8_t                       op_queues_size,
+                        void *                        p_buffer,
+                        app_timer_evt_schedule_func_t evt_schedule_func);
+
+/**@brief Function for creating a timer instance.
+ *
+ * @param[in]  p_timer_id        Pointer to timer identifier.
+ * @param[in]  mode              Timer mode.
+ * @param[in]  timeout_handler   Function to be executed when the timer expires.
+ *
+ * @retval     NRF_SUCCESS               If the timer was successfully created.
+ * @retval     NRF_ERROR_INVALID_PARAM   If a parameter was invalid.
+ * @retval     NRF_ERROR_INVALID_STATE   If the application timer module has not been initialized or
+ *                                       the timer is running.
+ *
+ * @note This function does the timer allocation in the caller's context. It is also not protected
+ *       by a critical region. Therefore care must be taken not to call it from several interrupt
+ *       levels simultaneously.
+ * @note The function can be called again on the timer instance and will re-initialize the instance if
+ *       the timer is not running.
+ * @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to
+ *       be called on the previously initialized instance.
+ */
+uint32_t app_timer_create(app_timer_id_t const *      p_timer_id,
+                          app_timer_mode_t            mode,
+                          app_timer_timeout_handler_t timeout_handler);
+
+/**@brief Function for starting a timer.
+ *
+ * @param[in]       timer_id      Timer identifier.
+ * @param[in]       timeout_ticks Number of ticks (of RTC1, including prescaling) to time-out event
+ *                                (minimum 5 ticks).
+ * @param[in]       p_context     General purpose pointer. Will be passed to the time-out handler when
+ *                                the timer expires.
+ *
+ * @retval     NRF_SUCCESS               If the timer was successfully started.
+ * @retval     NRF_ERROR_INVALID_PARAM   If a parameter was invalid.
+ * @retval     NRF_ERROR_INVALID_STATE   If the application timer module has not been initialized or the timer
+ *                                       has not been created.
+ * @retval     NRF_ERROR_NO_MEM          If the timer operations queue was full.
+ *
+ * @note The minimum timeout_ticks value is 5.
+ * @note For multiple active timers, time-outs occurring in close proximity to each other (in the
+ *       range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks.
+ * @note When calling this method on a timer that is already running, the second start operation
+ *       is ignored.
+ */
+uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
+
+/**@brief Function for stopping the specified timer.
+ *
+ * @param[in]  timer_id                  Timer identifier.
+ *
+ * @retval     NRF_SUCCESS               If the timer was successfully stopped.
+ * @retval     NRF_ERROR_INVALID_PARAM   If a parameter was invalid.
+ * @retval     NRF_ERROR_INVALID_STATE   If the application timer module has not been initialized or the timer
+ *                                       has not been created.
+ * @retval     NRF_ERROR_NO_MEM          If the timer operations queue was full.
+ */
+uint32_t app_timer_stop(app_timer_id_t timer_id);
+
+/**@brief Function for stopping all running timers.
+ *
+ * @retval     NRF_SUCCESS               If all timers were successfully stopped.
+ * @retval     NRF_ERROR_INVALID_STATE   If the application timer module has not been initialized.
+ * @retval     NRF_ERROR_NO_MEM          If the timer operations queue was full.
+ */
+uint32_t app_timer_stop_all(void);
+
+/**@brief Function for returning the current value of the RTC1 counter.
+ *
+ * @param[out] p_ticks   Current value of the RTC1 counter.
+ *
+ * @retval     NRF_SUCCESS   If the counter was successfully read.
+ */
+uint32_t app_timer_cnt_get(uint32_t * p_ticks);
+
+/**@brief Function for computing the difference between two RTC1 counter values.
+ *
+ * @param[in]  ticks_to       Value returned by app_timer_cnt_get().
+ * @param[in]  ticks_from     Value returned by app_timer_cnt_get().
+ * @param[out] p_ticks_diff   Number of ticks from ticks_from to ticks_to.
+ *
+ * @retval     NRF_SUCCESS   If the counter difference was successfully computed.
+ */
+uint32_t app_timer_cnt_diff_compute(uint32_t   ticks_to,
+                                    uint32_t   ticks_from,
+                                    uint32_t * p_ticks_diff);
+
+#endif // APP_TIMER_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_error.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+#include "nrf.h"
+#include "app_error.h"
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#ifdef DEBUG
+#include "bsp.h"
+
+/* global error variables - in order to prevent removal by optimizers */
+uint32_t m_error_code;
+uint32_t m_line_num;
+const uint8_t * m_p_file_name;
+#endif
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @warning This handler is an example only and does not fit a final product. You need to analyze
+ *          how your product is supposed to react in case of error.
+ *
+ * @param[in] error_code  Error code supplied to the handler.
+ * @param[in] line_num    Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ *
+ * Function is implemented as weak so that it can be overwritten by custom application error handler
+ * when needed.
+ */
+
+/*lint -save -e14 */
+__WEAK void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+    // On assert, the system can only recover with a reset.
+#ifndef DEBUG
+    NVIC_SystemReset();
+#else
+
+#ifdef BSP_DEFINES_ONLY 
+    LEDS_ON(LEDS_MASK);
+#else
+    UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR));
+    // This call can be used for debug purposes during application development.
+    // @note CAUTION: Activating this code will write the stack to flash on an error.
+    //                This function should NOT be used in a final product.
+    //                It is intended STRICTLY for development/debugging purposes.
+    //                The flash write will happen EVEN if the radio is active, thus interrupting
+    //                any communication.
+    //                Use with care. Uncomment the line below to use.
+    //ble_debug_assert_handler(error_code, line_num, p_file_name);
+#endif // BSP_DEFINES_ONLY
+
+    // The following variable helps Keil keep the call stack visible, in addition, it can be set to
+    // 0 in the debugger to continue executing code after the error check.
+    volatile bool loop = true;
+    UNUSED_VARIABLE(loop);
+
+    m_error_code = error_code;
+    m_line_num = line_num;
+    m_p_file_name = p_file_name;
+
+    UNUSED_VARIABLE(m_error_code);
+    UNUSED_VARIABLE(m_line_num);
+    UNUSED_VARIABLE(m_p_file_name);
+    __disable_irq();
+
+    while(loop);
+#endif // DEBUG
+}
+/*lint -restore */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_error.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler and macros for utilizing a common error handler.
+ */
+
+#ifndef APP_ERROR_H__
+#define APP_ERROR_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+
+/**@brief Function for error handling, which is called when an error has occurred. 
+ *
+ * @param[in] error_code  Error code supplied to the handler.
+ * @param[in] line_num    Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name. 
+ */
+void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
+
+/**@brief Macro for calling error handler function. 
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#ifdef DEBUG
+#define APP_ERROR_HANDLER(ERR_CODE)                         \
+    do                                                      \
+    {                                                       \
+        app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__);  \
+    } while (0)
+#else
+#define APP_ERROR_HANDLER(ERR_CODE)                         \
+    do                                                      \
+    {                                                       \
+        app_error_handler((ERR_CODE), 0, 0);  \
+    } while (0)
+#endif
+/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. 
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */    
+#define APP_ERROR_CHECK(ERR_CODE)                           \
+    do                                                      \
+    {                                                       \
+        const uint32_t LOCAL_ERR_CODE = (ERR_CODE);         \
+        if (LOCAL_ERR_CODE != NRF_SUCCESS)                  \
+        {                                                   \
+            APP_ERROR_HANDLER(LOCAL_ERR_CODE);              \
+        }                                                   \
+    } while (0)    
+    
+/**@brief Macro for calling error handler function if supplied boolean value is false. 
+ *
+ * @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
+ */
+#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE)                   \
+    do                                                        \
+    {                                                         \
+        const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
+        if (!LOCAL_BOOLEAN_VALUE)                             \
+        {                                                     \
+            APP_ERROR_HANDLER(0);                             \
+        }                                                     \
+    } while (0)        
+
+#endif // APP_ERROR_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_H__
+#define APP_UTIL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+
+enum
+{
+    UNIT_0_625_MS = 625,                                /**< Number of microseconds in 0.625 milliseconds. */
+    UNIT_1_25_MS  = 1250,                               /**< Number of microseconds in 1.25 milliseconds. */
+    UNIT_10_MS    = 10000                               /**< Number of microseconds in 10 milliseconds. */
+};
+
+
+/**@brief Implementation specific macro for delayed macro expansion used in string concatenation
+*
+* @param[in]   lhs   Left hand side in concatenation
+* @param[in]   rhs   Right hand side in concatenation
+*/
+#define STRING_CONCATENATE_IMPL(lhs, rhs) lhs ## rhs
+
+
+/**@brief Macro used to concatenate string using delayed macro expansion
+*
+* @note This macro will delay concatenation until the expressions have been resolved
+*
+* @param[in]   lhs   Left hand side in concatenation
+* @param[in]   rhs   Right hand side in concatenation
+*/
+#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs)
+
+
+// Disable lint-warnings/errors for STATIC_ASSERT
+//lint --emacro(10,STATIC_ASSERT)
+//lint --emacro(18,STATIC_ASSERT)
+//lint --emacro(19,STATIC_ASSERT)
+//lint --emacro(30,STATIC_ASSERT)
+//lint --emacro(37,STATIC_ASSERT)
+//lint --emacro(42,STATIC_ASSERT)
+//lint --emacro(26,STATIC_ASSERT)
+//lint --emacro(102,STATIC_ASSERT)
+//lint --emacro(533,STATIC_ASSERT)
+//lint --emacro(534,STATIC_ASSERT)
+//lint --emacro(132,STATIC_ASSERT)
+//lint --emacro(414,STATIC_ASSERT)
+//lint --emacro(578,STATIC_ASSERT)
+//lint --emacro(628,STATIC_ASSERT)
+//lint --emacro(648,STATIC_ASSERT)
+//lint --emacro(830,STATIC_ASSERT)
+
+
+/**@brief Macro for doing static (i.e. compile time) assertion.
+*
+* @note If the EXPR isn't resolvable, then the error message won't be shown.
+*
+* @note The output of STATIC_ASSERT_MSG will be different across different compilers.
+*
+* @param[in] EXPR Constant expression to be verified.
+*/
+#if defined ( __COUNTER__ )
+
+#define STATIC_ASSERT(EXPR) \
+    ;enum { STRING_CONCATENATE(static_assert_, __COUNTER__) = 1/(!!(EXPR)) }
+
+#else
+
+#define STATIC_ASSERT(EXPR) \
+    ;enum { STRING_CONCATENATE(assert_line_, __LINE__) = 1/(!!(EXPR)) }
+
+#endif
+
+
+
+/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */
+typedef uint8_t uint16_le_t[2];
+
+/**@brief type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */
+typedef uint8_t uint32_le_t[4];
+
+/**@brief Byte array type. */
+typedef struct
+{
+    uint16_t  size;                 /**< Number of array entries. */
+    uint8_t * p_data;               /**< Pointer to array entries. */
+} uint8_array_t;
+    
+/**@brief Perform rounded integer division (as opposed to truncating the result).
+ *
+ * @param[in]   A   Numerator.
+ * @param[in]   B   Denominator.
+ *
+ * @return      Rounded (integer) result of dividing A by B.
+ */
+#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B))
+
+/**@brief Check if the integer provided is a power of two.
+ *
+ * @param[in]   A   Number to be tested.
+ *
+ * @return      true if value is power of two.
+ * @return      false if value not power of two.
+ */
+#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) )
+
+/**@brief To convert milliseconds to ticks.
+ * @param[in] TIME          Number of milliseconds to convert.
+ * @param[in] RESOLUTION    Unit to be converted to in [us/ticks].
+ */
+#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+
+/**@brief Perform integer division, making sure the result is rounded up.
+ *
+ * @details One typical use for this is to compute the number of objects with size B is needed to
+ *          hold A number of bytes.
+ *
+ * @param[in]   A   Numerator.
+ * @param[in]   B   Denominator.
+ *
+ * @return      Integer result of dividing A by B, rounded up.
+ */
+#define CEIL_DIV(A, B)      \
+    (((A) + (B) - 1) / (B))
+
+/**@brief Function for creating a buffer aligned to 4 bytes.
+ *
+ * @param[in]   NAME        Name of the buffor.
+ * @param[in]   MIN_SIZE    Size of this buffor (it will be rounded up to multiples of 4 bytes).
+ */
+#define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))]
+
+/**@brief Function for changing the value unit.
+ *
+ * @param[in]   value               Value to be rescaled.
+ * @param[in]   old_unit_reversal   Reversal of the incoming unit.
+ * @param[in]   new_unit_reversal   Reversal of the desired unit.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint64_t value_rescale(uint32_t value, uint32_t old_unit_reversal, uint16_t new_unit_reversal)
+{
+    return (uint64_t)ROUNDED_DIV((uint64_t)value * new_unit_reversal, old_unit_reversal);
+}
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in]   value            Value to be encoded.
+ * @param[out]  p_encoded_data   Buffer where the encoded data is to be written.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+    p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0);
+    p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8);
+    return sizeof(uint16_t);
+}
+
+/**@brief Function for encoding a three-byte value.
+ *
+ * @param[in]   value            Value to be encoded.
+ * @param[out]  p_encoded_data   Buffer where the encoded data is to be written.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint8_t uint24_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+    p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+    p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+    p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+    return 3;
+}
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in]   value            Value to be encoded.
+ * @param[out]  p_encoded_data   Buffer where the encoded data is to be written.
+ *
+ * @return      Number of bytes written.
+ */
+static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+    p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+    p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+    p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+    p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24);
+    return sizeof(uint32_t);
+}
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded data is stored.
+ *
+ * @return      Decoded value.
+ */
+static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data)
+{
+        return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | 
+                 (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ));
+}
+
+/**@brief Function for decoding a three-byte value.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded data is stored.
+ *
+ * @return      Decoded value (uint32_t).
+ */
+static __INLINE uint32_t uint24_decode(const uint8_t * p_encoded_data)
+{
+    return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16));
+}
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in]   p_encoded_data   Buffer where the encoded data is stored.
+ *
+ * @return      Decoded value.
+ */
+static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data)
+{
+    return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8)  |
+             (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+             (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ));
+}
+
+/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts.
+ *
+ *  @details The calculation is based on a linearized version of the battery's discharge
+ *           curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and
+ *           is considered to be the lower boundary.
+ *
+ *           The discharge curve for CR2032 is non-linear. In this model it is split into
+ *           4 linear sections:
+ *           - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV)
+ *           - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV)
+ *           - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV)
+ *           - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV)
+ *
+ *           These numbers are by no means accurate. Temperature and
+ *           load in the actual application is not accounted for!
+ *
+ *  @param[in] mvolts The voltage in mV
+ *
+ *  @return    Battery level in percent.
+*/
+static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts)
+{
+    uint8_t battery_level;
+
+    if (mvolts >= 3000)
+    {
+        battery_level = 100;
+    }
+    else if (mvolts > 2900)
+    {
+        battery_level = 100 - ((3000 - mvolts) * 58) / 100;
+    }
+    else if (mvolts > 2740)
+    {
+        battery_level = 42 - ((2900 - mvolts) * 24) / 160;
+    }
+    else if (mvolts > 2440)
+    {
+        battery_level = 18 - ((2740 - mvolts) * 12) / 300;
+    }
+    else if (mvolts > 2100)
+    {
+        battery_level = 6 - ((2440 - mvolts) * 6) / 340;
+    }
+    else
+    {
+        battery_level = 0;
+    }
+
+    return battery_level;
+}
+
+/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary.
+ *
+ * @param[in]   p   Pointer value to be checked.
+ *
+ * @return      TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise.
+ */
+static __INLINE bool is_word_aligned(void const* p)
+{
+    return (((uintptr_t)p & 0x03) == 0);
+}
+
+#endif // APP_UTIL_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util_platform.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "app_util_platform.h"
+
+static uint32_t m_in_critical_region = 0;
+
+void critical_region_enter(void)
+{
+    __disable_irq();    
+    m_in_critical_region++;    
+}
+
+void critical_region_exit(void)
+{
+    m_in_critical_region--;    
+    if (m_in_critical_region == 0)
+    {
+        __enable_irq();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/app_util_platform.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 app_util_platform Utility Functions and Definitions (Platform)
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications when using SoftDevice.
+ */
+
+#ifndef APP_UTIL_PLATFORM_H__
+#define APP_UTIL_PLATFORM_H__
+
+#include <stdint.h>
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#include "app_error.h"
+#endif
+/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
+typedef enum
+{
+#ifndef SOFTDEVICE_PRESENT
+    APP_IRQ_PRIORITY_HIGHEST = 0,
+#endif
+    APP_IRQ_PRIORITY_HIGH    = 1,
+#ifndef SOFTDEVICE_PRESENT
+    APP_IRQ_PRIORITY_MID     = 2,
+#endif
+    APP_IRQ_PRIORITY_LOW     = 3
+} app_irq_priority_t;
+
+#define NRF_APP_PRIORITY_THREAD    4                    /**< "Interrupt level" when running in Thread Mode. */
+
+/**@cond NO_DOXYGEN */
+#define EXTERNAL_INT_VECTOR_OFFSET 16
+/**@endcond */
+
+#define PACKED(TYPE) __packed TYPE
+
+void critical_region_enter (void);
+void critical_region_exit (void);
+
+/**@brief Macro for entering a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ *       CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ *       in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_ENTER()                                                             \
+    {                                                                                       \
+        uint8_t IS_NESTED_CRITICAL_REGION = 0;                                              \
+        uint32_t CURRENT_INT_PRI = current_int_priority_get();                              \
+        if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH)                                       \
+        {                                                                                   \
+            uint32_t ERR_CODE = sd_nvic_critical_region_enter(&IS_NESTED_CRITICAL_REGION);  \
+            if (ERR_CODE == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)                               \
+            {                                                                               \
+                __disable_irq();                                                            \
+            }                                                                               \
+            else                                                                            \
+            {                                                                               \
+                APP_ERROR_CHECK(ERR_CODE);                                                  \
+            }                                                                               \
+        }        
+#else
+#define CRITICAL_REGION_ENTER() critical_region_enter()
+#endif
+
+/**@brief Macro for leaving a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ *       CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ *       in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_EXIT()                                                              \
+        if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH)                                       \
+        {                                                                                   \
+            uint32_t ERR_CODE;                                                              \
+            __enable_irq();                                                                 \
+            ERR_CODE = sd_nvic_critical_region_exit(IS_NESTED_CRITICAL_REGION);             \
+            if (ERR_CODE != NRF_ERROR_SOFTDEVICE_NOT_ENABLED)                               \
+            {                                                                               \
+                APP_ERROR_CHECK(ERR_CODE);                                                  \
+            }                                                                               \
+        }                                                                                   \
+    }
+#else
+#define CRITICAL_REGION_EXIT() critical_region_exit()
+#endif 
+       
+/**@brief Function for finding the current interrupt level.
+ *
+ * @return   Current interrupt level.
+ * @retval   APP_IRQ_PRIORITY_HIGH    We are running in Application High interrupt level.
+ * @retval   APP_IRQ_PRIORITY_LOW     We are running in Application Low interrupt level.
+ * @retval   APP_IRQ_PRIORITY_THREAD  We are running in Thread Mode.
+ */
+static __INLINE uint8_t current_int_priority_get(void)
+{
+    uint32_t isr_vector_num = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
+    if (isr_vector_num > 0)
+    {
+        int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
+        return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF);
+    }
+    else
+    {
+        return NRF_APP_PRIORITY_THREAD;
+    }
+}
+
+#endif // APP_UTIL_PLATFORM_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/common.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,58 @@
+ /*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* @file
+* @brief Common header file for generic macros and definitions
+ *
+ */
+
+/*
+ * GPIO glue macros, this can be used to define a pin number in source/header file and use that macro for pin
+ * configuration using this expansion.
+ * example:
+ * #define RESET_PIN    8
+ * NRF_GPIO->PINCNF(RESET_PIN) = XXX  ;  // Expanded NRF_GPIO->PIN_CNF[8] = XXX
+ */
+#define PINX_GLUE(x, y, z)       x##y##_##z            /*!< first level glue for pin macros */
+#define PINCNF(p)                PINX_GLUE(PIN,p,CNF)  /*!< gpio configure pin number 'p' */
+#define PINOUT(p)                PINX_GLUE(PIN,p,OUT)  /*!< gpio out pin number 'p' */
+
+/*lint --flb "Leave library region" */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nordic_common.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 Common defines and macros for firmware developed by Nordic Semiconductor.
+ */
+
+#ifndef NORDIC_COMMON_H__
+#define NORDIC_COMMON_H__
+
+/** The upper 8 bits of a 32 bit value */
+//lint -emacro(572,MSB) // Suppress warning 572 "Excessive shift value"
+#define MSB(a) (((a) & 0xFF000000) >> 24)
+/** The lower 8 bits (of a 32 bit value) */
+#define LSB(a) ((a) & 0x000000FF)
+
+/** The upper 8 bits of a 16 bit value */
+//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value"
+#define MSB_16(a) (((a) & 0xFF00) >> 8)
+/** The lower 8 bits (of a 16 bit value) */
+#define LSB_16(a) ((a) & 0x00FF)
+
+/** Leaves the minimum of the two 32-bit arguments */
+/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+/** Leaves the maximum of the two 32-bit arguments */
+/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/** Concatenates two parameters. Useful as a second level of indirection,
+ *  when a parameter can be macro itself. */
+#define CONCAT_2(p1, p2)      p1##p2
+/** Concatenates three parameters. Useful as a second level of indirection,
+ *  when a parameter can be macro itself. */
+#define CONCAT_3(p1, p2, p3)  p1##p2##p3
+
+/**@brief Set a bit in the uint32 word.
+ *
+ * @param[in] W  Word whose bit is being set.
+ * @param[in] B  Bit number in the word to be set.
+ */
+#define SET_BIT(W,B)  ((W) |= (uint32_t)(1U << (B)))
+
+
+/**@brief Clears a bit in the uint32 word.
+ *
+ * @param[in] W   Word whose bit is to be cleared.
+ * @param[in] B   Bit number in the word to be cleared.
+ */
+#define CLR_BIT(W, B) ((W) &= (~((uint32_t)1 << (B))))
+
+
+/**@brief Checks if a bit is set.
+ *
+ * @param[in] W   Word whose bit is to be checked.
+ * @param[in] B   Bit number in the word to be checked.
+ *
+ * @retval 1 if bit is set.
+ * @retval 0 if bit is not set.
+ */
+#define IS_SET(W,B) (((W) >> (B)) & 1)
+
+#define BIT_0 0x01 /**< The value of bit 0 */
+#define BIT_1 0x02 /**< The value of bit 1 */
+#define BIT_2 0x04 /**< The value of bit 2 */
+#define BIT_3 0x08 /**< The value of bit 3 */
+#define BIT_4 0x10 /**< The value of bit 4 */
+#define BIT_5 0x20 /**< The value of bit 5 */
+#define BIT_6 0x40 /**< The value of bit 6 */
+#define BIT_7 0x80 /**< The value of bit 7 */
+#define BIT_8 0x0100 /**< The value of bit 8 */
+#define BIT_9 0x0200 /**< The value of bit 9 */
+#define BIT_10 0x0400 /**< The value of bit 10 */
+#define BIT_11 0x0800 /**< The value of bit 11 */
+#define BIT_12 0x1000 /**< The value of bit 12 */
+#define BIT_13 0x2000 /**< The value of bit 13 */
+#define BIT_14 0x4000 /**< The value of bit 14 */
+#define BIT_15 0x8000 /**< The value of bit 15 */
+#define BIT_16 0x00010000 /**< The value of bit 16 */
+#define BIT_17 0x00020000 /**< The value of bit 17 */
+#define BIT_18 0x00040000 /**< The value of bit 18 */
+#define BIT_19 0x00080000 /**< The value of bit 19 */
+#define BIT_20 0x00100000 /**< The value of bit 20 */
+#define BIT_21 0x00200000 /**< The value of bit 21 */
+#define BIT_22 0x00400000 /**< The value of bit 22 */
+#define BIT_23 0x00800000 /**< The value of bit 23 */
+#define BIT_24 0x01000000 /**< The value of bit 24 */
+#define BIT_25 0x02000000 /**< The value of bit 25 */
+#define BIT_26 0x04000000 /**< The value of bit 26 */
+#define BIT_27 0x08000000 /**< The value of bit 27 */
+#define BIT_28 0x10000000 /**< The value of bit 28 */
+#define BIT_29 0x20000000 /**< The value of bit 29 */
+#define BIT_30 0x40000000 /**< The value of bit 30 */
+#define BIT_31 0x80000000 /**< The value of bit 31 */
+
+#define UNUSED_VARIABLE(X)  ((void)(X))
+#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X)
+
+#endif // NORDIC_COMMON_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nrf_assert.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "nrf_assert.h"
+
+#if defined(DEBUG_NRF)
+void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name)
+{
+    (void) file_name; /* Unused parameter */
+    (void) line_num;  /* Unused parameter */
+ 
+    while (1) ;
+}
+#endif /* DEBUG_NRF */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/nrf_assert.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 Utilities for verifying program logic
+ */
+
+#ifndef NRF_ASSERT_H_
+#define NRF_ASSERT_H_
+
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+
+/** @brief Function for handling assertions.
+ *
+ *
+ * @note
+ * This function is called when an assertion has triggered.
+ *
+ *
+ * @post
+ * All hardware is put into an idle non-emitting state (in particular the radio is highly
+ * important to switch off since the radio might be in a state that makes it send
+ * packets continiously while a typical final infinit ASSERT loop is executing).
+ *
+ *
+ * @param line_num The line number where the assertion is called
+ * @param file_name Pointer to the file name
+ */
+void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
+
+/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ 
+/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \
+
+/** @brief Function for checking intended for production code.
+ *
+ * Check passes if "expr" evaluates to true. */
+#define ASSERT(expr) \
+if (expr)                                                                     \
+{                                                                             \
+}                                                                             \
+else                                                                          \
+{                                                                             \
+  assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__);               \
+}
+#else
+#define ASSERT(expr) //!< Assert empty when disabled
+__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
+#endif /* defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) */
+
+#endif /* NRF_ASSERT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_common.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/** @cond */
+/**@file
+ *
+ * @ingroup experimental_api
+ * @defgroup sdk_common SDK Common Header
+ * @breif All common headers needed for SDK examples will be included here so that application
+ *       developer does not have to include headers on him/herself.
+ * @{
+ */
+
+#ifndef SDK_COMMON_H__
+#define SDK_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "compiler_abstraction.h"
+#include "sdk_os.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+
+/** @} */
+/** @endcond */
+#endif // SDK_COMMON_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_errors.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 sdk_error SDK Error codes
+ * @{
+ * @ingroup app_common
+ * @{
+ * @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for
+ *          identifying the module where the error occurred while the least least significant LSB
+ *          are used to provide the cause or nature of error. Each module is assigned a 16-bit
+ *          unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit
+ *          LSB range is with module id as the MSB in the 32-bit error code is reserved for the
+ *          module. As an example, if 0x8800 identifies a certain SDK module, all values from 
+ *          0x88000000 - 0x8800FFFF are reserved for this module.
+ *          It should be noted that common error reasons have been assigned values to make it 
+ *          possible to decode error reason easily. As an example, lets module uninitialized has
+ *          been assigned an error code 0x000A0. Then, if application encounters an error code
+ *          0xZZZZ00A0, it knows that it accessing a certain module without initializing it.
+ *          Apart from this, each module is allowed to define error codes that are not covered by
+ *          the common ones, however, these values are defined in a range that does not conflict
+ *          with common error values. For module, specific error however, it is possible that the
+ *          same error value is used by two different modules to indicated errors of very different
+ *          nature. If error is already defined by the NRF common error codes, these are reused.
+ *          A range is reserved for application as well, it can use this range for defining
+ *          application specific errors.
+ *
+ * @note Success code, NRF_SUCCESS, does not include any module identifier.          
+
+ */
+
+#ifndef SDK_ERRORS_H__
+#define SDK_ERRORS_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+/**
+ * @defgroup sdk_err_base Base defined for SDK Modules
+ * @{
+ */
+#define SDK_ERROR_BASE         (NRF_ERROR_BASE_NUM + 0x8000)   /**< Base value defined for SDK module identifiers. */
+#define SDK_COMMON_ERROR_BASE  (NRF_ERROR_BASE_NUM + 0x0080)   /**< Base error value to be used for SDK error values. */
+/* @} */
+
+/**
+ * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred.
+ * @{
+ */
+#define DEVICE_MANAGER_ERR_BASE   (0x8000)
+#define MEMORY_MANAGER_ERR_BASE   (0x8100)
+/* @} */
+
+
+/**
+ * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
+ * @{
+ */
+#define IOT_ERR_BASE_START        (0xA000)
+#define IOT_ERR_BASE_STOP         (0xAFFF)
+/* @} */
+ 
+
+/**
+ * @defgroup sdk_common_errors Codes reserved as identification for common errors.
+ * @{
+ */
+#define MODULE_NOT_INITIALZED      (SDK_COMMON_ERROR_BASE + 0x0000)
+#define MUTEX_INIT_FAILED          (SDK_COMMON_ERROR_BASE + 0x0001)
+#define MUTEX_LOCK_FAILED          (SDK_COMMON_ERROR_BASE + 0x0002)
+#define MUTEX_UNLOCK_FAILED        (SDK_COMMON_ERROR_BASE + 0x0003)
+#define MUTEX_COND_INIT_FAILED     (SDK_COMMON_ERROR_BASE + 0x0004)
+#define MODULE_ALREADY_INITIALIZED (SDK_COMMON_ERROR_BASE + 0x0005)
+#define API_NOT_IMPLEMENTED        (SDK_COMMON_ERROR_BASE + 0x0010)
+#define FEATURE_NOT_ENABLED        (SDK_COMMON_ERROR_BASE + 0x0011)
+/* @} */
+
+
+/**
+ * @defgroup dm_specific_errors Error / status codes specific to device manager.
+ * @{
+ */
+#define DM_NO_APP_CONTEXT                (DEVICE_MANAGER_ERR_BASE + 0x0040)
+#define DM_SERVICE_CONTEXT_NOT_APPLIED   (DEVICE_MANAGER_ERR_BASE + 0x0041)
+#define DM_CONTEXT_INFO_LOST             (DEVICE_MANAGER_ERR_BASE + 0x0042)
+#define DM_DEVICE_CONTEXT_FULL           (DEVICE_MANAGER_ERR_BASE + 0x0043)
+/* @} */
+
+/**
+ * @brief API Result.
+ *
+ * @details Indicates success or failure of an API procedure. In case of failure, a comprehensive
+ *          error code indicating cause or reason for failure is provided.
+ *
+ *          Though called an API result, it could used in Asynchronous notifications callback along
+ *          with asynchronous callback as event result. This mechanism is employed when an event
+ *          marks the end of procedure initiated using API. API result, in this case, will only be
+ *          an indicative of whether the procedure has been requested successfully.
+ */
+typedef uint32_t ret_code_t;
+/** @} */
+/** @} */
+
+#endif // SDK_ERRORS_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_mapped_flags.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_mapped_flags.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+
+
+/**@brief Function for setting the state of a flag to true.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in]  p_flags  The collection of flags to modify.
+ * @param[in]  index    The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+    *p_flags |= (1U << index);
+}
+
+
+/**@brief Function for setting the state of a flag to false.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in]  p_flags  The collection of flags to modify.
+ * @param[in]  index    The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+    *p_flags &= ~(1U << index);
+}
+
+
+/**@brief Function for getting the state of a flag.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in]  p_flags  The collection of flags to read.
+ * @param[in]  index    The index of the flag to get.
+ */
+static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index)
+{
+    return ((flags & (1 << index)) != 0);
+}
+
+
+
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags)
+{
+    for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+    {
+        if (sdk_mapped_flags_get_by_index(flags, i))
+        {
+            return i;
+        }
+    }
+    return SDK_MAPPED_FLAGS_INVALID_INDEX;
+}
+
+
+void sdk_mapped_flags_update_by_key(uint16_t           * p_keys,
+                                    sdk_mapped_flags_t * p_flags,
+                                    uint16_t             key,
+                                    bool                 value)
+{
+    sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value);
+}
+
+
+void sdk_mapped_flags_bulk_update_by_key(uint16_t           * p_keys,
+                                         sdk_mapped_flags_t * p_flags,
+                                         uint32_t             n_flag_collections,
+                                         uint16_t             key,
+                                         bool                 value)
+{
+    if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0))
+    {
+        for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+        {
+            if (p_keys[i] == key)
+            {
+                for (int j = 0; j < n_flag_collections; j++)
+                {
+                    if (value)
+                    {
+                        sdk_mapped_flags_set_by_index(&p_flags[j], i);
+                    }
+                    else
+                    {
+                        sdk_mapped_flags_clear_by_index(&p_flags[j], i);
+                    }
+                }
+                return;
+            }
+        }
+    }
+}
+
+
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key)
+{
+    if (p_keys != NULL)
+    {
+        for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+        {
+            if (p_keys[i] == key)
+            {
+                return sdk_mapped_flags_get_by_index(flags, i);
+            }
+        }
+    }
+    return false;
+}
+
+
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t           * p_keys,
+                                                          sdk_mapped_flags_t   flags)
+{
+    sdk_mapped_flags_key_list_t key_list;
+    key_list.len = 0;
+
+    if (p_keys != NULL)
+    {
+        for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+        {
+            if (sdk_mapped_flags_get_by_index(flags, i))
+            {
+                key_list.flag_keys[key_list.len++] = p_keys[i];
+            }
+        }
+    }
+
+    return key_list;
+}
+
+
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags)
+{
+    uint32_t n_flags_set = 0;
+
+    for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+    {
+        if (sdk_mapped_flags_get_by_index(flags, i))
+        {
+            n_flags_set += 1;
+        }
+    }
+    return n_flags_set;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_mapped_flags.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 SDK_MAPPED_FLAGS_H__
+#define SDK_MAPPED_FLAGS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "compiler_abstraction.h"
+
+/**
+ * @file
+ * @defgroup sdk_mapped_flags Mapped flags
+ * @ingroup app_common
+ * @{
+ * @brief Module for writing and reading flags that are associated
+ *        with keys.
+ *
+ * @details The flags are represented as bits in a bitmap called a <i>flag collection</i>. The keys
+ *          are uint16_t. Each flag collection contains all flags of the same type, one flag for
+ *          each key.
+ *
+ *          The mapped flags module does not keep the flag states, nor the list of keys. These are
+ *          provided in the API calls. A key's index in the key list determines which bit in the
+ *          flag collection is associated with it. This module does not ever edit the key list, and
+ *          does not edit flags except in function calls that take the flag collection as a pointer.
+ *
+ */
+
+#define SDK_MAPPED_FLAGS_N_KEYS          8       /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */
+#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8       /**< The number of flags that fit in one byte. */
+#define SDK_MAPPED_FLAGS_INVALID_INDEX   0xFFFF  /**< A flag index guaranteed to be invalid. */
+
+typedef uint8_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */
+
+
+// Test whether the flag collection type is large enough to hold all the flags. If this fails,
+// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t.
+STATIC_ASSERT((
+    sizeof(sdk_mapped_flags_t)*SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS);
+
+
+/**@brief Type used to present a subset of the registered keys.
+ */
+typedef struct
+{
+    uint32_t len;                                 /**< The length of the list. */
+    uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS];  /**< The list of keys. */
+} sdk_mapped_flags_key_list_t;
+
+
+/**@brief Function for getting the first index at which the flag is true in the provided
+ *        collection.
+ *
+ * @param[in]  flags   The flag collection to search for a flag set to true.
+ *
+ * @return  The first index that has its flag set to true. If none were found, the
+ *          function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX.
+ */
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for updating the state of a flag.
+ *
+ * @param[in]  p_keys   The list of associated keys (assumed to have a length of
+ *                      @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags  The flag collection to modify.
+ * @param[in]  key      The key to modify the flag of.
+ * @param[in]  value    The state to set the flag to.
+ */
+void sdk_mapped_flags_update_by_key(uint16_t           * p_keys,
+                                    sdk_mapped_flags_t * p_flags,
+                                    uint16_t             key,
+                                    bool                 value);
+
+
+/**@brief Function for updating the state of the same flag in multiple flag collections.
+ *
+ * @details The key and value are the same for all flag collections in the p_flags array.
+ *
+ * @param[in]  p_keys              The list of associated keys (assumed to have a length of
+ *                                 @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags             The flag collections to modify.
+ * @param[out] n_flag_collections  The number of flag collections in p_flags.
+ * @param[in]  key                 The key to modify the flag of.
+ * @param[in]  value               The state to set the flag to.
+ */
+void sdk_mapped_flags_bulk_update_by_key(uint16_t           * p_keys,
+                                         sdk_mapped_flags_t * p_flags,
+                                         uint32_t             n_flag_collections,
+                                         uint16_t             key,
+                                         bool                 value);
+
+
+/**@brief Function for getting the state of a specific flag.
+ *
+ * @param[in]  p_keys  The list of associated keys (assumed to have a length of
+ *                     @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in]  flags   The flag collection to read from.
+ * @param[in]  key     The key to get the flag for.
+ *
+ * @return  The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key);
+
+
+/**@brief Function for getting a list of all keys that have a specific flag set to true.
+ *
+ * @param[in]  p_keys  The list of associated keys (assumed to have a length of
+ *                     @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in]  flags   The flag collection to search.
+ *
+ * @return  The list of keys.
+ */
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t           * p_keys,
+                                                          sdk_mapped_flags_t   flags);
+
+
+/**@brief Function for getting the number of keys that have a specific flag set to true.
+ *
+ * @param[in]  flags  The flag collection to search.
+ *
+ * @return  The number of keys.
+ */
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for querying whether any flags in the collection are set.
+ *
+ * @param[in]  flags  The flag collection to query.
+ *
+ * @retval  true If one or more flags are set to true.
+ * @retval  false Otherwise.
+ */
+static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags)
+{
+    return (flags != 0);
+}
+
+
+/** @} */
+
+#endif /* SDK_MAPPED_FLAGS_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/libraries/util/sdk_os.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /** @cond */
+/**@file
+ *
+ * @defgroup sdk_os SDK OS Abstraction
+ * @ingroup experimental_api
+ * @details In order to made SDK modules independent of use of an embedded OS, and permit
+ *          application with varied task architecture, SDK abstracts the OS specific
+ *          elements here in order to make all other modules agnostic to the OS or task
+ *          architecture.
+ * @{
+ */
+
+#ifndef SDK_OS_H__
+#define SDK_OS_H__
+
+#define SDK_MUTEX_DEFINE(X)
+#define SDK_MUTEX_INIT(X)
+#define SDK_MUTEX_LOCK(X)
+#define SDK_MUTEX_UNLOCK(X)
+
+/**
+ * @defgroup os_data_type Data types.
+ */
+ 
+/** @} */
+/** @endcond */
+#endif // SDK_OS_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 ant_stack_handler_types Types definitions for ANT support in SoftDevice handler.
+ * @{
+ * @ingroup  softdevice_handler
+ * @brief    This file contains the declarations of types required for ANT stack support. These
+ *           types will be defined when the preprocessor define ANT_STACK_SUPPORT_REQD is defined.
+ */
+
+#ifndef ANT_STACK_HANDLER_TYPES_H__
+#define ANT_STACK_HANDLER_TYPES_H__
+
+#ifdef ANT_STACK_SUPPORT_REQD
+
+#include <stdlib.h>
+
+#define ANT_STACK_EVT_MSG_BUF_SIZE      32                                                /**< Size of ANT event message buffer. This will be provided to the SoftDevice while fetching an event. */
+#define ANT_STACK_EVT_STRUCT_SIZE       (sizeof(ant_evt_t))                               /**< Size of the @ref ant_evt_t structure. This will be used by the @ref softdevice_handler to internal event buffer size needed. */
+
+/**@brief ANT stack event type. */
+typedef struct
+{
+    uint8_t channel;                                                                      /**< Channel number. */
+    uint8_t event;                                                                        /**< Event code. */
+    uint8_t evt_buffer[ANT_STACK_EVT_MSG_BUF_SIZE];                                       /**< Event message buffer. */
+} ant_evt_t;
+
+/**@brief Application ANT stack event handler type. */
+typedef void (*ant_evt_handler_t) (ant_evt_t * p_ant_evt);
+
+/**@brief     Function for registering for ANT events.
+ *
+ * @details   The application should use this function to register for receiving ANT events from
+ *            the SoftDevice. If the application does not call this function, then any ANT event
+ *            that may be generated by the SoftDevice will NOT be fetched. Once the application has
+ *            registered for the events, it is not possible to  possible to cancel the registration.
+ *            However, it is possible to register a different function for handling the events at
+ *            any point of time.
+ *
+ * @param[in] ant_evt_handler Function to be called for each received ANT event.
+ *
+ * @retval    NRF_SUCCESS     Successful registration.
+ * @retval    NRF_ERROR_NULL  Null pointer provided as input.
+ */
+uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler);
+
+#else
+
+// The ANT Stack support is not required.
+
+#define ANT_STACK_EVT_STRUCT_SIZE       0                                                 /**< Since the ANT stack support is not required, this is equated to 0, so that the @ref softdevice_handler.h can compute the internal event buffer size without having to care for ANT events.*/
+
+#endif // ANT_STACK_SUPPORT_REQD
+
+#endif // ANT_STACK_HANDLER_TYPES_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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_stack_handler_types Types definitions for BLE support in SoftDevice handler.
+ * @{
+ * @ingroup  softdevice_handler
+ * @brief    This file contains the declarations of types required for BLE stack support. These
+ *           types will be defined when the preprocessor define BLE_STACK_SUPPORT_REQD is defined.
+ */
+
+#ifndef BLE_STACK_HANDLER_TYPES_H__
+#define BLE_STACK_HANDLER_TYPES_H__
+
+#define BLE_STACK_SUPPORT_REQD
+#ifdef BLE_STACK_SUPPORT_REQD
+
+#include <stdlib.h>
+#include "ble.h"
+#include "nrf_sdm.h"
+#include "app_error.h"
+#include "app_util.h"
+
+#define BLE_STACK_EVT_MSG_BUF_SIZE       (sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT))     /**< Size of BLE event message buffer. This will be provided to the SoftDevice while fetching an event. */
+#define BLE_STACK_HANDLER_SCHED_EVT_SIZE 0                                                 /**< The size of the scheduler event used by SoftDevice handler when passing BLE events using the @ref app_scheduler. */
+
+/**@brief Application stack event handler type. */
+typedef void (*ble_evt_handler_t) (ble_evt_t * p_ble_evt);
+
+/**@brief     Function for registering for BLE events.
+ *
+ * @details   The application should use this function to register for receiving BLE events from
+ *            the SoftDevice. If the application does not call this function, then any BLE event
+ *            that may be generated by the SoftDevice will NOT be fetched. Once the application has
+ *            registered for the events, it is not possible to cancel the registration.
+ *            However, it is possible to register a different function for handling the events at
+ *            any point of time.
+ *
+ * @param[in] ble_evt_handler Function to be called for each received BLE event.
+ *
+ * @retval    NRF_SUCCESS     Successful registration.
+ * @retval    NRF_ERROR_NULL  Null pointer provided as input.
+ */
+uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler);
+
+#else
+
+#define BLE_STACK_EVT_MSG_BUF_SIZE        0                                                /**< Since the BLE stack support is not required, this is equated to 0, so that the @ref softdevice_handler.h can compute the internal event buffer size without having to care for BLE events.*/
+#define BLE_STACK_HANDLER_SCHED_EVT_SIZE  0
+
+#endif // BLE_STACK_SUPPORT_REQD
+
+#endif // BLE_STACK_HANDLER_TYPES_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "softdevice_handler.h"
+#include <stdlib.h>
+#include "nordic_common.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "nrf_assert.h"
+#include "nrf_soc.h"
+#include "nrf.h"
+
+#if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
+    #include "ant_interface.h"
+#elif defined(ANT_STACK_SUPPORT_REQD) 
+    #include "ant_interface.h"
+#elif defined(BLE_STACK_SUPPORT_REQD)
+    #include "ble.h"
+#endif
+
+#ifdef NRF51
+#define SOFTDEVICE_EVT_IRQ        SD_EVT_IRQn       /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define SOFTDEVICE_EVT_IRQHandler SD_EVT_IRQHandler
+#elif defined (NRF52)
+#define SOFTDEVICE_EVT_IRQ        SWI2_EGU2_IRQn
+#define SOFTDEVICE_EVT_IRQHandler SWI2_EGU2_IRQHandler
+#endif /* NRF51 */
+
+static softdevice_evt_schedule_func_t m_evt_schedule_func;              /**< Pointer to function for propagating SoftDevice events to the scheduler. */
+
+static volatile bool                  m_softdevice_enabled = false;     /**< Variable to indicate whether the SoftDevice is enabled. */
+
+#ifdef BLE_STACK_SUPPORT_REQD
+// The following three definitions is needed only if BLE events are needed to be pulled from the stack.
+static uint8_t                      * mp_ble_evt_buffer;                /**< Buffer for receiving BLE events from the SoftDevice. */
+static uint16_t                       m_ble_evt_buffer_size;            /**< Size of BLE event buffer. */
+static ble_evt_handler_t              m_ble_evt_handler;                /**< Application event handler for handling BLE events. */
+#endif
+
+#ifdef ANT_STACK_SUPPORT_REQD
+// The following two definition is needed only if ANT events are needed to be pulled from the stack.
+static ant_evt_t                      m_ant_evt_buffer;                 /**< Buffer for receiving ANT events from the SoftDevice. */
+static ant_evt_handler_t              m_ant_evt_handler;                /**< Application event handler for handling ANT events.  */
+#endif
+
+static sys_evt_handler_t              m_sys_evt_handler;                /**< Application event handler for handling System (SOC) events.  */
+
+
+/**@brief       Callback function for asserts in the SoftDevice.
+ *
+ * @details     A pointer to this function will be passed to the SoftDevice. This function will be
+ *              called if an ASSERT statement in the SoftDevice fails.
+ *
+ * @param[in]   pc         The value of the program counter when the ASSERT call failed.
+ * @param[in]   line_num   Line number of the failing ASSERT call.
+ * @param[in]   file_name  File name of the failing ASSERT call.
+ */
+void softdevice_assertion_handler(uint32_t pc, uint16_t line_num, const uint8_t * file_name)
+{
+    UNUSED_PARAMETER(pc);
+    assert_nrf_callback(line_num, file_name);
+}
+
+
+void intern_softdevice_events_execute(void)
+{
+    if (!m_softdevice_enabled)
+    {
+        // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the
+        // application without using this module's API (i.e softdevice_handler_init)
+
+        return;
+    }
+
+    bool no_more_soc_evts = (m_sys_evt_handler == NULL);
+#ifdef BLE_STACK_SUPPORT_REQD
+    bool no_more_ble_evts = (m_ble_evt_handler == NULL);
+#endif
+#ifdef ANT_STACK_SUPPORT_REQD
+    bool no_more_ant_evts = (m_ant_evt_handler == NULL);
+#endif
+
+    for (;;)
+    {
+        uint32_t err_code;
+
+        if (!no_more_soc_evts)
+        {
+            uint32_t evt_id;
+
+            // Pull event from SOC.
+            err_code = sd_evt_get(&evt_id);
+            
+            if (err_code == NRF_ERROR_NOT_FOUND)
+            {
+                no_more_soc_evts = true;
+            }
+            else if (err_code != NRF_SUCCESS)
+            {
+                APP_ERROR_HANDLER(err_code);
+            }
+            else
+            {
+                // Call application's SOC event handler.
+                m_sys_evt_handler(evt_id);
+            }
+        }
+
+#ifdef BLE_STACK_SUPPORT_REQD
+        // Fetch BLE Events.
+        if (!no_more_ble_evts)
+        {
+            // Pull event from stack
+            uint16_t evt_len = m_ble_evt_buffer_size;
+
+            err_code = sd_ble_evt_get(mp_ble_evt_buffer, &evt_len);
+            if (err_code == NRF_ERROR_NOT_FOUND)
+            {
+                no_more_ble_evts = true;
+            }
+            else if (err_code != NRF_SUCCESS)
+            {
+                APP_ERROR_HANDLER(err_code);
+            }
+            else
+            {
+                // Call application's BLE stack event handler.
+                m_ble_evt_handler((ble_evt_t *)mp_ble_evt_buffer);
+            }
+        }
+#endif
+
+#ifdef ANT_STACK_SUPPORT_REQD
+        // Fetch ANT Events.
+        if (!no_more_ant_evts)
+        {
+            // Pull event from stack
+            err_code = sd_ant_event_get(&m_ant_evt_buffer.channel,
+                                        &m_ant_evt_buffer.event,
+                                        m_ant_evt_buffer.evt_buffer);
+            if (err_code == NRF_ERROR_NOT_FOUND)
+            {
+                no_more_ant_evts = true;
+            }
+            else if (err_code != NRF_SUCCESS)
+            {
+                APP_ERROR_HANDLER(err_code);
+            }
+            else
+            {
+                // Call application's ANT stack event handler.
+                m_ant_evt_handler(&m_ant_evt_buffer);
+            }
+        }
+#endif
+
+        if (no_more_soc_evts)
+        {
+            // There are no remaining System (SOC) events to be fetched from the SoftDevice.
+#if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
+            // Check if there are any remaining BLE and ANT events.
+            if (no_more_ble_evts && no_more_ant_evts)
+            {
+                break;
+            }
+#elif defined(BLE_STACK_SUPPORT_REQD)
+            // Check if there are any remaining BLE events.
+            if (no_more_ble_evts)
+            {
+                break;
+            }
+#elif defined(ANT_STACK_SUPPORT_REQD)
+            // Check if there are any remaining ANT events.
+            if (no_more_ant_evts)
+            {
+                break;
+            }
+#else
+            // No need to check for BLE or ANT events since there is no support for BLE and ANT
+            // required.
+            break;
+#endif
+        }
+    }
+}
+
+bool softdevice_handler_isEnabled(void)
+{
+    return m_softdevice_enabled;
+}
+
+uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t           clock_source,
+                                 void *                         p_ble_evt_buffer,
+                                 uint16_t                       ble_evt_buffer_size,
+                                 softdevice_evt_schedule_func_t evt_schedule_func)
+{
+    uint32_t err_code;
+
+    // Save configuration.
+#if defined (BLE_STACK_SUPPORT_REQD)
+    // Check that buffer is not NULL.
+    if (p_ble_evt_buffer == NULL)
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+    
+    // Check that buffer is correctly aligned.
+    if (!is_word_aligned(p_ble_evt_buffer))
+    {
+        return NRF_ERROR_INVALID_PARAM;
+    }
+
+    mp_ble_evt_buffer     = (uint8_t *)p_ble_evt_buffer;
+    m_ble_evt_buffer_size = ble_evt_buffer_size;
+#else
+    // The variables p_ble_evt_buffer and ble_evt_buffer_size is not needed if BLE Stack support
+    // is not required.
+    UNUSED_PARAMETER(p_ble_evt_buffer);
+    UNUSED_PARAMETER(ble_evt_buffer_size);
+#endif
+
+    m_evt_schedule_func = evt_schedule_func;
+
+//Enabling FPU for SoftDevice
+#ifdef S132
+    SCB->CPACR |= (3UL << 20) | (3UL << 22);
+    __DSB();
+    __ISB();
+#endif
+    // Initialize SoftDevice.
+    err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+#ifdef S132
+    SCB->CPACR = 0;
+    __DSB();
+    __ISB();
+#endif
+
+    m_softdevice_enabled = true;
+
+    // Enable BLE event interrupt (interrupt priority has already been set by the stack).
+    return sd_nvic_EnableIRQ(SOFTDEVICE_EVT_IRQ);
+}
+
+
+uint32_t softdevice_handler_sd_disable(void)
+{
+    uint32_t err_code = sd_softdevice_disable();
+ 
+    m_softdevice_enabled = !(err_code == NRF_SUCCESS);
+
+    return err_code;
+}
+
+
+#ifdef BLE_STACK_SUPPORT_REQD
+uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler)
+{
+    if (ble_evt_handler == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    m_ble_evt_handler = ble_evt_handler;
+
+    return NRF_SUCCESS;
+}
+#endif
+
+
+#ifdef ANT_STACK_SUPPORT_REQD
+uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler)
+{
+    if (ant_evt_handler == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    m_ant_evt_handler = ant_evt_handler;
+
+    return NRF_SUCCESS;
+}
+#endif
+
+
+uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler)
+{
+    if (sys_evt_handler == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    m_sys_evt_handler = sys_evt_handler;
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief   Function for handling the Application's BLE Stack events interrupt.
+ *
+ * @details This function is called whenever an event is ready to be pulled.
+ */
+void SOFTDEVICE_EVT_IRQHandler(void)
+{
+    if (m_evt_schedule_func != NULL)
+    {
+        uint32_t err_code = m_evt_schedule_func();
+        APP_ERROR_CHECK(err_code);
+    }
+    else
+    {
+        intern_softdevice_events_execute();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 softdevice_handler SoftDevice Event Handler
+ * @{
+ * @ingroup  app_common
+ * @brief    API for initializing and disabling the SoftDevice
+ *
+ * @details  This API contains the functions and defines exposed by the @ref lib_softdevice_handler.
+ *           For more information on the library and how the application should use it, please refer
+ *           @ref lib_softdevice_handler.
+ *
+ * @note     Use the USE_SCHEDULER parameter of the SOFTDEVICE_HANDLER_INIT() macro to select if
+ *           the @ref app_scheduler is to be used or not.
+ *
+ * @note     Even if the scheduler is not used, softdevice_handler.h will include app_scheduler.h.
+ *           So when compiling, app_scheduler.h must be available in one of the compiler include
+ *           paths.
+ */
+
+#ifndef SOFTDEVICE_HANDLER_H__
+#define SOFTDEVICE_HANDLER_H__
+
+#include <stdlib.h>
+#include "nordic_common.h"
+#include "nrf_sdm.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "ble_stack_handler_types.h"
+#include "ant_stack_handler_types.h"
+
+#define SOFTDEVICE_SCHED_EVT_SIZE       0                                                 /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). For SoftDevice events, this size is 0, since the events are being pulled in the event handler. */
+#define SYS_EVT_MSG_BUF_SIZE            sizeof(uint32_t)                                  /**< Size of System (SOC) event message buffer. */
+
+/**@brief Type of function for passing events from the stack handler module to the scheduler. */
+typedef uint32_t (*softdevice_evt_schedule_func_t) (void);
+
+/**@brief Application System (SOC) event handler type. */
+typedef void (*sys_evt_handler_t) (uint32_t evt_id);
+
+
+/**@brief     Macro for initializing the stack event handler.
+ *
+ * @details   It will handle dimensioning and allocation of the memory buffer required for reading
+ *            events from the stack, making sure the buffer is correctly aligned. It will also
+ *            connect the stack event handler to the scheduler/RTOS (if specified).
+ *
+ * @param[in] CLOCK_SOURCE     Low frequency clock source and accuracy (type nrf_clock_lfclksrc_t,
+ *                             see sd_softdevice_enable() for details).
+ * @param[in] EVT_HANDLER      scheduler/RTOS event handler function.
+ *
+ * @note      Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ *            several times as long as it is from the same location, that is to do a
+ *            reinitialization).
+ */
+/*lint -emacro(506, SOFTDEVICE_HANDLER_INIT) */ /* Suppress "Constant value Boolean */
+#define SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE,                                                      \
+                                EVT_HANDLER)                                                     \
+    do                                                                                             \
+    {                                                                                              \
+        static uint32_t BLE_EVT_BUFFER[CEIL_DIV(BLE_STACK_EVT_MSG_BUF_SIZE, sizeof(uint32_t))];    \
+        uint32_t ERR_CODE;                                                                         \
+        ERR_CODE = softdevice_handler_init((CLOCK_SOURCE),                                         \
+                                           BLE_EVT_BUFFER,                                         \
+                                           sizeof(BLE_EVT_BUFFER),                                 \
+                                           EVT_HANDLER);      \
+        APP_ERROR_CHECK(ERR_CODE);                                                                 \
+    } while (0)
+
+/**
+ * @brief Function for retrieving the information about SD state
+ *
+ * The information about current state of softdevice.
+ * @retval false SD is not initialized and SD commands should not be called.
+ * @retval true  SD is already initialized
+ */
+bool softdevice_handler_isEnabled(void);
+
+/**@brief      Function for initializing the stack handler module.
+ *
+ * @details    Enables the SoftDevice and the stack event interrupt handler.
+ *
+ * @note       This function must be called before calling any function in the SoftDevice API.
+ *
+ * @note       Normally initialization should be done using the SOFTDEVICE_HANDLER_INIT() macro,
+ *             as that will both allocate the event buffer, and also align the buffer correctly.
+ *
+ * @param[in]  clock_source        Low frequency clock source to be used by the SoftDevice.
+ * @param[in]  p_ble_evt_buffer    Buffer for holding one BLE stack event. Since heap is not being
+ *                                 used, this buffer must be provided by the application. The
+ *                                 buffer must be large enough to hold the biggest stack event the
+ *                                 application is supposed to handle. The buffer must be aligned to
+ *                                 a 4 byte boundary. This parameter is unused if BLE stack support 
+ *                                 is not required.
+ * @param[in]  ble_evt_buffer_size Size of SoftDevice BLE event buffer. This parameter is unused if
+ *                                 BLE stack support is not required.
+ * @param[in]  evt_schedule_func   Function for passing events to the scheduler. Point to
+ *                                 ble_ant_stack_evt_schedule() to connect to the scheduler.
+ *                                 Set to NULL to make the stack handler module call the event
+ *                                 handler directly from the stack event interrupt handler.
+ *
+ * @retval     NRF_SUCCESS               Successful initialization.
+ * @retval     NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
+ *                                       boundary) or NULL.
+ */
+uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t              clock_source,
+                                 void *                            p_ble_evt_buffer,
+                                 uint16_t                          ble_evt_buffer_size,
+                                 softdevice_evt_schedule_func_t    evt_schedule_func);
+
+
+/**@brief     Function for disabling the SoftDevice.
+ *
+ * @details   This function will disable the SoftDevice. It will also update the internal state
+ *            of this module.
+ */
+uint32_t softdevice_handler_sd_disable(void);
+
+
+/**@brief     Function for registering for System (SOC) events.
+ *
+ * @details   The application should use this function to register for receiving System (SOC)
+ *            events from the SoftDevice. If the application does not call this function, then any
+ *            System (SOC) events that may be generated by the SoftDevice will NOT be fetched. Once
+ *            the application has registered for the events, it is not possible to  possible to
+ *            cancel the registration. However, it is possible to register a different function for
+ *            handling the events at any point of time.
+ *
+ * @param[in] sys_evt_handler Function to be called for each received System (SOC) event.
+ *
+ * @retval    NRF_SUCCESS     Successful registration.
+ * @retval    NRF_ERROR_NULL  Null pointer provided as input.
+ */
+uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler);
+
+
+// Functions for connecting the Stack Event Handler to the scheduler:
+/**@cond NO_DOXYGEN */
+void intern_softdevice_events_execute(void);
+
+
+/**@endcond */
+
+#endif // SOFTDEVICE_HANDLER_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "softdevice_handler_appsh.h"
+#include "app_scheduler.h"
+#include <string.h>
+
+void softdevice_evt_get(void * p_event_data, uint16_t event_size)
+{
+    APP_ERROR_CHECK_BOOL(event_size == 0);
+    intern_softdevice_events_execute();
+}
+
+uint32_t softdevice_evt_schedule(void)
+{
+    return app_sched_event_put(NULL, 0, softdevice_evt_get);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 SOFTDEVICE_HANDLER_APPSH_H
+#define SOFTDEVICE_HANDLER_APPSH_H
+
+#include "softdevice_handler.h"
+#include <stdint.h>
+
+#define SOFTDEVICE_HANDLER_APPSH_INIT(CLOCK_SOURCE,USE_SCHEDULER) \
+    SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE,(USE_SCHEDULER) ? softdevice_evt_schedule : NULL)
+
+uint32_t softdevice_evt_schedule(void);
+
+#endif //SOFTDEVICE_HANDLER_APPSH_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_COMMON BLE SoftDevice Common
+  @{
+  @defgroup ble_api Events, type definitions and API calls
+  @{
+
+  @brief Module independent events, type definitions and API calls for the BLE SoftDevice.
+
+ */
+
+#ifndef BLE_H__
+#define BLE_H__
+
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_gap.h"
+#include "ble_l2cap.h"
+#include "ble_gatt.h"
+#include "ble_gattc.h"
+#include "ble_gatts.h"
+
+/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief Common API SVC numbers.
+ */
+enum BLE_COMMON_SVCS
+{
+  SD_BLE_ENABLE = BLE_SVC_BASE,         /**< Enable and initialize the BLE stack */
+  SD_BLE_EVT_GET,                       /**< Get an event from the pending events queue. */
+  SD_BLE_TX_BUFFER_COUNT_GET,           /**< Get the total number of available application transmission buffers from the BLE stack. */
+  SD_BLE_UUID_VS_ADD,                   /**< Add a Vendor Specific UUID. */
+  SD_BLE_UUID_DECODE,                   /**< Decode UUID bytes. */
+  SD_BLE_UUID_ENCODE,                   /**< Encode UUID bytes. */
+  SD_BLE_VERSION_GET,                   /**< Get the local version information (company id, Link Layer Version, Link Layer Subversion). */
+  SD_BLE_USER_MEM_REPLY,                /**< User Memory Reply. */
+  SD_BLE_OPT_SET,                       /**< Set a BLE option. */
+  SD_BLE_OPT_GET,                       /**< Get a BLE option. */
+};
+
+/**
+ * @brief BLE Module Independent Event IDs.
+ */
+enum BLE_COMMON_EVTS
+{
+  BLE_EVT_TX_COMPLETE  = BLE_EVT_BASE,  /**< Transmission Complete. @ref ble_evt_tx_complete_t */
+  BLE_EVT_USER_MEM_REQUEST,             /**< User Memory request. @ref ble_evt_user_mem_request_t */
+  BLE_EVT_USER_MEM_RELEASE              /**< User Memory release. @ref ble_evt_user_mem_release_t */
+};
+
+/**@brief Common Option IDs.
+ * IDs that uniquely identify a common option.
+ */
+enum BLE_COMMON_OPTS
+{
+  BLE_COMMON_OPT_RADIO_CPU_MUTEX = BLE_OPT_BASE    /**< Radio CPU mutex option. @ref ble_common_opt_radio_cpu_mutex_t */
+};
+/** @} */
+
+/** @addtogroup BLE_COMMON_DEFINES Defines
+ * @{ */
+
+/** @brief  Required pointer alignment for BLE Events.
+*/
+#define BLE_EVTS_PTR_ALIGNMENT    4
+
+/** @defgroup BLE_USER_MEM_TYPES User Memory Types
+ * @{ */
+#define BLE_USER_MEM_TYPE_INVALID               0x00  /**< Invalid User Memory Types. */
+#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES   0x01  /**< User Memory for GATTS queued writes. */
+/** @} */
+
+/** @brief  Maximum number of Vendor Specific UUIDs.
+*/
+#define BLE_UUID_VS_MAX_COUNT     10
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_STRUCTURES Structures
+ * @{ */
+
+/**@brief User Memory Block. */
+typedef struct
+{
+  uint8_t          *p_mem;      /**< Pointer to the start of the user memory block. */
+  uint16_t          len;        /**< Length in bytes of the user memory block. */
+} ble_user_mem_block_t;
+
+/**
+ * @brief Event structure for @ref BLE_EVT_TX_COMPLETE.
+ */
+typedef struct
+{
+  uint8_t count;                        /**< Number of packets transmitted. */
+} ble_evt_tx_complete_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
+typedef struct
+{
+  uint8_t                     type;     /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+} ble_evt_user_mem_request_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
+typedef struct
+{
+  uint8_t                     type;       /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+  ble_user_mem_block_t        mem_block;  /**< User memory block */
+} ble_evt_user_mem_release_t;
+
+
+/**@brief Event structure for events not associated with a specific function module. */
+typedef struct
+{
+  uint16_t conn_handle;                 /**< Connection Handle on which this event occurred. */
+  union
+  {
+    ble_evt_tx_complete_t           tx_complete;        /**< Transmission Complete. */
+    ble_evt_user_mem_request_t      user_mem_request;   /**< User Memory Request Event Parameters. */
+    ble_evt_user_mem_release_t      user_mem_release;   /**< User Memory Release Event Parameters. */
+  } params;
+} ble_common_evt_t;
+
+/**@brief BLE Event header. */
+typedef struct
+{
+  uint16_t evt_id;                      /**< Value from a BLE_<module>_EVT series. */
+  uint16_t evt_len;                     /**< Length in octets excluding this header. */
+} ble_evt_hdr_t;
+
+/**@brief Common BLE Event type, wrapping the module specific event reports. */
+typedef struct
+{
+  ble_evt_hdr_t header;                 /**< Event header. */
+  union
+  {
+    ble_common_evt_t  common_evt;         /**< Common Event, evt_id in BLE_EVT_* series. */
+    ble_gap_evt_t     gap_evt;            /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
+    ble_l2cap_evt_t   l2cap_evt;          /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
+    ble_gattc_evt_t   gattc_evt;          /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
+    ble_gatts_evt_t   gatts_evt;          /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
+  } evt;
+} ble_evt_t;
+
+
+/**
+ * @brief Version Information.
+ */
+typedef struct
+{
+  uint8_t   version_number;             /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */
+  uint16_t  company_id;                 /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
+  uint16_t  subversion_number;          /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
+} ble_version_t;
+
+/**@brief Mutual exclusion of radio activity and CPU execution.
+ *
+ *        This option configures the application's access to the CPU when the radio is active. The
+ *        application can configure itself to be blocked from using the CPU while the radio is
+ *        active. By default, the application will be able to share CPU time with the SoftDevice
+ *        during radio activity. This parameter structure is used together with @ref sd_ble_opt_set
+ *        to configure the @ref BLE_COMMON_OPT_RADIO_CPU_MUTEX option.
+ *
+ * @note  Note that the application should use this option to configure the SoftDevice to block the
+ *        CPU during radio activity (i.e enable mutual exclusion) when running the SoftDevice on
+ *        hardware affected by PAN #44 "CCM may exceed real time requirements"and PAN #45 "AAR may
+ *        exceed real time requirements".
+ *
+ * @note  Note that when acting as a scanner, the mutex is only enabled for radio TX activity.
+ *
+ * @note  @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+  uint8_t enable : 1;                          /**< Enable mutual exclusion of radio activity and the CPU execution. */
+} ble_common_opt_radio_cpu_mutex_t;
+
+/**@brief Option structure for common options. */
+typedef union
+{
+  ble_common_opt_radio_cpu_mutex_t  radio_cpu_mutex;        /**< Parameters for the option for the mutual exclusion of radio activity and CPU execution. */
+} ble_common_opt_t;
+
+/**@brief Common BLE Option type, wrapping the module specific options. */
+typedef union
+{
+  ble_common_opt_t  common_opt;         /**< Common option, opt_id in BLE_COMMON_OPT_* series. */
+  ble_gap_opt_t     gap_opt;            /**< GAP option, opt_id in BLE_GAP_OPT_* series. */
+} ble_opt_t;
+
+/**
+ * @brief BLE GATTS init options
+ */
+typedef struct
+{
+  ble_gatts_enable_params_t  gatts_enable_params; /**< GATTS init options @ref ble_gatts_enable_params_t. */
+} ble_enable_params_t;
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enable the BLE stack
+ *
+ * @param[in] p_ble_enable_params Pointer to ble_enable_params_t
+ *
+ * @details This call initializes the BLE stack, no other BLE related function can be called before this one.
+ *
+ * @return @ref NRF_SUCCESS BLE the BLE stack has been initialized successfully
+ * @retval @ref NRF_ERROR_INVALID_STATE the BLE stack had already been initialized and cannot be reinitialized.
+ * @return @ref NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @return @ref NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4.
+ *                                       The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
+ * @return @ref NRF_ERROR_NO_MEM         The Attribute Table size is too large. Decrease size in @ref ble_gatts_enable_params_t.
+ */
+SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params));
+
+/**@brief Get an event from the pending events queue.
+ *
+ * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. This buffer <b>must be 4-byte aligned in memory</b>.
+ * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
+ *
+ * @details This call allows the application to pull a BLE event from the BLE stack. The application is signalled that an event is 
+ * available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
+ * The application is free to choose whether to call this function from thread mode (main context) or directly from the Interrupt Service Routine
+ * that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher priority than the application, this function should be called
+ * in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. 
+ * Failure to do so could potentially leave events in the internal queue without the application being aware of this fact.
+ * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to be copied into
+ * application memory. If the buffer provided is not large enough to fit the entire contents of the event, @ref NRF_ERROR_DATA_SIZE will be returned
+ * and the application can then call again with a larger buffer size.
+ * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large enough to fit certain events, 
+ * and so it is the application's responsibility to provide an amount of memory large enough so that the relevant event is copied in full.
+ * The application may "peek" the event length by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return.
+ *
+ * @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT
+ *
+ * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
+ * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
+ */
+SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
+
+
+/**@brief Get the total number of available application transmission buffers per link in the BLE stack.
+ *
+ * @details This call allows the application to obtain the total number of
+ *          transmission buffers available per link for application data. Please note that
+ *          this does not give the number of free buffers, but rather the total amount of them.
+ *          The application has two options to handle its own application transmission buffers:
+ *          - Use a simple arithmetic calculation: at boot time the application should use this function
+ *          to find out the total amount of buffers available to it and store it in a variable.
+ *          Every time a packet that consumes an application buffer is sent using any of the 
+ *          exposed functions in this BLE API, the application should decrement that variable.
+ *          Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event is received by the application
+ *          it should retrieve the count field in such event and add that number to the same
+ *          variable storing the number of available packets.
+ *          This mechanism allows the application to be aware at any time of the number of
+ *          application packets available in the BLE stack's internal buffers, and therefore
+ *          it can know with certainty whether it is possible to send more data or it has to
+ *          wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds.
+ *          - Choose to simply not keep track of available buffers at all, and instead handle the 
+ *          @ref BLE_ERROR_NO_TX_BUFFERS error by queueing the packet to be transmitted and 
+ *          try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives.
+ *
+ *          The API functions that <b>may</b> consume an application buffer depending on 
+ *          the parameters supplied to them can be found below:
+ *
+ *          - @ref sd_ble_gattc_write (write without response only)
+ *          - @ref sd_ble_gatts_hvx (notifications only)
+ *          - @ref sd_ble_l2cap_tx (all packets)
+ *
+ * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission buffers upon
+ *                     successful return.
+ *
+ * @retval ::NRF_SUCCESS Number of application transmission buffers retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t *p_count));
+
+
+/**@brief Add a Vendor Specific UUID.
+ *
+ * @details This call enables the application to add a vendor specific UUID to the BLE stack's table,
+ *          for later use all other modules and APIs. This then allows the application to use the shorter,
+ *          24-bit @ref ble_uuid_t format when dealing with both 16-bit and 128-bit UUIDs without having to
+ *          check for lengths and having split code paths. The way that this is accomplished is by extending the 
+ *          grouping mechanism that the Bluetooth SIG standard base UUID uses for all other 128-bit UUIDs. The 
+ *          type field in the @ref ble_uuid_t structure is an index (relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN) 
+ *          to the table populated by multiple calls to this function, and the uuid field in the same structure 
+ *          contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to the 
+ *          application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, 
+ *          although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
+ *
+ * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by 
+ * the 16-bit uuid field in @ref ble_uuid_t.
+ *
+ *
+ * @param[in]  p_vs_uuid    Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
+ *                          bytes 12 and 13.
+ * @param[out] p_uuid_type  Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
+ * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
+ * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
+ * @retval ::NRF_ERROR_FORBIDDEN If p_vs_uuid has already been added to the VS UUID table.
+ */
+SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
+
+
+/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
+ * 
+ * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared 
+ * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add 
+ * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index 
+ * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. 
+ *
+ * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
+ *
+ * @param[in]      uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
+ * @param[in]      p_uuid_le   Pointer pointing to little endian raw UUID bytes.
+ * @param[out]  p_uuid      Pointer to a @ref ble_uuid_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
+ * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
+ */                                                 
+SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
+
+
+/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
+ *
+ * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
+ *
+ * @param[in]      p_uuid        Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
+ * @param[out]     p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
+ * @param[out]     p_uuid_le     Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully encoded into the buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
+ */
+SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
+
+
+/**@brief Get Version Information.
+ *
+ * @details This call allows the application to get the BLE stack version information.
+ *
+ * @param[out] p_version Pointer to a ble_version_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS  Version information stored successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
+ */
+SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
+
+
+/**@brief Provide a user memory block.
+ *
+ * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in,out] p_block Pointer to a user memory block structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
+
+/**@brief Set a BLE option.
+ *
+ * @details This call allows the application to set the value of an option.
+ *
+ * @param[in] opt_id Option ID.
+ * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
+ *
+ * @retval ::NRF_SUCCESS  Option set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ */
+SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
+
+
+/**@brief Get a BLE option.
+ *
+ * @details This call allows the application to retrieve the value of an option.
+ *
+ * @param[in] opt_id Option ID.
+ * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS  Option retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
+ *
+ */
+SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
+
+/** @} */
+
+#endif /* BLE_H__ */
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_err.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_COMMON
+  @{
+  @addtogroup  nrf_error
+  @{
+    @ingroup BLE_COMMON
+  @}
+
+  @defgroup ble_err General error codes
+  @{
+
+  @brief General error code definitions for the BLE API.
+
+  @ingroup BLE_COMMON
+*/
+#ifndef NRF_BLE_ERR_H__
+#define NRF_BLE_ERR_H__
+
+#include "nrf_error.h"
+
+/* @defgroup BLE_ERRORS Error Codes
+ * @{ */
+#define BLE_ERROR_NOT_ENABLED            (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
+#define BLE_ERROR_INVALID_CONN_HANDLE    (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
+#define BLE_ERROR_INVALID_ATTR_HANDLE    (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
+#define BLE_ERROR_NO_TX_BUFFERS          (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */
+#define BLE_ERROR_INVALID_ROLE           (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
+/** @} */
+
+
+/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
+ *  @brief Assignment of subranges for module specific error codes.
+ *  @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
+ * @{ */
+#define NRF_L2CAP_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
+#define NRF_GAP_ERR_BASE               (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
+#define NRF_GATTC_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
+#define NRF_GATTS_ERR_BASE             (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
+/** @} */
+
+#endif
+
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1362 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_GAP Generic Access Profile (GAP)
+  @{
+  @brief Definitions and prototypes for the GAP interface.
+ */
+
+#ifndef BLE_GAP_H__
+#define BLE_GAP_H__
+
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "nrf_svc.h"
+
+/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GAP API SVC numbers.
+ */
+enum BLE_GAP_SVCS
+{
+  SD_BLE_GAP_ADDRESS_SET  = BLE_GAP_SVC_BASE,  /**< Set own Bluetooth Address. */
+  SD_BLE_GAP_ADDRESS_GET,                      /**< Get own Bluetooth Address. */
+  SD_BLE_GAP_ADV_DATA_SET,                     /**< Set Advertising Data. */
+  SD_BLE_GAP_ADV_START,                        /**< Start Advertising. */
+  SD_BLE_GAP_ADV_STOP,                         /**< Stop Advertising. */
+  SD_BLE_GAP_CONN_PARAM_UPDATE,                /**< Connection Parameter Update. */
+  SD_BLE_GAP_DISCONNECT,                       /**< Disconnect. */
+  SD_BLE_GAP_TX_POWER_SET,                     /**< Set TX Power. */
+  SD_BLE_GAP_APPEARANCE_SET,                   /**< Set Appearance. */
+  SD_BLE_GAP_APPEARANCE_GET,                   /**< Get Appearance. */
+  SD_BLE_GAP_PPCP_SET,                         /**< Set PPCP. */
+  SD_BLE_GAP_PPCP_GET,                         /**< Get PPCP. */
+  SD_BLE_GAP_DEVICE_NAME_SET,                  /**< Set Device Name. */
+  SD_BLE_GAP_DEVICE_NAME_GET,                  /**< Get Device Name. */
+  SD_BLE_GAP_AUTHENTICATE,                     /**< Initiate Pairing/Bonding. */
+  SD_BLE_GAP_SEC_PARAMS_REPLY,                 /**< Reply with Security Parameters. */
+  SD_BLE_GAP_AUTH_KEY_REPLY,                   /**< Reply with an authentication key. */
+  SD_BLE_GAP_ENCRYPT,                          /**< Initiate encryption procedure. */
+  SD_BLE_GAP_SEC_INFO_REPLY,                   /**< Reply with Security Information. */
+  SD_BLE_GAP_CONN_SEC_GET,                     /**< Obtain connection security level. */
+  SD_BLE_GAP_RSSI_START,                       /**< Start reporting of changes in RSSI. */ 
+  SD_BLE_GAP_RSSI_STOP,                        /**< Stop reporting of changes in RSSI. */ 
+  SD_BLE_GAP_SCAN_START,                       /**< Start Scanning. */
+  SD_BLE_GAP_SCAN_STOP,                        /**< Stop Scanning. */
+  SD_BLE_GAP_CONNECT,                          /**< Connect. */
+  SD_BLE_GAP_CONNECT_CANCEL,                   /**< Cancel ongoing connection procedure. */
+  SD_BLE_GAP_RSSI_GET,                         /**< Get the last RSSI sample. */
+};
+
+/**@brief GAP Event IDs.
+ * IDs that uniquely identify an event coming from the stack to the application.
+ */
+enum BLE_GAP_EVTS
+{
+  BLE_GAP_EVT_CONNECTED  = BLE_GAP_EVT_BASE,    /**< Connection established. @ref ble_gap_evt_connected_t */
+  BLE_GAP_EVT_DISCONNECTED,                     /**< Disconnected from peer. @ref ble_gap_evt_disconnected_t */
+  BLE_GAP_EVT_CONN_PARAM_UPDATE,                /**< Connection Parameters updated. ble_gap_evt_conn_param_update_t */
+  BLE_GAP_EVT_SEC_PARAMS_REQUEST,               /**< Request to provide security parameters. @ref ble_gap_evt_sec_params_request_t */
+  BLE_GAP_EVT_SEC_INFO_REQUEST,                 /**< Request to provide security information. @ref ble_gap_evt_sec_info_request_t */
+  BLE_GAP_EVT_PASSKEY_DISPLAY,                  /**< Request to display a passkey to the user. @ref ble_gap_evt_passkey_display_t */
+  BLE_GAP_EVT_AUTH_KEY_REQUEST,                 /**< Request to provide an authentication key. @ref ble_gap_evt_auth_key_request_t */
+  BLE_GAP_EVT_AUTH_STATUS,                      /**< Authentication procedure completed with status. @ref ble_gap_evt_auth_status_t */
+  BLE_GAP_EVT_CONN_SEC_UPDATE,                  /**< Connection security updated. @ref ble_gap_evt_conn_sec_update_t */
+  BLE_GAP_EVT_TIMEOUT,                          /**< Timeout expired. @ref ble_gap_evt_timeout_t */
+  BLE_GAP_EVT_RSSI_CHANGED,                     /**< RSSI report. @ref ble_gap_evt_rssi_changed_t */
+  BLE_GAP_EVT_ADV_REPORT,                       /**< Advertising report. @ref ble_gap_evt_adv_report_t */
+  BLE_GAP_EVT_SEC_REQUEST,                      /**< Security Request. @ref ble_gap_evt_sec_request_t */
+  BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST,        /**< Connection Parameter Update Request. @ref ble_gap_evt_conn_param_update_request_t */
+  BLE_GAP_EVT_SCAN_REQ_REPORT,                  /**< Scan request report. @ref ble_gap_evt_scan_req_report_t */
+};
+
+/**@brief GAP Option IDs.
+ * IDs that uniquely identify a GAP option.
+ */
+enum BLE_GAP_OPTS
+{
+  BLE_GAP_OPT_CH_MAP  = BLE_GAP_OPT_BASE,       /**< Channel Map. @ref ble_gap_opt_ch_map_t  */
+  BLE_GAP_OPT_LOCAL_CONN_LATENCY,               /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */
+  BLE_GAP_OPT_PASSKEY,                          /**< Set passkey. @ref ble_gap_opt_passkey_t */
+  BLE_GAP_OPT_PRIVACY,                          /**< Custom privacy. @ref ble_gap_opt_privacy_t */
+  BLE_GAP_OPT_SCAN_REQ_REPORT,                  /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */
+  BLE_GAP_OPT_COMPAT_MODE                       /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */
+};
+/** @} */
+
+/**@addtogroup BLE_GAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP
+ * @{ */
+#define BLE_ERROR_GAP_UUID_LIST_MISMATCH            (NRF_GAP_ERR_BASE + 0x000)  /**< UUID list does not contain an integral number of UUIDs. */
+#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST   (NRF_GAP_ERR_BASE + 0x001)  /**< Use of Whitelist not permitted with discoverable advertising. */
+#define BLE_ERROR_GAP_INVALID_BLE_ADDR              (NRF_GAP_ERR_BASE + 0x002)  /**< The upper two bits of the address do not correspond to the specified address type. */
+#define BLE_ERROR_GAP_WHITELIST_IN_USE              (NRF_GAP_ERR_BASE + 0x003)  /**< Attempt to overwrite the whitelist while already in use by another operation. */ 
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLES GAP Roles
+ * @note Not explicitly used in peripheral API, but will be relevant for central API.
+ * @{ */
+#define BLE_GAP_ROLE_INVALID     0x0            /**< Invalid Role. */
+#define BLE_GAP_ROLE_PERIPH      0x1            /**< Peripheral Role. */
+#define BLE_GAP_ROLE_CENTRAL     0x2            /**< Central Role. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources
+ * @{ */
+#define BLE_GAP_TIMEOUT_SRC_ADVERTISING                0x00 /**< Advertising timeout. */
+#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST           0x01 /**< Security request timeout. */
+#define BLE_GAP_TIMEOUT_SRC_SCAN                       0x02 /**< Scanning timeout. */
+#define BLE_GAP_TIMEOUT_SRC_CONN                       0x03 /**< Connection timeout. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types
+ * @{ */
+#define BLE_GAP_ADDR_TYPE_PUBLIC                        0x00 /**< Public address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC                 0x01 /**< Random Static address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE     0x02 /**< Private Resolvable address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Private Non-Resolvable address. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADDR_CYCLE_MODES GAP Address cycle modes
+ * @{ */
+#define BLE_GAP_ADDR_CYCLE_MODE_NONE      0x00 /**< Set addresses directly, no automatic address cycling. */
+#define BLE_GAP_ADDR_CYCLE_MODE_AUTO      0x01 /**< Automatically generate and update private addresses. */
+/** @} */
+
+/**@brief The default interval in seconds at which a private address is refreshed when address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO.  */
+#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (60 * 15)
+
+/** @brief BLE address length. */
+#define BLE_GAP_ADDR_LEN            6
+
+
+/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
+ * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
+ * @{ */
+#define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */
+#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */
+#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */
+#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */
+#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */
+#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */
+#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */
+#define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */
+#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */ 
+#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */
+#define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */
+#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */
+#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
+ * @{ */
+#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE         (0x01)   /**< LE Limited Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE         (0x02)   /**< LE General Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED         (0x04)   /**< BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER         (0x08)   /**< Simultaneous LE and BR/EDR, Controller. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST               (0x10)   /**< Simultaneous LE and BR/EDR, Host. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE   (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)   /**< LE Limited Discoverable Mode, BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE   (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)   /**< LE General Discoverable Mode, BR/EDR not supported. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min
+ * @{ */
+#define BLE_GAP_ADV_INTERVAL_MIN        0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */
+#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */
+#define BLE_GAP_ADV_INTERVAL_MAX        0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */
+ /**@}  */
+
+
+/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min
+ * @{ */
+#define BLE_GAP_SCAN_INTERVAL_MIN       0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_INTERVAL_MAX       0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */
+ /** @}  */
+
+
+/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min
+ * @{ */
+#define BLE_GAP_SCAN_WINDOW_MIN         0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_WINDOW_MAX         0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */
+ /** @}  */
+
+
+/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min
+ * @{ */
+#define BLE_GAP_SCAN_TIMEOUT_MIN        0x0001 /**< Minimum Scan timeout in seconds. */
+#define BLE_GAP_SCAN_TIMEOUT_MAX        0xFFFF /**< Maximum Scan timeout in seconds. */
+ /** @}  */
+
+
+/**@brief Maximum size of advertising data in octets. */
+#define  BLE_GAP_ADV_MAX_SIZE           31
+
+
+/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types
+ * @{ */
+#define BLE_GAP_ADV_TYPE_ADV_IND          0x00   /**< Connectable undirected. */
+#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND   0x01   /**< Connectable directed. */
+#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND     0x02   /**< Scannable undirected. */
+#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND  0x03   /**< Non connectable undirected. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies
+ * @{ */
+#define BLE_GAP_ADV_FP_ANY                0x00   /**< Allow scan requests and connect requests from any device. */
+#define BLE_GAP_ADV_FP_FILTER_SCANREQ     0x01   /**< Filter scan requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_CONNREQ     0x02   /**< Filter connect requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_BOTH        0x03   /**< Filter both scan and connect requests with whitelist. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values
+ * @{ */
+#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX      180 /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180s). */
+#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED  0 /**< Unlimited advertising in general discoverable mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes
+ * @{ */
+#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE  0x00   /**< Not discoverable discovery Mode. */
+#define BLE_GAP_DISC_MODE_LIMITED           0x01   /**< Limited Discovery Mode. */
+#define BLE_GAP_DISC_MODE_GENERAL           0x02   /**< General Discovery Mode. */
+/**@} */
+
+/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities
+ * @{ */
+#define BLE_GAP_IO_CAPS_DISPLAY_ONLY      0x00   /**< Display Only. */
+#define BLE_GAP_IO_CAPS_DISPLAY_YESNO     0x01   /**< Display and Yes/No entry. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY     0x02   /**< Keyboard Only. */
+#define BLE_GAP_IO_CAPS_NONE              0x03   /**< No I/O capabilities. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY  0x04   /**< Keyboard and Display. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types
+ * @{ */
+#define BLE_GAP_AUTH_KEY_TYPE_NONE        0x00   /**< No key (may be used to reject). */
+#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY     0x01   /**< 6-digit Passkey. */
+#define BLE_GAP_AUTH_KEY_TYPE_OOB         0x02   /**< Out Of Band data. */
+/**@} */
+
+/**@defgroup BLE_GAP_SEC_STATUS GAP Security status
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SUCCESS                0x00  /**< Procedure completed with success. */
+#define BLE_GAP_SEC_STATUS_TIMEOUT                0x01  /**< Procedure timed out. */
+#define BLE_GAP_SEC_STATUS_PDU_INVALID            0x02  /**< Invalid PDU received. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN       0x03  /**< Reserved for Future Use range #1 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END         0x80  /**< Reserved for Future Use range #1 end. */
+#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED   0x81  /**< Passkey entry failed (user cancelled or other). */
+#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE      0x82  /**< Out of Band Key not available. */
+#define BLE_GAP_SEC_STATUS_AUTH_REQ               0x83  /**< Authentication requirements not met. */
+#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE          0x84  /**< Confirm value failed. */
+#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP       0x85  /**< Pairing not supported.  */
+#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE           0x86  /**< Encryption key size. */
+#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED    0x87  /**< Unsupported SMP command. */
+#define BLE_GAP_SEC_STATUS_UNSPECIFIED            0x88  /**< Unspecified reason. */
+#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS      0x89  /**< Too little time elapsed since last attempt. */
+#define BLE_GAP_SEC_STATUS_INVALID_PARAMS         0x8A  /**< Invalid parameters. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN       0x8B  /**< Reserved for Future Use range #2 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END         0xFF  /**< Reserved for Future Use range #2 end. */
+/**@} */
+
+/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL           0x00  /**< Local failure. */
+#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE          0x01  /**< Remote failure. */
+/**@} */
+
+/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits
+ * @{ */
+#define BLE_GAP_CP_MIN_CONN_INTVL_NONE           0xFFFF  /**< No new minimum connction interval specified in connect parameters. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MIN            0x0006  /**< Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MAX            0x0C80  /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_NONE           0xFFFF  /**< No new maximum connction interval specified in connect parameters. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MIN            0x0006  /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MAX            0x0C80  /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_SLAVE_LATENCY_MAX             0x01F3  /**< Highest slave latency permitted, in connection events. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE         0xFFFF  /**< No new supervision timeout specified in connect parameters. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN          0x000A  /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX          0x0C80  /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */
+/**@} */
+
+
+/**@brief GAP device name maximum length. */
+#define BLE_GAP_DEVNAME_MAX_LEN           31
+
+/**@brief Disable RSSI events for connections */
+#define BLE_GAP_RSSI_THRESHOLD_INVALID    0xFF
+
+/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
+ *
+ * See @ref ble_gap_conn_sec_mode_t.
+ * @{ */
+/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr)         do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr)              do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr)       do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr)     do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr)    do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr)  do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
+/**@} */
+
+
+/**@brief GAP Security Random Number Length. */
+#define BLE_GAP_SEC_RAND_LEN 8
+
+/**@brief GAP Security Key Length. */
+#define BLE_GAP_SEC_KEY_LEN 16
+
+/**@brief GAP Passkey Length. */
+#define BLE_GAP_PASSKEY_LEN 6
+
+/**@brief Maximum amount of addresses in a whitelist. */
+#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8)
+
+/**@brief Maximum amount of IRKs in a whitelist.
+ * @note  The number of IRKs is limited to 8, even if the hardware supports more.
+ */
+#define BLE_GAP_WHITELIST_IRK_MAX_COUNT (8)
+
+/**@defgroup GAP_SEC_MODES GAP Security Modes
+ * @{ */
+#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */
+/**@} */
+
+/**@} */
+
+/**@addtogroup BLE_GAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Bluetooth Low Energy address. */
+typedef struct
+{
+  uint8_t addr_type;                    /**< See @ref BLE_GAP_ADDR_TYPES. */
+  uint8_t addr[BLE_GAP_ADDR_LEN];       /**< 48-bit address, LSB format. */
+} ble_gap_addr_t;
+
+
+/**@brief GAP connection parameters.
+ *
+ * @note  When ble_conn_params_t is received in an event, both min_conn_interval and
+ *        max_conn_interval will be equal to the connection interval set by the central.
+ *
+ * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:
+ *       conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval
+ *       that corresponds to the following Bluetooth Spec requirement:
+ *       The Supervision_Timeout in milliseconds shall be larger than
+ *       (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
+ */
+typedef struct
+{
+  uint16_t min_conn_interval;         /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+  uint16_t max_conn_interval;         /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+  uint16_t slave_latency;             /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+  uint16_t conn_sup_timeout;          /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+} ble_gap_conn_params_t;
+
+
+/**@brief GAP connection security modes.
+ *
+ * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n
+ * Security Mode 1 Level 1: No security is needed (aka open link).\n
+ * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n
+ * Security Mode 1 Level 3: MITM protected encrypted link required.\n
+ * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n
+ * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n
+ */
+typedef struct
+{
+  uint8_t sm : 4;                     /**< Security Mode (1 or 2), 0 for no permissions at all. */
+  uint8_t lv : 4;                     /**< Level (1, 2 or 3), 0 for no permissions at all. */
+
+} ble_gap_conn_sec_mode_t;
+
+
+/**@brief GAP connection security status.*/
+typedef struct
+{
+  ble_gap_conn_sec_mode_t sec_mode;           /**< Currently active security mode for this connection.*/
+  uint8_t                 encr_key_size;      /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */
+} ble_gap_conn_sec_t;
+
+
+/**@brief Identity Resolving Key. */
+typedef struct
+{
+  uint8_t irk[BLE_GAP_SEC_KEY_LEN];   /**< Array containing IRK. */
+} ble_gap_irk_t;
+
+
+/**@brief Whitelist structure. */
+typedef struct
+{
+  ble_gap_addr_t    **pp_addrs;        /**< Pointer to an array of device address pointers, pointing to addresses to be used in whitelist. NULL if none are given. */
+  uint8_t             addr_count;      /**< Count of device addresses in array, up to @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. */
+  ble_gap_irk_t     **pp_irks;         /**< Pointer to an array of Identity Resolving Key (IRK) pointers, each pointing to an IRK in the whitelist. NULL if none are given. */
+  uint8_t             irk_count;       /**< Count of IRKs in array, up to @ref BLE_GAP_WHITELIST_IRK_MAX_COUNT. */
+} ble_gap_whitelist_t;
+
+/**@brief Channel mask for RF channels used in advertising and scanning. */ 
+typedef struct
+{
+  uint8_t ch_37_off : 1;  /**< Setting this bit to 1 will turn off advertising on channel 37 */
+  uint8_t ch_38_off : 1;  /**< Setting this bit to 1 will turn off advertising on channel 38 */
+  uint8_t ch_39_off : 1;  /**< Setting this bit to 1 will turn off advertising on channel 39 */
+} ble_gap_adv_ch_mask_t;
+
+/**@brief GAP advertising parameters.*/
+typedef struct
+{
+  uint8_t               type;                 /**< See @ref BLE_GAP_ADV_TYPES. */
+  ble_gap_addr_t       *p_peer_addr;          /**< For @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND mode only, known peer address. */
+  uint8_t               fp;                   /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */
+  ble_gap_whitelist_t  *p_whitelist;          /**< Pointer to whitelist, NULL if no whitelist or the current active whitelist is to be used. */
+  uint16_t              interval;             /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s), see @ref BLE_GAP_ADV_INTERVALS.
+                                                   - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising.
+                                                   - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/
+  uint16_t              timeout;              /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */
+  ble_gap_adv_ch_mask_t channel_mask;         /**< Advertising channel mask. @see ble_gap_channel_mask_t for documentation. */
+} ble_gap_adv_params_t;
+
+
+/**@brief GAP scanning parameters. */
+typedef struct
+{
+  uint8_t                 active    : 1;        /**< If 1, perform active scanning (scan requests). */
+  uint8_t                 selective : 1;        /**< If 1, ignore unknown devices (non whitelisted). */
+  ble_gap_whitelist_t *   p_whitelist;          /**< Pointer to whitelist, NULL if no whitelist or the current active whitelist is to be used. */
+  uint16_t                interval;             /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+  uint16_t                window;               /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+  uint16_t                timeout;              /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+} ble_gap_scan_params_t;
+
+
+/** @brief Keys that can be exchanged during a bonding procedure. */
+typedef struct
+{
+  uint8_t enc     : 1;                        /**< Long Term Key and Master Identification. */
+  uint8_t id      : 1;                        /**< Identity Resolving Key and Identity Address Information. */
+  uint8_t sign    : 1;                        /**< Connection Signature Resolving Key. */
+} ble_gap_sec_kdist_t;
+
+
+/**@brief GAP security parameters. */
+typedef struct
+{
+  uint8_t               bond    : 1;               /**< Perform bonding. */
+  uint8_t               mitm    : 1;               /**< Man In The Middle protection required. */
+  uint8_t               io_caps : 3;               /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
+  uint8_t               oob     : 1;               /**< Out Of Band data available. */
+  uint8_t               min_key_size;              /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
+  uint8_t               max_key_size;              /**< Maximum encryption key size in octets between min_key_size and 16. */
+  ble_gap_sec_kdist_t   kdist_periph;              /**< Key distribution bitmap: keys that the peripheral device will distribute. */
+  ble_gap_sec_kdist_t   kdist_central;             /**< Key distribution bitmap: keys that the central device will distribute. */
+} ble_gap_sec_params_t;
+
+
+/**@brief GAP Encryption Information. */
+typedef struct
+{
+  uint8_t   ltk[BLE_GAP_SEC_KEY_LEN];   /**< Long Term Key. */
+  uint8_t   auth : 1;                   /**< Authenticated Key. */
+  uint8_t   ltk_len : 7;                /**< LTK length in octets. */
+} ble_gap_enc_info_t;
+
+
+/**@brief GAP Master Identification. */
+typedef struct
+{
+  uint16_t  ediv;                       /**< Encrypted Diversifier. */
+  uint8_t   rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */
+} ble_gap_master_id_t;
+
+
+/**@brief GAP Signing Information. */
+typedef struct
+{
+  uint8_t   csrk[BLE_GAP_SEC_KEY_LEN];        /**< Connection Signature Resolving Key. */
+} ble_gap_sign_info_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */
+typedef struct
+{
+  ble_gap_addr_t        peer_addr;              /**< Bluetooth address of the peer device. */
+  ble_gap_addr_t        own_addr;               /**< Bluetooth address of the local device used during connection setup. */
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+  uint8_t               role;                   /**< BLE role for this connection, see @ref BLE_GAP_ROLES */
+#endif
+  uint8_t               irk_match :1;           /**< If 1, peer device's address resolved using an IRK. */
+  uint8_t               irk_match_idx  :7;      /**< Index in IRK list where the address was matched. */
+  ble_gap_conn_params_t conn_params;            /**< GAP Connection Parameters. */
+} ble_gap_evt_connected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */
+typedef struct
+{
+  uint8_t reason;                               /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */
+} ble_gap_evt_disconnected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */
+typedef struct
+{
+  ble_gap_conn_params_t conn_params;            /**<  GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */
+typedef struct
+{
+  ble_gap_sec_params_t peer_params;             /**< Initiator Security Parameters. */
+} ble_gap_evt_sec_params_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */
+typedef struct
+{
+  ble_gap_addr_t      peer_addr;                     /**< Bluetooth address of the peer device. */
+  ble_gap_master_id_t master_id;                     /**< Master Identification for LTK lookup. */
+  uint8_t             enc_info  : 1;                 /**< If 1, Encryption Information required. */
+  uint8_t             id_info   : 1;                 /**< If 1, Identity Information required. */
+  uint8_t             sign_info : 1;                 /**< If 1, Signing Information required. */
+} ble_gap_evt_sec_info_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
+typedef struct
+{
+  uint8_t passkey[BLE_GAP_PASSKEY_LEN];         /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+} ble_gap_evt_passkey_display_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */
+typedef struct
+{
+  uint8_t key_type;                             /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */
+} ble_gap_evt_auth_key_request_t;
+
+
+/**@brief Security levels supported.
+ * @note See Bluetooth Specification Version 4.1 Volume 3, Part C, Chapter 10.
+*/
+typedef struct
+{
+  uint8_t lv1 : 1;                              /**< If 1: Level 1 is supported. */
+  uint8_t lv2 : 1;                              /**< If 1: Level 2 is supported. */
+  uint8_t lv3 : 1;                              /**< If 1: Level 3 is supported. */
+} ble_gap_sec_levels_t;
+
+
+/**@brief Encryption Key. */
+typedef struct
+{
+  ble_gap_enc_info_t    enc_info;             /**< Encryption Information. */
+  ble_gap_master_id_t   master_id;            /**< Master Identification. */
+} ble_gap_enc_key_t;
+
+
+/**@brief Identity Key. */
+typedef struct
+{
+  ble_gap_irk_t         id_info;              /**< Identity Information. */
+  ble_gap_addr_t        id_addr_info;         /**< Identity Address Information. */
+} ble_gap_id_key_t;
+
+
+/**@brief Security Keys. */
+typedef struct
+{
+  ble_gap_enc_key_t     *p_enc_key;           /**< Encryption Key, or NULL. */
+  ble_gap_id_key_t      *p_id_key;            /**< Identity Key, or NULL. */
+  ble_gap_sign_info_t   *p_sign_key;          /**< Signing Key, or NULL. */
+} ble_gap_sec_keys_t;
+
+
+/**@brief Security key set (both Peripheral and Central keys).
+ *         Note that when distributing Bluetooth addresses pertaining to the local device those
+ *         will have to be filled in by the user. */
+typedef struct
+{
+  ble_gap_sec_keys_t keys_periph;     /**< Keys distributed by the device in the Peripheral role. */
+  ble_gap_sec_keys_t keys_central;    /**< Keys distributed by the device in the Central role. */
+} ble_gap_sec_keyset_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */
+typedef struct
+{
+  uint8_t               auth_status;            /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */
+  uint8_t               error_src : 2;          /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+  uint8_t               bonded : 1;             /**< Procedure resulted in a bond. */
+  ble_gap_sec_levels_t  sm1_levels;             /**< Levels supported in Security Mode 1. */
+  ble_gap_sec_levels_t  sm2_levels;             /**< Levels supported in Security Mode 2. */
+  ble_gap_sec_kdist_t   kdist_periph;           /**< Bitmap stating which keys were exchanged (distributed) by the peripheral. */
+  ble_gap_sec_kdist_t   kdist_central;          /**< Bitmap stating which keys were exchanged (distributed) by the central. */
+} ble_gap_evt_auth_status_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */
+typedef struct
+{
+  ble_gap_conn_sec_t conn_sec;                  /**< Connection security level. */
+} ble_gap_evt_conn_sec_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */
+typedef struct
+{
+  uint8_t src;                                  /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */
+} ble_gap_evt_timeout_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */
+typedef struct
+{
+  int8_t  rssi;                               /**< Received Signal Strength Indication in dBm. */
+} ble_gap_evt_rssi_changed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */
+typedef struct
+{
+  ble_gap_addr_t peer_addr;                     /**< Bluetooth address of the peer device. */
+  int8_t         rssi;                          /**< Received Signal Strength Indication in dBm. */
+  uint8_t        scan_rsp : 1;                  /**< If 1, the report corresponds to a scan response and the type field may be ignored. */
+  uint8_t        type     : 2;                  /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */
+  uint8_t        dlen     : 5;                  /**< Advertising or scan response data length. */
+  uint8_t        data[BLE_GAP_ADV_MAX_SIZE];    /**< Advertising or scan response data. */
+} ble_gap_evt_adv_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */
+typedef struct
+{
+  uint8_t    bond    : 1;                       /**< Perform bonding. */
+  uint8_t    mitm    : 1;                       /**< Man In The Middle protection required. */
+} ble_gap_evt_sec_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */
+typedef struct
+{
+  ble_gap_conn_params_t conn_params;            /**<  GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */
+typedef struct
+{
+  int8_t                  rssi;              /**< Received Signal Strength Indication in dBm. */
+  ble_gap_addr_t          peer_addr;         /**< Bluetooth address of the peer device. */
+} ble_gap_evt_scan_req_report_t;
+
+
+
+/**@brief GAP event structure. */
+typedef struct
+{
+  uint16_t conn_handle;                                     /**< Connection Handle on which event occured. */
+  union                                                     /**< union alternative identified by evt_id in enclosing struct. */
+  {
+    ble_gap_evt_connected_t                   connected;                    /**< Connected Event Parameters. */
+    ble_gap_evt_disconnected_t                disconnected;                 /**< Disconnected Event Parameters. */
+    ble_gap_evt_conn_param_update_t           conn_param_update;            /**< Connection Parameter Update Parameters. */
+    ble_gap_evt_sec_params_request_t          sec_params_request;           /**< Security Parameters Request Event Parameters. */
+    ble_gap_evt_sec_info_request_t            sec_info_request;             /**< Security Information Request Event Parameters. */
+    ble_gap_evt_passkey_display_t             passkey_display;              /**< Passkey Display Event Parameters. */
+    ble_gap_evt_auth_key_request_t            auth_key_request;             /**< Authentication Key Request Event Parameters. */
+    ble_gap_evt_auth_status_t                 auth_status;                  /**< Authentication Status Event Parameters. */
+    ble_gap_evt_conn_sec_update_t             conn_sec_update;              /**< Connection Security Update Event Parameters. */
+    ble_gap_evt_timeout_t                     timeout;                      /**< Timeout Event Parameters. */
+    ble_gap_evt_rssi_changed_t                rssi_changed;                 /**< RSSI Event parameters. */
+    ble_gap_evt_adv_report_t                  adv_report;                   /**< Advertising Report Event Parameters. */
+    ble_gap_evt_sec_request_t                 sec_request;                  /**< Security Request Event Parameters. */
+    ble_gap_evt_conn_param_update_request_t   conn_param_update_request;    /**< Connection Parameter Update Parameters. */
+    ble_gap_evt_scan_req_report_t             scan_req_report;              /**< Scan Request Report parameters. */
+  } params;                                                                 /**< Event Parameters. */
+
+} ble_gap_evt_t;
+
+
+/**@brief Channel Map option.
+ *        Used with @ref sd_ble_opt_get to get the current channel map
+ *        or @ref sd_ble_opt_set to set a new channel map. When setting the
+ *        channel map, it applies to all current and future connections. When getting the
+ *        current channel map, it applies to a single connection and the connection handle
+ *        must be supplied.
+ *
+ * @note  Setting the channel map may take some time, depending on connection parameters.
+ *        The time taken may be different for each connection and the get operation will
+ *        return the previous channel map until the new one has taken effect.
+ *
+ * @note  After setting the channel map, by spec it can not be set again until at least 1 s has passed.
+ *        See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46.
+ *
+ * @retval ::NRF_SUCCESS Get or set successful.
+ * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices.
+ *
+ */
+typedef struct
+{
+  uint16_t conn_handle;                   /**< Connection Handle (only applicable for get) */
+  uint8_t ch_map[5];                      /**< Channel Map (37-bit). */
+} ble_gap_opt_ch_map_t;
+
+
+/**@brief Local connection latency option.
+ *
+ *        Local connection latency is a feature which enables the slave to improve
+ *        current consumption by ignoring the slave latency set by the peer. The
+ *        local connection latency can only be set to a multiple of the slave latency,
+ *        and cannot be longer than half of the supervision timeout.
+ *
+ *        Used with @ref sd_ble_opt_set to set the local connection latency. The
+ *        @ref sd_ble_opt_get is not supported for this option, but the actual
+ *        local connection latency (unless set to NULL) is set as a return parameter
+ *        when setting the option.
+ *
+ * @note  The latency set will be truncated down to the closest slave latency event
+ *        multiple, or the nearest multiple before half of the supervision timeout.
+ *
+ * @note  The local connection latency is disabled by default, and needs to be enabled for new
+ *        connections and whenever the connection is updated.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+  uint16_t   conn_handle;                       /**< Connection Handle */
+  uint16_t   requested_latency;                 /**< Requested local connection latency. */
+  uint16_t * p_actual_latency;                  /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
+} ble_gap_opt_local_conn_latency_t;
+
+
+/**@brief Passkey Option.
+ *
+ *        Structure containing the passkey to be used during pairing. This can be used with @ref
+ *        sd_ble_opt_set to make the SoftDevice use a pre-programmed passkey for authentication
+ *        instead of generating a random one.
+ *
+ * @note  @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+  uint8_t * p_passkey;                          /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/
+} ble_gap_opt_passkey_t;
+
+
+/**@brief Custom Privacy Option.
+ *
+ *        This structure is used with both @ref sd_ble_opt_set (as input) and with
+ *        @ref sd_ble_opt_get (as output).
+ *
+ *        Structure containing:
+ *        - A pointer to an IRK to set (if input), or a place to store a read IRK (if output).
+ *        - A private address refresh cycle.
+ *
+ * @note  The specified address cycle interval is used when the address cycle mode is
+ *        @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically 
+ *        refreshed at all. The default interval is @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S.
+ *
+ * @note  If the current address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address will immediately be
+ *        refreshed when a custom privacy option is set. A new address can be generated manually by calling
+ *        @ref sd_ble_gap_address_set with the same type again. 
+ *
+ * @note  If the IRK is updated, the new IRK becomes the one to be distributed in all
+ *        bonding procedures performed after @ref sd_ble_opt_set returns.
+ *
+ * @retval ::NRF_SUCCESS Set or read successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer to IRK storage is invalid.
+ */
+typedef struct
+{
+  ble_gap_irk_t * p_irk;        /**< When input: Pointer to custom IRK, or NULL to use/reset to the device's default IRK. When output: Pointer to where the current IRK is to be stored, or NULL to not read out the IRK. */
+  uint16_t        interval_s;   /**< When input: Custom private address cycle interval in seconds. When output: The current private address cycle interval. */
+} ble_gap_opt_privacy_t;
+
+
+/**@brief Scan request report option.
+ *
+ *        This can be used with @ref sd_ble_opt_set to make the SoftDevice send
+ *        @ref BLE_GAP_EVT_SCAN_REQ_REPORT events.
+ *
+ *  @note   Due to the limited space reserved for scan request report events,
+ *          not all received scan requests will be reported.
+ *
+ *  @note   If whitelisting is used, only whitelisted requests are reported.
+ *
+ *  @retval ::NRF_SUCCESS Set successfully.
+ *  @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set.
+ */
+typedef struct
+{
+   uint8_t enable : 1;                           /**< Enable scan request reports. */
+} ble_gap_opt_scan_req_report_t;
+
+/**@brief Compatibility mode option.
+ *
+ *        This can be used with @ref sd_ble_opt_set to enable and disable
+ *        compatibility modes. Compatibility modes are disabled by default.
+ *
+ *  @note  Compatibility mode 1 enables interoperability with devices that do not support 
+ *         a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet.
+ *
+ *  @retval ::NRF_SUCCESS Set successfully.
+ *  @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set.
+ */
+typedef struct
+{
+   uint8_t mode_1_enable : 1;                           /**< Enable compatibility mode 1.*/
+} ble_gap_opt_compat_mode_t;
+
+
+/**@brief Option structure for GAP options. */
+typedef union
+{
+  ble_gap_opt_ch_map_t                  ch_map;                    /**< Parameters for the Channel Map option. */
+  ble_gap_opt_local_conn_latency_t      local_conn_latency;        /**< Parameters for the Local connection latency option */
+  ble_gap_opt_passkey_t                 passkey;                   /**< Parameters for the Passkey option.*/
+  ble_gap_opt_privacy_t                 privacy;                   /**< Parameters for the Custom privacy option. */
+  ble_gap_opt_scan_req_report_t         scan_req_report;           /**< Parameters for the scan request report option.*/
+  ble_gap_opt_compat_mode_t             compat_mode;               /**< Parameters for the compatibility mode option.*/
+} ble_gap_opt_t;
+/**@} */
+
+
+/**@addtogroup BLE_GAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set local Bluetooth address.
+ *
+ * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address type is required to
+ * be @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or
+ * @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. The given address is ignored and the
+ * SoftDevice will generate a new private address automatically every 
+ * @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S seconds. If this API
+ * call is used again with the same parameters, the SoftDevice will immediately
+ * generate a new private address to replace the current address.
+ *
+ * @note If the application wishes to use a @ref BLE_GAP_ADDR_TYPE_PUBLIC or
+ * @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC address, the cycle mode must be
+ * @ref BLE_GAP_ADDR_CYCLE_MODE_NONE.
+ *
+ * @note If this API function is called while advertising or scanning, the softdevice will immediately update the
+ * advertising or scanning address without the need to stop the procedure in the following cases:
+ *   - If the previously set address is of type @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address
+ *   is also of type @ref BLE_GAP_ADDR_TYPE_PUBLIC
+ *   - If the previously set address is not @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address is
+ *   also not @ref BLE_GAP_ADDR_TYPE_PUBLIC.
+ * If the address is changed from a @ref BLE_GAP_ADDR_TYPE_PUBLIC address to another type or from
+ * another type to a @ref BLE_GAP_ADDR_TYPE_PUBLIC address, the change will take effect the next
+ * time an advertising or scanning procedure is started.
+ *
+ * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_NONE and the application is
+ *       using privacy, the application must take care to generate and set new private addresses
+ *       periodically to comply with the Privacy specification in Bluetooth Core Spec.
+ *
+ * @param[in] addr_cycle_mode Address cycle mode, see @ref BLE_GAP_ADDR_CYCLE_MODES.
+ * @param[in] p_addr          Pointer to address structure.
+ *
+ * @retval ::NRF_SUCCESS Address successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ */
+SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, const ble_gap_addr_t *p_addr));
+
+
+/**@brief Get local Bluetooth address.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Address successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t *p_addr));
+
+
+/**@brief Set, clear or update advertising and scan response data.
+ *
+ * @note The format of the advertising data will be checked by this call to ensure interoperability.
+ *       Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
+ *       duplicating the local name in the advertising data and scan response data. 
+ *
+ * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding 
+ *        length (dlen/srdlen) set to 0.
+ *
+ * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect.
+ *
+ * @param[in] p_data    Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data.
+ * @param[in] dlen      Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL.
+ * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data.
+ * @param[in] srdlen    Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL.
+ *
+ * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type.
+ * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied.
+ */
+SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen));
+
+
+/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @note An application can start an advertising procedure for broadcasting purposes while a connection
+ *       is active. After a @ref BLE_GAP_EVT_CONNECTED event is received, this function may therefore
+ *       be called to start a broadcast advertising procedure. The advertising procedure
+ *       cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or
+ *       @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time.
+ *
+ * @note To use the currently active whitelist set p_adv_params->p_whitelist to NULL.
+ *
+ * @param[in] p_adv_params Pointer to advertising parameters structure.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has started advertising.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied.
+ * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it.
+ */
+SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params));
+
+
+/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has stopped advertising.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state).
+ */
+SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void));
+
+
+/**@brief Update connection parameters.
+ *
+ * @details In the central role this will initiate a Link Layer connection parameter update procedure,
+ *          otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for
+ *          the central to perform the procedure. In both cases, and regardless of success or failure, the application
+ *          will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
+ *
+ * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_conn_params  Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+ *                           the parameters in the PPCP characteristic of the GAP service will be used instead.
+ *                           If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected
+ *
+ * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Disconnect (GAP Link Termination).
+ *
+ * @details This call initiates the disconnection procedure, and its completion will be communicated to the application
+ *          with a @ref BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE).
+ *
+ * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress).
+ */
+SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code));
+
+
+/**@brief Set the radio's transmit power.
+ *
+ * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm).
+ *
+ * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm.
+ *
+ * @retval ::NRF_SUCCESS Successfully changed the transmit power.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power));
+
+
+/**@brief Set GAP Appearance value.
+ *
+ * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS  Appearance value set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance));
+
+
+/**@brief Get GAP Appearance value.
+ *
+ * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance));
+
+
+/**@brief Set GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Get GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params));
+
+
+/**@brief Set GAP device name.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ *
+ * @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
+
+
+/**@brief Get GAP device name.
+ *
+ * @param[out]    p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b> string will be placed. Set to NULL to obtain the complete device name length.
+ * @param[in,out] p_len      Length of the buffer pointed by p_dev_name, complete device name length on output.
+ *
+ * @note          If the device name is longer than the size of the supplied buffer,
+ *                p_len will return the complete device name length,
+ *                and not the number of bytes actually returned in p_dev_name.
+ *                The application may use this information to allocate a suitable buffer size.
+ *
+ * @retval ::NRF_SUCCESS GAP device name retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len));
+
+
+/**@brief Initiate the GAP Authentication procedure.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure.
+ *                         In the peripheral role, only the timeout, bond and mitm fields of this structure are used.
+ *                         In the central role, this pointer may be NULL to reject a Security Request.
+ *
+ * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), 
+ *          otherwise in the peripheral role, an SMP Security Request will be sent.
+ *
+ * @note    Calling this function may result in the following events depending on the outcome and parameters: @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST,
+ *          @ref BLE_GAP_EVT_SEC_INFO_REQUEST, @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, @ref BLE_GAP_EVT_CONN_SEC_UPDATE, @ref BLE_GAP_EVT_AUTH_STATUS.
+ *
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_TIMEOUT A SMP timout has occured, and further SMP operations on this link is prohibited.
+ */
+SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params));
+
+
+/**@brief Reply with GAP security parameters.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have
+ *                         already been provided during a previous call to @ref sd_ble_gap_authenticate.
+ * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys distributed as a result of the ongoing security procedure 
+ *                         will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application 
+ *                         upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event.
+ *                         The pointer to the ID key data distributed by the <b>local device</b> constitutes however an exception. It can either point to ID key data 
+ *                         filled in by the user before calling this function, in which case a user-supplied Bluetooth address and IRK will be distributed, 
+ *                         or the pointer to the ID key data structure can be NULL, in which case the device's configured (or default, if none is configured) 
+ *                         Bluetooth address and IRK will be distributed. 
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note    If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset));
+
+
+/**@brief Reply with an authentication key.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES.
+ * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL.
+ *                If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination).
+ *                If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note    If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @retval ::NRF_SUCCESS Authentication key successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key));
+
+
+/**@brief Initiate GAP Encryption procedure.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure.
+ * @param[in] p_enc_info  Pointer to a @ref ble_gap_enc_info_t encryption information structure.
+ *
+ * @details In the central role, this function will initiate the encryption procedure using the encryption information provided.
+ *
+ * @note    Calling this function may result in the following event depending on the outcome and parameters: @ref BLE_GAP_EVT_CONN_SEC_UPDATE.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry.
+ */
+SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info));
+
+
+/**@brief Reply with GAP security information.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE.
+ * @note    If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ * @note    Data signing is not yet supported, and p_sign_info must therefore be NULL.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security information.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info));
+
+
+/**@brief Get the current connection security.
+ *
+ * @param[in]  conn_handle Connection handle.
+ * @param[out] p_conn_sec  Pointer to a @ref ble_gap_conn_sec_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Current connection security successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec));
+
+
+/**@brief Start reporting the received signal strength to the application. 
+ *
+ * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called.
+ *
+ * @param[in] conn_handle        Connection handle.
+ * @param[in] threshold_dbm      Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID.
+ * @param[in] skip_count         Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event.
+ *
+ * @retval ::NRF_SUCCESS                   Successfully activated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE       Disconnection in progress. Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
+
+
+/**@brief Stop reporting the received signal strength.
+ *
+ * @note An RSSI change detected before the call but not yet received by the application 
+ * may be reported after @ref sd_ble_gap_rssi_stop has been called.
+ *
+ * @param[in] conn_handle Connection handle.
+ *
+ * @retval ::NRF_SUCCESS                   Successfully deactivated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE       Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle));
+
+
+/**@brief Get the received signal strength for the last connection event.
+ *
+ * @param[in]  conn_handle Connection handle.
+ * @param[out] p_rssi      Pointer to the location where the RSSI measurement shall be stored.
+ *
+ * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND
+ * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start.
+ *
+ * @retval ::NRF_SUCCESS                   Successfully read the RSSI.
+ * @retval ::NRF_ERROR_NOT_FOUND           No sample is available.
+ * @retval ::NRF_ERROR_INVALID_ADDR        Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE       RSSI reporting is not ongoing, or disconnection in progress.
+ */
+SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi));
+
+
+/**@brief Start scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @note To use the currently active whitelist set p_scan_params->p_whitelist to NULL.
+ *
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it.
+ */
+SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params));
+
+
+/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @retval ::NRF_SUCCESS Successfully stopped scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state).
+ */
+SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void));
+
+
+/**@brief Create a connection (GAP Link Establishment).
+ *
+ * @note To use the currently active whitelist set p_scan_params->p_whitelist to NULL.    
+ *
+ * @param[in] p_peer_addr   Pointer to peer address. If the selective bit is set in @ref ble_gap_scan_params_t, then this must be NULL.
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated connection procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address.
+ * @retval ::NRF_ERROR_NO_MEM limit of available connections reached.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established wait for the corresponding
+ *                          @ref BLE_GAP_EVT_CONNECTED event before calling again.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it.
+ */
+SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Cancel a connection establishment.
+ *
+ * @retval ::NRF_SUCCESS Successfully cancelled an ongoing connection procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ */
+SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void));
+
+/** @} */
+
+#endif // BLE_GAP_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gatt.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
+  @{
+  @brief  Common definitions and prototypes for the GATT interfaces.
+ */
+
+#ifndef BLE_GATT_H__
+#define BLE_GATT_H__
+
+#include "ble_types.h"
+#include "ble_ranges.h"
+
+
+/** @addtogroup BLE_GATT_DEFINES Defines
+ * @{ */
+
+/** @brief Default MTU size. */
+#define GATT_MTU_SIZE_DEFAULT 23
+
+/** @brief Only the default MTU size of 23 is currently supported. */
+#define GATT_RX_MTU 23
+
+
+/**@brief Invalid Attribute Handle. */
+#define BLE_GATT_HANDLE_INVALID            0x0000
+
+/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
+ * @{ */
+#define BLE_GATT_TIMEOUT_SRC_PROTOCOL                  0x00 /**< ATT Protocol timeout. */
+/** @} */
+
+/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
+ * @{ */
+#define BLE_GATT_OP_INVALID                0x00  /**< Invalid Operation. */
+#define BLE_GATT_OP_WRITE_REQ              0x01  /**< Write Request. */
+#define BLE_GATT_OP_WRITE_CMD              0x02  /**< Write Command. */
+#define BLE_GATT_OP_SIGN_WRITE_CMD         0x03  /**< Signed Write Command. */
+#define BLE_GATT_OP_PREP_WRITE_REQ         0x04  /**< Prepare Write Request. */
+#define BLE_GATT_OP_EXEC_WRITE_REQ         0x05  /**< Execute Write Request. */
+/** @} */
+
+/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
+ * @{ */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE  0x01
+/** @} */
+
+/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
+ * @{ */
+#define BLE_GATT_HVX_INVALID               0x00  /**< Invalid Operation. */
+#define BLE_GATT_HVX_NOTIFICATION          0x01  /**< Handle Value Notification. */
+#define BLE_GATT_HVX_INDICATION            0x02  /**< Handle Value Indication. */
+/** @} */
+
+/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
+ * @{ */
+#define BLE_GATT_STATUS_SUCCESS                           0x0000  /**< Success. */
+#define BLE_GATT_STATUS_UNKNOWN                           0x0001  /**< Unknown or not applicable status. */
+#define BLE_GATT_STATUS_ATTERR_INVALID                    0x0100  /**< ATT Error: Invalid Error Code. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE             0x0101  /**< ATT Error: Invalid Attribute Handle. */
+#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED         0x0102  /**< ATT Error: Read not permitted. */
+#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED        0x0103  /**< ATT Error: Write not permitted. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_PDU                0x0104  /**< ATT Error: Used in ATT as Invalid PDU. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION       0x0105  /**< ATT Error: Authenticated link required. */
+#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED      0x0106  /**< ATT Error: Used in ATT as Request Not Supported. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET             0x0107  /**< ATT Error: Offset specified was past the end of the attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION        0x0108  /**< ATT Error: Used in ATT as Insufficient Authorisation. */
+#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL         0x0109  /**< ATT Error: Used in ATT as Prepare Queue Full. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND        0x010A  /**< ATT Error: Used in ATT as Attribute not found. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG         0x010B  /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE         0x010C  /**< ATT Error: Encryption key size used is insufficient. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH     0x010D  /**< ATT Error: Invalid value size. */
+#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR             0x010E  /**< ATT Error: Very unlikely error. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION           0x010F  /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE     0x0110  /**< ATT Error: Attribute type is not a supported grouping attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES            0x0111  /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN           0x0112  /**< ATT Error: Reserved for Future Use range #1 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END             0x017F  /**< ATT Error: Reserved for Future Use range #1 end. */
+#define BLE_GATT_STATUS_ATTERR_APP_BEGIN                  0x0180  /**< ATT Error: Application range begin. */
+#define BLE_GATT_STATUS_ATTERR_APP_END                    0x019F  /**< ATT Error: Application range end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN           0x01A0  /**< ATT Error: Reserved for Future Use range #2 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END             0x01DF  /**< ATT Error: Reserved for Future Use range #2 end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN           0x01E0  /**< ATT Error: Reserved for Future Use range #3 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END             0x01FC  /**< ATT Error: Reserved for Future Use range #3 end. */
+#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR      0x01FD  /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
+#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG       0x01FE  /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
+#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE           0x01FF  /**< ATT Common Profile and Service Error: Out Of Range. */
+/** @} */
+
+
+/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
+ *  @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+ * @{ */
+#define BLE_GATT_CPF_FORMAT_RFU                 0x00 /**< Reserved For Future Use. */
+#define BLE_GATT_CPF_FORMAT_BOOLEAN             0x01 /**< Boolean. */
+#define BLE_GATT_CPF_FORMAT_2BIT                0x02 /**< Unsigned 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_NIBBLE              0x03 /**< Unsigned 4-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT8               0x04 /**< Unsigned 8-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT12              0x05 /**< Unsigned 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT16              0x06 /**< Unsigned 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT24              0x07 /**< Unsigned 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT32              0x08 /**< Unsigned 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT48              0x09 /**< Unsigned 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT64              0x0A /**< Unsigned 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT128             0x0B /**< Unsigned 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT8               0x0C /**< Signed 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT12              0x0D /**< Signed 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT16              0x0E /**< Signed 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT24              0x0F /**< Signed 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT32              0x10 /**< Signed 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT48              0x11 /**< Signed 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT64              0x12 /**< Signed 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT128             0x13 /**< Signed 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_FLOAT32             0x14 /**< IEEE-754 32-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_FLOAT64             0x15 /**< IEEE-754 64-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_SFLOAT              0x16 /**< IEEE-11073 16-bit SFLOAT. */
+#define BLE_GATT_CPF_FORMAT_FLOAT               0x17 /**< IEEE-11073 32-bit FLOAT. */
+#define BLE_GATT_CPF_FORMAT_DUINT16             0x18 /**< IEEE-20601 format. */
+#define BLE_GATT_CPF_FORMAT_UTF8S               0x19 /**< UTF-8 string. */
+#define BLE_GATT_CPF_FORMAT_UTF16S              0x1A /**< UTF-16 string. */
+#define BLE_GATT_CPF_FORMAT_STRUCT              0x1B /**< Opaque Structure. */
+/** @} */
+
+/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
+ * @{
+ */
+#define BLE_GATT_CPF_NAMESPACE_BTSIG            0x01 /**< Bluetooth SIG defined Namespace. */
+#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATT_STRUCTURES Structures
+ * @{ */
+
+/**@brief GATT Characteristic Properties. */
+typedef struct
+{
+  /* Standard properties */
+  uint8_t broadcast       :1; /**< Broadcasting of the value permitted. */
+  uint8_t read            :1; /**< Reading the value permitted. */
+  uint8_t write_wo_resp   :1; /**< Writing the value with Write Command permitted. */
+  uint8_t write           :1; /**< Writing the value with Write Request permitted. */
+  uint8_t notify          :1; /**< Notications of the value permitted. */
+  uint8_t indicate        :1; /**< Indications of the value permitted. */
+  uint8_t auth_signed_wr  :1; /**< Writing the value with Signed Write Command permitted. */
+} ble_gatt_char_props_t;
+
+/**@brief GATT Characteristic Extended Properties. */
+typedef struct
+{
+  /* Extended properties */
+  uint8_t reliable_wr     :1; /**< Writing the value with Queued Write operations permitted. */
+  uint8_t wr_aux          :1; /**< Writing the Characteristic User Description descriptor permitted. */
+} ble_gatt_char_ext_props_t;
+
+#endif // BLE_GATT_H__
+
+/** @} */
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gattc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
+  @{
+  @brief  Definitions and prototypes for the GATT Client interface.
+ */
+
+#ifndef BLE_GATTC_H__
+#define BLE_GATTC_H__
+
+#include "ble_gatt.h"
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "nrf_svc.h"
+
+/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GATTC API SVC numbers. */
+enum BLE_GATTC_SVCS
+{
+  SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
+  SD_BLE_GATTC_RELATIONSHIPS_DISCOVER,                         /**< Relationship Discovery. */
+  SD_BLE_GATTC_CHARACTERISTICS_DISCOVER,                       /**< Characteristic Discovery. */
+  SD_BLE_GATTC_DESCRIPTORS_DISCOVER,                           /**< Characteristic Descriptor Discovery. */
+  SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ,                        /**< Read Characteristic Value by UUID. */
+  SD_BLE_GATTC_READ,                                           /**< Generic read. */
+  SD_BLE_GATTC_CHAR_VALUES_READ,                               /**< Read multiple Characteristic Values. */
+  SD_BLE_GATTC_WRITE,                                          /**< Generic write. */
+  SD_BLE_GATTC_HV_CONFIRM                                      /**< Handle Value Confirmation. */
+};
+
+/**
+ * @brief GATT Client Event IDs.
+ */
+enum BLE_GATTC_EVTS
+{
+  BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE,  /**< Primary Service Discovery Response event. @ref ble_gattc_evt_prim_srvc_disc_rsp_t */
+  BLE_GATTC_EVT_REL_DISC_RSP,                             /**< Relationship Discovery Response event. @ref ble_gattc_evt_rel_disc_rsp_t */
+  BLE_GATTC_EVT_CHAR_DISC_RSP,                            /**< Characteristic Discovery Response event. @ref ble_gattc_evt_char_disc_rsp_t */
+  BLE_GATTC_EVT_DESC_DISC_RSP,                            /**< Descriptor Discovery Response event. @ref ble_gattc_evt_desc_disc_rsp_t */
+  BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP,                /**< Read By UUID Response event. @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t */
+  BLE_GATTC_EVT_READ_RSP,                                 /**< Read Response event. @ref ble_gattc_evt_read_rsp_t */
+  BLE_GATTC_EVT_CHAR_VALS_READ_RSP,                       /**< Read multiple Response event. @ref ble_gattc_evt_char_vals_read_rsp_t */
+  BLE_GATTC_EVT_WRITE_RSP,                                /**< Write Response event. @ref ble_gattc_evt_write_rsp_t */
+  BLE_GATTC_EVT_HVX,                                      /**< Handle Value Notification or Indication event. @ref ble_gattc_evt_hvx_t */
+  BLE_GATTC_EVT_TIMEOUT                                   /**< Timeout event. @ref ble_gattc_evt_timeout_t */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
+ * @{ */
+#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED    (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
+/** @} */
+
+/**@brief Last Attribute Handle. */
+#define BLE_GATTC_HANDLE_END                0xFFFF
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_STRUCTURES Structures
+ * @{ */
+
+/**@brief Operation Handle Range. */
+typedef struct
+{
+  uint16_t          start_handle; /**< Start Handle. */
+  uint16_t          end_handle;   /**< End Handle. */
+} ble_gattc_handle_range_t;
+
+
+/**@brief GATT service. */
+typedef struct
+{
+  ble_uuid_t               uuid;          /**< Service UUID. */
+  ble_gattc_handle_range_t handle_range;  /**< Service Handle Range. */
+} ble_gattc_service_t;
+
+
+/**@brief  GATT include. */
+typedef struct
+{
+  uint16_t            handle;           /**< Include Handle. */
+  ble_gattc_service_t included_srvc;    /**< Handle of the included service. */
+} ble_gattc_include_t;
+
+
+/**@brief GATT characteristic. */
+typedef struct
+{
+  ble_uuid_t              uuid;                 /**< Characteristic UUID. */
+  ble_gatt_char_props_t   char_props;           /**< Characteristic Properties. */
+  uint8_t                 char_ext_props : 1;   /**< Extended properties present. */
+  uint16_t                handle_decl;          /**< Handle of the Characteristic Declaration. */
+  uint16_t                handle_value;         /**< Handle of the Characteristic Value. */
+} ble_gattc_char_t;
+
+
+/**@brief GATT descriptor. */
+typedef struct
+{
+  uint16_t          handle;         /**< Descriptor Handle. */
+  ble_uuid_t        uuid;           /**< Descriptor UUID. */
+} ble_gattc_desc_t;
+
+
+/**@brief Write Parameters. */
+typedef struct
+{
+  uint8_t    write_op;                 /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
+  uint8_t    flags;                    /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
+  uint16_t   handle;                   /**< Handle to the attribute to be written. */
+  uint16_t   offset;                   /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
+  uint16_t   len;                      /**< Length of data in bytes. */
+  uint8_t   *p_value;                  /**< Pointer to the value data. */
+} ble_gattc_write_params_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
+typedef struct
+{
+  uint16_t             count;           /**< Service count. */
+  ble_gattc_service_t services[1];      /**< Service data, variable length. */
+} ble_gattc_evt_prim_srvc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
+typedef struct
+{
+  uint16_t             count;           /**< Include count. */
+  ble_gattc_include_t includes[1];      /**< Include data, variable length. */
+} ble_gattc_evt_rel_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
+typedef struct
+{
+  uint16_t            count;          /**< Characteristic count. */
+  ble_gattc_char_t    chars[1];       /**< Characteristic data, variable length. */
+} ble_gattc_evt_char_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
+typedef struct
+{
+  uint16_t            count;          /**< Descriptor count. */
+  ble_gattc_desc_t    descs[1];       /**< Descriptor data, variable length. */
+} ble_gattc_evt_desc_disc_rsp_t;
+
+/**@brief GATT read by UUID handle value pair. */
+typedef struct 
+{
+  uint16_t            handle;          /**< Attribute Handle. */
+  uint8_t             *p_value;        /**< Pointer to value, variable length (length available as value_len in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t). 
+                                            Please note that this pointer is absolute to the memory provided by the user when retrieving the event,
+                                            so it will effectively point to a location inside the handle_value array. */
+} ble_gattc_handle_value_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
+typedef struct
+{
+  uint16_t                  count;            /**< Handle-Value Pair Count. */
+  uint16_t                  value_len;        /**< Length of the value in Handle-Value(s) list. */
+  ble_gattc_handle_value_t  handle_value[1];  /**< Handle-Value(s) list, variable length. */
+} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
+typedef struct
+{
+  uint16_t            handle;         /**< Attribute Handle. */
+  uint16_t            offset;         /**< Offset of the attribute data. */
+  uint16_t            len;            /**< Attribute data length. */
+  uint8_t             data[1];        /**< Attribute data, variable length. */
+} ble_gattc_evt_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
+typedef struct
+{
+  uint16_t            len;            /**< Concatenated Attribute values length. */
+  uint8_t             values[1];      /**< Attribute values, variable length. */
+} ble_gattc_evt_char_vals_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
+typedef struct
+{
+  uint16_t            handle;           /**< Attribute Handle. */
+  uint8_t             write_op;         /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
+  uint16_t            offset;           /**< Data offset. */
+  uint16_t            len;              /**< Data length. */
+  uint8_t             data[1];          /**< Data, variable length. */
+} ble_gattc_evt_write_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
+typedef struct
+{
+  uint16_t            handle;         /**< Handle to which the HVx operation applies. */
+  uint8_t             type;           /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+  uint16_t            len;            /**< Attribute data length. */
+  uint8_t             data[1];        /**< Attribute data, variable length. */
+} ble_gattc_evt_hvx_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
+typedef struct
+{
+  uint8_t          src;                       /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gattc_evt_timeout_t;
+
+/**@brief GATTC event structure. */
+typedef struct
+{
+  uint16_t            conn_handle;                /**< Connection Handle on which event occured. */
+  uint16_t            gatt_status;                /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+  uint16_t            error_handle;               /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
+  union
+  {
+    ble_gattc_evt_prim_srvc_disc_rsp_t          prim_srvc_disc_rsp;         /**< Primary Service Discovery Response Event Parameters. */
+    ble_gattc_evt_rel_disc_rsp_t                rel_disc_rsp;               /**< Relationship Discovery Response Event Parameters. */
+    ble_gattc_evt_char_disc_rsp_t               char_disc_rsp;              /**< Characteristic Discovery Response Event Parameters. */
+    ble_gattc_evt_desc_disc_rsp_t               desc_disc_rsp;              /**< Descriptor Discovery Response Event Parameters. */
+    ble_gattc_evt_char_val_by_uuid_read_rsp_t   char_val_by_uuid_read_rsp;  /**< Characteristic Value Read by UUID Response Event Parameters. */
+    ble_gattc_evt_read_rsp_t                    read_rsp;                   /**< Read Response Event Parameters. */
+    ble_gattc_evt_char_vals_read_rsp_t          char_vals_read_rsp;         /**< Characteristic Values Read Response Event Parameters. */
+    ble_gattc_evt_write_rsp_t                   write_rsp;                  /**< Write Response Event Parameters. */
+    ble_gattc_evt_hvx_t                         hvx;                        /**< Handle Value Notification/Indication Event Parameters. */
+    ble_gattc_evt_timeout_t                     timeout;                    /**< Timeout Event Parameters. */
+  } params;                                                                 /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
+} ble_gattc_evt_t;
+/** @} */
+
+/** @addtogroup BLE_GATTC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
+ *
+ * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. 
+ *          If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
+ *
+ * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ *       type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] start_handle Handle to start searching from.
+ * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
+
+
+/**@brief Initiate or continue a GATT Relationship Discovery procedure.
+ *
+ * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
+ *          this must be called again with an updated handle range to continue the search.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
+ *          this must be called again with an updated handle range to continue the discovery.
+ *
+ * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ *       type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
+ *          this must be called again with an updated handle range to continue the discovery.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
+ *
+ * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
+ *          this must be called again with an updated handle range to continue the discovery.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_uuid Pointer to a Characteristic value UUID to read.
+ * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
+ *
+ * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
+ *          to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the 
+ *          complete value.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute to be read.
+ * @param[in] offset Offset into the attribute value to be read.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
+
+
+/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @details This function initiates a GATT Read Multiple Characteristic Values procedure. 
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
+ * @param[in] handle_count The number of handles in p_handles.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
+
+
+/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
+ *
+ * @details This function can perform all write procedures described in GATT. 
+ *
+ * @note    It is important to note that a write without response will <b>consume an application buffer</b>, and will therefore 
+ *          generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the 
+ *          standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response 
+ *          has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_write_params A pointer to a write parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Write procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers left.
+ */
+SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
+
+
+/**@brief Send a Handle Value Confirmation to the GATT Server.
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute in the indication.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
+ */
+SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
+
+/** @} */
+
+#endif /* BLE_GATTC_H__ */
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_gatts.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
+  @{
+  @brief  Definitions and prototypes for the GATTS interface.
+ */
+
+#ifndef BLE_GATTS_H__
+#define BLE_GATTS_H__
+
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "ble_l2cap.h"
+#include "ble_gap.h"
+#include "ble_gatt.h"
+#include "nrf_svc.h"
+
+/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief GATTS API SVC numbers.
+ */
+enum BLE_GATTS_SVCS
+{
+  SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
+  SD_BLE_GATTS_INCLUDE_ADD,                      /**< Add an included service. */
+  SD_BLE_GATTS_CHARACTERISTIC_ADD,               /**< Add a characteristic. */
+  SD_BLE_GATTS_DESCRIPTOR_ADD,                   /**< Add a generic attribute. */
+  SD_BLE_GATTS_VALUE_SET,                        /**< Set an attribute value. */
+  SD_BLE_GATTS_VALUE_GET,                        /**< Get an attribute value. */
+  SD_BLE_GATTS_HVX,                              /**< Handle Value Notification or Indication. */
+  SD_BLE_GATTS_SERVICE_CHANGED,                  /**< Perform a Service Changed Indication to one or more peers. */
+  SD_BLE_GATTS_RW_AUTHORIZE_REPLY,               /**< Reply to an authorization request for a read or write operation on one or more attributes. */ 
+  SD_BLE_GATTS_SYS_ATTR_SET,                     /**< Set the persistent system attributes for a connection. */  
+  SD_BLE_GATTS_SYS_ATTR_GET,                     /**< Retrieve the persistent system attributes. */
+};
+
+/**
+ * @brief GATT Server Event IDs.
+ */
+enum BLE_GATTS_EVTS
+{
+  BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE,       /**< Write operation performed. @ref ble_gatts_evt_write_t */
+  BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST,             /**< Read/Write Authorization request.@ref ble_gatts_evt_rw_authorize_request_t */
+  BLE_GATTS_EVT_SYS_ATTR_MISSING,                 /**< A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set(). @ref ble_gatts_evt_sys_attr_missing_t */
+  BLE_GATTS_EVT_HVC,                              /**< Handle Value Confirmation. @ref ble_gatts_evt_hvc_t */
+  BLE_GATTS_EVT_SC_CONFIRM,                       /**< Service Changed Confirmation. No additional event structure applies. */
+  BLE_GATTS_EVT_TIMEOUT                           /**< Timeout. @ref ble_gatts_evt_timeout_t */
+};
+/** @} */
+
+/** @addtogroup BLE_GATTS_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
+ * @{ */
+#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE   (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
+#define BLE_ERROR_GATTS_SYS_ATTR_MISSING    (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
+ * @{ */
+#define BLE_GATTS_FIX_ATTR_LEN_MAX (510)  /**< Maximum length for fixed length Attribute Values. */
+#define BLE_GATTS_VAR_ATTR_LEN_MAX (512)  /**< Maximum length for variable length Attribute Values. */ 
+/** @} */
+
+/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
+ * @{ */
+#define BLE_GATTS_SRVC_TYPE_INVALID          0x00  /**< Invalid Service Type. */
+#define BLE_GATTS_SRVC_TYPE_PRIMARY          0x01  /**< Primary Service. */
+#define BLE_GATTS_SRVC_TYPE_SECONDARY        0x02  /**< Secondary Type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
+ * @{ */
+#define BLE_GATTS_ATTR_TYPE_INVALID         0x00  /**< Invalid Attribute Type. */
+#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL  0x01  /**< Primary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL   0x02  /**< Secondary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_INC_DECL        0x03  /**< Include Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_DECL       0x04  /**< Characteristic Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_VAL        0x05  /**< Characteristic Value. */
+#define BLE_GATTS_ATTR_TYPE_DESC            0x06  /**< Descriptor. */
+#define BLE_GATTS_ATTR_TYPE_OTHER           0x07  /**< Other, non-GATT specific type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_OPS GATT Server Operations
+ * @{ */
+#define BLE_GATTS_OP_INVALID                0x00  /**< Invalid Operation. */
+#define BLE_GATTS_OP_WRITE_REQ              0x01  /**< Write Request. */
+#define BLE_GATTS_OP_WRITE_CMD              0x02  /**< Write Command. */
+#define BLE_GATTS_OP_SIGN_WRITE_CMD         0x03  /**< Signed Write Command. */
+#define BLE_GATTS_OP_PREP_WRITE_REQ         0x04  /**< Prepare Write Request. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL  0x05  /**< Execute Write Request: Cancel all prepared writes. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW     0x06  /**< Execute Write Request: Immediately execute all prepared writes. */
+/** @} */
+
+/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
+ * @{ */
+#define BLE_GATTS_VLOC_INVALID       0x00  /**< Invalid Location. */
+#define BLE_GATTS_VLOC_STACK         0x01  /**< Attribute Value is located in stack memory, no user memory is required. */
+#define BLE_GATTS_VLOC_USER          0x02  /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
+                                                will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
+/** @} */
+
+/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
+ * @{ */
+#define BLE_GATTS_AUTHORIZE_TYPE_INVALID    0x00  /**< Invalid Type. */
+#define BLE_GATTS_AUTHORIZE_TYPE_READ       0x01  /**< Authorize a Read Operation. */
+#define BLE_GATTS_AUTHORIZE_TYPE_WRITE      0x02  /**< Authorize a Write Request Operation. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
+ * @{ */
+#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0)  /**< Restrict system attributes to system services only. */
+#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1)  /**< Restrict system attributes to user services only. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
+ * @{
+ */
+#define BLE_GATTS_ATTR_TAB_SIZE_MIN         216    /**< Minimum Attribute Table size */
+#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT     0x0000 /**< Default Attribute Table size (0x600 bytes for this version of the SoftDevice). */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTS init options
+ */
+typedef struct
+{
+  uint8_t   service_changed:1;             /**< Include the Service Changed characteristic in the Attribute Table. */
+  uint32_t  attr_tab_size;                 /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */
+} ble_gatts_enable_params_t;
+
+/**@brief Attribute metadata. */
+typedef struct
+{
+  ble_gap_conn_sec_mode_t read_perm;       /**< Read permissions. */
+  ble_gap_conn_sec_mode_t write_perm;      /**< Write permissions. */
+  uint8_t                 vlen       :1;   /**< Variable length attribute. */
+  uint8_t                 vloc       :2;   /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+  uint8_t                 rd_auth    :1;   /**< Read authorization and value will be requested from the application on every read operation. */ 
+  uint8_t                 wr_auth    :1;   /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
+} ble_gatts_attr_md_t;
+
+
+/**@brief GATT Attribute. */
+typedef struct
+{
+  ble_uuid_t          *p_uuid;          /**< Pointer to the attribute UUID. */
+  ble_gatts_attr_md_t *p_attr_md;       /**< Pointer to the attribute metadata structure. */
+  uint16_t             init_len;        /**< Initial attribute value length in bytes. */
+  uint16_t             init_offs;       /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+  uint16_t             max_len;         /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+  uint8_t*             p_value;         /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
+                                             that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. 
+                                             The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
+} ble_gatts_attr_t;
+
+/**@brief GATT Attribute Value. */
+typedef struct
+{
+  uint16_t  len;        /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
+  uint16_t  offset;     /**< Attribute value offset. */
+  uint8_t   *p_value;   /**< Pointer to where value is stored or will be stored. 
+                             If value is stored in user memory, only the attribute length is updated when p_value == NULL.
+                             Set to NULL when reading to obtain the complete length of the attribute value */
+} ble_gatts_value_t;
+
+
+/**@brief GATT Attribute Context. */
+typedef struct
+{
+  ble_uuid_t           srvc_uuid;       /**< Service UUID. */
+  ble_uuid_t           char_uuid;       /**< Characteristic UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */
+  ble_uuid_t           desc_uuid;       /**< Descriptor UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */
+  uint16_t             srvc_handle;     /**< Service Handle. */
+  uint16_t             value_handle;    /**< Characteristic Value Handle if applicable (BLE_GATT_HANDLE_INVALID otherwise). */
+  uint8_t              type;            /**< Attribute Type, see @ref BLE_GATTS_ATTR_TYPES. */
+} ble_gatts_attr_context_t;
+
+
+/**@brief GATT Characteristic Presentation Format. */
+typedef struct
+{
+  uint8_t          format;      /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
+  int8_t           exponent;    /**< Exponent for integer data types. */
+  uint16_t         unit;        /**< Unit from Bluetooth Assigned Numbers. */
+  uint8_t          name_space;  /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+  uint16_t         desc;        /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+} ble_gatts_char_pf_t;
+
+
+/**@brief GATT Characteristic metadata. */
+typedef struct
+{
+  ble_gatt_char_props_t       char_props;               /**< Characteristic Properties. */
+  ble_gatt_char_ext_props_t   char_ext_props;           /**< Characteristic Extended Properties. */
+  uint8_t                    *p_char_user_desc;         /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
+  uint16_t                    char_user_desc_max_size;  /**< The maximum size in bytes of the user description descriptor. */
+  uint16_t                    char_user_desc_size;      /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ 
+  ble_gatts_char_pf_t*        p_char_pf;                /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
+  ble_gatts_attr_md_t*        p_user_desc_md;           /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
+  ble_gatts_attr_md_t*        p_cccd_md;                /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
+  ble_gatts_attr_md_t*        p_sccd_md;                /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
+} ble_gatts_char_md_t;
+
+
+/**@brief GATT Characteristic Definition Handles. */
+typedef struct
+{
+  uint16_t          value_handle;       /**< Handle to the characteristic value. */
+  uint16_t          user_desc_handle;   /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+  uint16_t          cccd_handle;        /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+  uint16_t          sccd_handle;        /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+} ble_gatts_char_handles_t;
+
+
+/**@brief GATT HVx parameters. */
+typedef struct
+{
+  uint16_t          handle;             /**< Characteristic Value Handle. */
+  uint8_t           type;               /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+  uint16_t          offset;             /**< Offset within the attribute value. */
+  uint16_t         *p_len;              /**< Length in bytes to be written, length in bytes written after successful return. */
+  uint8_t          *p_data;             /**< Actual data content, use NULL to use the current attribute value. */
+} ble_gatts_hvx_params_t;
+
+/**@brief GATT Read Authorization parameters. */
+typedef struct
+{
+  uint16_t          gatt_status;        /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+  uint8_t           update : 1;         /**< If set, data supplied in p_data will be used in the ATT response. */
+  uint16_t          offset;             /**< Offset of the attribute value being updated. */
+  uint16_t          len;                /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
+  uint8_t          *p_data;             /**< Pointer to new value used to update the attribute value. */
+} ble_gatts_read_authorize_params_t;
+
+/**@brief GATT Write Authorization parameters. */
+typedef struct
+{
+  uint16_t          gatt_status;        /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+} ble_gatts_write_authorize_params_t;
+
+/**@brief GATT Read or Write Authorize Reply parameters. */
+typedef struct
+{
+  uint8_t                               type;   /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+  union {
+    ble_gatts_read_authorize_params_t   read;   /**< Read authorization parameters. */
+    ble_gatts_write_authorize_params_t  write;  /**< Write authorization parameters. */
+  } params;                                     /**< Reply Parameters. */
+} ble_gatts_rw_authorize_reply_params_t;
+
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
+typedef struct
+{
+  uint16_t                    handle;             /**< Attribute Handle. */
+  uint8_t                     op;                 /**< Type of write operation, see @ref BLE_GATTS_OPS. */
+  ble_gatts_attr_context_t    context;            /**< Attribute Context. */
+  uint16_t                    offset;             /**< Offset for the write operation. */
+  uint16_t                    len;                /**< Length of the received data. */
+  uint8_t                     data[1];            /**< Received data, variable length. */
+} ble_gatts_evt_write_t;
+
+/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
+typedef struct
+{
+  uint16_t                    handle;             /**< Attribute Handle. */
+  ble_gatts_attr_context_t    context;            /**< Attribute Context. */
+  uint16_t                    offset;             /**< Offset for the read operation. */
+} ble_gatts_evt_read_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
+typedef struct
+{
+  uint8_t                     type;             /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+  union {
+    ble_gatts_evt_read_t      read;             /**< Attribute Read Parameters. */
+    ble_gatts_evt_write_t     write;            /**< Attribute Write Parameters. */
+  } request;                                    /**< Request Parameters. */
+} ble_gatts_evt_rw_authorize_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
+typedef struct
+{
+  uint8_t hint;                                 /**< Hint (currently unused). */
+} ble_gatts_evt_sys_attr_missing_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
+typedef struct
+{
+  uint16_t          handle;                       /**< Attribute Handle. */
+} ble_gatts_evt_hvc_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
+typedef struct
+{
+  uint8_t          src;                       /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gatts_evt_timeout_t;
+
+
+/**@brief GATT Server event callback event structure. */
+typedef struct
+{
+  uint16_t conn_handle;                                       /**< Connection Handle on which the event occurred. */
+  union
+  {
+    ble_gatts_evt_write_t                 write;              /**< Write Event Parameters. */
+    ble_gatts_evt_rw_authorize_request_t  authorize_request;  /**< Read or Write Authorize Request Parameters. */
+    ble_gatts_evt_sys_attr_missing_t      sys_attr_missing;   /**< System attributes missing. */
+    ble_gatts_evt_hvc_t                   hvc;                /**< Handle Value Confirmation Event Parameters. */
+    ble_gatts_evt_timeout_t               timeout;            /**< Timeout Event. */
+  } params;                                                   /**< Event Parameters. */
+} ble_gatts_evt_t;
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Add a service declaration to the Attribute Table.
+ *
+ * @param[in] type      Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
+ * @param[in] p_uuid    Pointer to service UUID.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
+ *       add a secondary service declaration that is not referenced by another service later in the Attribute Table.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a service declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
+
+
+/**@brief Add an include declaration to the Attribute Table.
+ *
+ * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). 
+ *
+ * @note The included service must already be present in the Attribute Table prior to this call.
+ *
+ * @param[in] service_handle    Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] inc_srvc_handle   Handle of the included service.
+ * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added an include declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ */
+SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
+
+
+/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
+ *
+ * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). 
+ *
+ * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits,
+ *       readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values.
+ *
+ * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
+ *
+ * @param[in] service_handle    Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_char_md         Characteristic metadata.
+ * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
+ * @param[out] p_handles        Pointer to the structure where the assigned handles will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a characteristic.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
+
+
+/**@brief Add a descriptor to the Attribute Table.
+ *
+ * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). 
+ *
+ * @param[in] char_handle   Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_attr        Pointer to the attribute structure.
+ * @param[out] p_handle     Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a descriptor.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
+
+/**@brief Set the value of a given attribute.
+ *
+ * @param[in] conn_handle  Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
+ * @param[in] handle       Attribute handle.
+ * @param[in,out] p_value  Attribute value information.
+ *
+ * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist.
+ *
+ * @retval ::NRF_SUCCESS Successfully set the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Get the value of a given attribute.
+ *
+ * @param[in] conn_handle  Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used.
+ * @param[in] handle       Attribute handle.
+ * @param[in,out] p_value  Attribute value information.
+ *
+ * @note                 If the attribute value is longer than the size of the supplied buffer,
+ *                       p_len will return the total attribute value length (excluding offset),
+ *                       and not the number of bytes actually returned in p_data.
+ *                       The application may use this information to allocate a suitable buffer size.
+ * 
+ * @note                 When retrieving system attribute values with this function, the connection handle
+ *                       may refer to an already disconnected connection. Refer to the documentation of
+ *                       @ref sd_ble_gatts_sys_attr_get for further information.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Notify or Indicate an attribute value.
+ *
+ * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
+ *          (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
+ *          the application can atomically perform a value update and a server initiated transaction with a single API call.
+ *          If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from
+ *          the peer.
+ *
+ * @note    The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. 
+ *          When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and 
+ *          @ref BLE_ERROR_NO_TX_BUFFERS the Attribute Table has been updated.
+ *          The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len).
+ *
+ * @note    It is important to note that a notification will <b>consume an application buffer</b>, and will therefore 
+ *          generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the 
+ *          standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation 
+ *          has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details.
+ *
+ * @param[in] conn_handle  Connection handle.
+ * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with
+ *                         the contents pointed by it before sending the notification or indication.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers to send the data, applies only to notifications.
+ */
+SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
+
+/**@brief Indicate the Service Changed attribute value.
+ *
+ * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
+ *          Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
+ *          be issued.
+ *
+ * @note    Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
+ *
+ * @param[in] conn_handle  Connection handle.
+ * @param[in] start_handle Start of affected attribute handle range.
+ * @param[in] end_handle   End of affected attribute handle range.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, notifications or indications must be enabled in the CCCD.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
+
+/**@brief Respond to a Read/Write authorization request.
+ *
+ * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
+ *
+ * @param[in] conn_handle                 Connection handle.
+ * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
+ *
+ * @retval ::NRF_SUCCESS               Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE   Invalid Connection State or no authorization request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM   Authorization op invalid,
+ *                                         or for Read Authorization reply: requested handles not replied with,
+ *                                         or for Write Authorization reply: handle supplied does not match requested handle.
+ * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
+
+
+/**@brief Update persistent system attribute information.
+ *
+ * @details Supply information about persistent system attributes to the stack, 
+ *          previously obtained using @ref sd_ble_gatts_sys_attr_get.
+ *          This call is only allowed for active connections, and is usually 
+ *          made immediately after a connection is established with an known bonded device,
+ *          often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
+ *
+ *          p_sysattrs may point directly to the application's stored copy of the system attributes 
+ *          obtained using @ref sd_ble_gatts_sys_attr_get.
+ *          If the pointer is NULL, the system attribute info is initialized, assuming that
+ *          the application does not have any previously saved system attribute data for this device.
+ *
+ * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. 
+ *
+ * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
+ *       This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
+ *       reset the SoftDevice to return to a known state.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
+ *
+ * @param[in]  conn_handle        Connection handle.
+ * @param[in]  p_sys_attr_data    Pointer to a saved copy of system attributes supplied to the stack, or NULL.
+ * @param[in]  len                Size of data pointed by p_sys_attr_data, in octets. 
+ * @param[in]  flags              Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully set the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE   Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time.
+ */ 
+SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); 
+
+ 
+/**@brief Retrieve persistent system attribute information from the stack.
+ *
+ * @details This call is used to retrieve information about values to be stored perisistently by the application
+ *          during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, 
+ *          the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
+ *          If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
+ *          the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
+ *          Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
+ *          may be written to at any time by the peer during a connection's lifetime.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
+ *
+ * @param[in]     conn_handle       Connection handle of the recently terminated connection.
+ * @param[out]    p_sys_attr_data   Pointer to a buffer where updated information about system attributes will be filled in. NULL can be provided to 
+ *                                  obtain the length of the data
+ * @param[in,out] p_len             Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data.
+ * @param[in]     flags             Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
+ * @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
+ */ 
+SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); 
+
+/** @} */
+
+#endif // BLE_GATTS_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_hci.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_COMMON 
+  @{
+*/
+
+
+#ifndef BLE_HCI_H__
+#define BLE_HCI_H__ 
+
+/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
+ * @{ */
+
+#define BLE_HCI_STATUS_CODE_SUCCESS                        0x00   /**< Success. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND           0x01   /**< Unknown BLE Command. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER  0x02   /**< Unknown Connection Identifier. */
+/*0x03 Hardware Failure
+0x04 Page Timeout
+*/
+#define BLE_HCI_AUTHENTICATION_FAILURE                     0x05   /**< Authentication Failure. */
+#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING             0x06   /**< Pin or Key missing. */
+#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED                   0x07   /**< Memory Capacity Exceeded. */
+#define BLE_HCI_CONNECTION_TIMEOUT                         0x08   /**< Connection Timeout. */
+/*0x09 Connection Limit Exceeded
+0x0A Synchronous Connection Limit To A Device Exceeded
+0x0B ACL Connection Already Exists*/
+#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED             0x0C   /**< Command Disallowed. */
+/*0x0D Connection Rejected due to Limited Resources
+0x0E Connection Rejected Due To Security Reasons
+0x0F Connection Rejected due to Unacceptable BD_ADDR
+0x10 Connection Accept Timeout Exceeded
+0x11 Unsupported Feature or Parameter Value*/
+#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12  /**< Invalid BLE Command Parameters. */
+#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION           0x13  /**< Remote User Terminated Connection. */
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14  /**< Remote Device Terminated Connection due to low resources.*/
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF     0x15  /**< Remote Device Terminated Connection due to power off. */
+#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION            0x16  /**< Local Host Terminated Connection. */
+/*
+0x17 Repeated Attempts
+0x18 Pairing Not Allowed
+0x19 Unknown LMP PDU
+*/
+#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A                   /**< Unsupported Remote Feature. */
+/*
+0x1B SCO Offset Rejected
+0x1C SCO Interval Rejected
+0x1D SCO Air Mode Rejected*/
+#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS     0x1E       /**< Invalid LMP Parameters. */
+#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR          0x1F       /**< Unspecified Error. */
+/*0x20 Unsupported LMP Parameter Value
+0x21 Role Change Not Allowed
+*/
+#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT       0x22       /**< LMP Response Timeout. */
+/*0x23 LMP Error Transaction Collision*/
+#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED        0x24       /**< LMP PDU Not Allowed. */
+/*0x25 Encryption Mode Not Acceptable
+0x26 Link Key Can Not be Changed
+0x27 Requested QoS Not Supported
+*/
+#define BLE_HCI_INSTANT_PASSED                         0x28       /**< Instant Passed. */
+#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED      0x29       /**< Pairing with Unit Key Unsupported. */
+#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION        0x2A       /**< Different Transaction Collision. */
+/*
+0x2B Reserved
+0x2C QoS Unacceptable Parameter
+0x2D QoS Rejected
+0x2E Channel Classification Not Supported
+0x2F Insufficient Security
+0x30 Parameter Out Of Mandatory Range
+0x31 Reserved
+0x32 Role Switch Pending
+0x33 Reserved
+0x34 Reserved Slot Violation
+0x35 Role Switch Failed
+0x36 Extended Inquiry Response Too Large
+0x37 Secure Simple Pairing Not Supported By Host.
+0x38 Host Busy - Pairing
+0x39 Connection Rejected due to No Suitable Channel Found*/
+#define BLE_HCI_CONTROLLER_BUSY                        0x3A       /**< Controller Busy. */
+#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE             0x3B       /**< Connection Interval Unacceptable. */
+#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT            0x3C       /**< Directed Adverisement Timeout. */
+#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE     0x3D       /**< Connection Terminated due to MIC Failure. */
+#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED          0x3E       /**< Connection Failed to be Established. */
+
+/** @} */
+
+
+#endif // BLE_HCI_H__
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_l2cap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
+  @{
+  @brief Definitions and prototypes for the L2CAP interface.
+ */
+
+#ifndef BLE_L2CAP_H__
+#define BLE_L2CAP_H__ 
+
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "ble_err.h"
+#include "nrf_svc.h"
+
+/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief L2CAP API SVC numbers. */
+enum BLE_L2CAP_SVCS 
+{
+  SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE,  /**< Register a CID. */
+  SD_BLE_L2CAP_CID_UNREGISTER,                     /**< Unregister a CID. */
+  SD_BLE_L2CAP_TX                                  /**< Transmit a packet. */
+};
+
+/**@brief L2CAP Event IDs. */
+enum BLE_L2CAP_EVTS 
+{
+  BLE_L2CAP_EVT_RX  = BLE_L2CAP_EVT_BASE          /**< L2CAP packet received. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_L2CAP SVC return values specific to L2CAP
+ * @{ */
+#define BLE_ERROR_L2CAP_CID_IN_USE            (NRF_L2CAP_ERR_BASE + 0x000)  /**< CID already in use. */
+/** @} */
+
+/**@brief Default L2CAP MTU. */
+#define BLE_L2CAP_MTU_DEF           (23)    
+
+/**@brief Invalid Channel Identifier. */
+#define BLE_L2CAP_CID_INVALID       (0x0000) 
+
+/**@brief Dynamic Channel Identifier base. */
+#define BLE_L2CAP_CID_DYN_BASE      (0x0040) 
+
+/**@brief Maximum amount of dynamic CIDs. */
+#define BLE_L2CAP_CID_DYN_MAX       (8) 
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Packet header format for L2CAP transmission. */
+typedef struct
+{
+  uint16_t   len;                                 /**< Length of valid info in data member. */
+  uint16_t   cid;                                 /**< Channel ID on which packet is transmitted. */
+} ble_l2cap_header_t;
+
+
+/**@brief L2CAP Received packet event report. */
+typedef struct
+{
+  ble_l2cap_header_t header;                      /**< L2CAP packet header. */
+  uint8_t    data[1];                             /**< Packet data, variable length. */
+} ble_l2cap_evt_rx_t;
+
+
+/**@brief L2CAP event callback event structure. */
+typedef struct
+{
+  uint16_t conn_handle;                           /**< Connection Handle on which event occured. */
+  union
+  {
+    ble_l2cap_evt_rx_t rx;                        /**< RX Event parameters. */
+  } params;                                       /**< Event Parameters. */
+} ble_l2cap_evt_t;
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Register a CID with L2CAP.
+ *
+ * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID.
+ *          
+ * @param[in] cid L2CAP CID.
+ *
+ * @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CID must be above @ref BLE_L2CAP_CID_DYN_BASE.
+ * @retval ::BLE_ERROR_L2CAP_CID_IN_USE L2CAP CID already in use.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t cid));
+
+/**@brief Unregister a CID with L2CAP.
+ *
+ * @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer.
+ *          
+ * @param[in] cid L2CAP CID.
+ *
+ * @retval ::NRF_SUCCESS Successfully unregistered the CID.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND CID not previously registered.
+ */
+SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16_t cid));
+
+/**@brief Transmit an L2CAP packet.
+ *
+ * @note    It is important to note that a call to this function will <b>consume an application buffer</b>, and will therefore 
+ *          generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. 
+ *          Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details.
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] p_header    Pointer to a packet header containing length and CID.
+ * @param[in] p_data      Pointer to the data to be transmitted.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued an L2CAP packet for transmission.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register.
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF.
+ */
+SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data));
+
+/** @} */
+
+#endif // BLE_L2CAP_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_ranges.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_COMMON
+  @{
+  @defgroup ble_ranges Module specific SVC, event and option number subranges
+  @{
+
+  @brief Definition of SVC, event and option number subranges for each API module.
+
+  @note
+  SVCs, event and option numbers are split into subranges for each API module.
+  Each module receives its entire allocated range of SVC calls, whether implemented or not,
+  but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
+
+  Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
+  rather than the last SVC function call actually defined and implemented.
+
+  Specific SVC, event and option values are defined in each module's ble_<module>.h file,
+  which defines names of each individual SVC code based on the range start value.
+*/
+
+#ifndef BLE_RANGES_H__
+#define BLE_RANGES_H__
+
+#define BLE_SVC_BASE           0x60       /**< Common BLE SVC base. */
+#define BLE_SVC_LAST           0x6B       /**< Total: 12. */
+
+#define BLE_RESERVED_SVC_BASE  0x6C       /**< Reserved BLE SVC base. */
+#define BLE_RESERVED_SVC_LAST  0x6F       /**< Total: 4. */
+
+#define BLE_GAP_SVC_BASE       0x70       /**< GAP BLE SVC base. */
+#define BLE_GAP_SVC_LAST       0x8F       /**< Total: 32. */
+
+#define BLE_GATTC_SVC_BASE     0x90       /**< GATTC BLE SVC base. */
+#define BLE_GATTC_SVC_LAST     0x9F       /**< Total: 32. */
+
+#define BLE_GATTS_SVC_BASE     0xA0       /**< GATTS BLE SVC base. */
+#define BLE_GATTS_SVC_LAST     0xAF       /**< Total: 16. */
+
+#define BLE_L2CAP_SVC_BASE     0xB0       /**< L2CAP BLE SVC base. */
+#define BLE_L2CAP_SVC_LAST     0xBF       /**< Total: 16. */
+
+
+#define BLE_EVT_INVALID        0x00       /**< Invalid BLE Event. */
+
+#define BLE_EVT_BASE           0x01       /**< Common BLE Event base. */
+#define BLE_EVT_LAST           0x0F       /**< Total: 15. */
+
+#define BLE_GAP_EVT_BASE       0x10       /**< GAP BLE Event base. */
+#define BLE_GAP_EVT_LAST       0x2F       /**< Total: 32. */
+
+#define BLE_GATTC_EVT_BASE     0x30       /**< GATTC BLE Event base. */
+#define BLE_GATTC_EVT_LAST     0x4F       /**< Total: 32. */
+
+#define BLE_GATTS_EVT_BASE     0x50       /**< GATTS BLE Event base. */
+#define BLE_GATTS_EVT_LAST     0x6F       /**< Total: 32. */
+
+#define BLE_L2CAP_EVT_BASE     0x70       /**< L2CAP BLE Event base. */
+#define BLE_L2CAP_EVT_LAST     0x8F       /**< Total: 32.  */
+
+
+#define BLE_OPT_INVALID        0x00       /**< Invalid BLE Option. */
+
+#define BLE_OPT_BASE           0x01       /**< Common BLE Option base. */
+#define BLE_OPT_LAST           0x1F       /**< Total: 31. */
+
+#define BLE_GAP_OPT_BASE       0x20       /**< GAP BLE Option base. */
+#define BLE_GAP_OPT_LAST       0x3F       /**< Total: 32. */
+
+#define BLE_GATTC_OPT_BASE     0x40       /**< GATTC BLE Option base. */
+#define BLE_GATTC_OPT_LAST     0x5F       /**< Total: 32. */
+
+#define BLE_GATTS_OPT_BASE     0x60       /**< GATTS BLE Option base. */
+#define BLE_GATTS_OPT_LAST     0x7F       /**< Total: 32. */
+
+#define BLE_L2CAP_OPT_BASE     0x80       /**< L2CAP BLE Option base. */
+#define BLE_L2CAP_OPT_LAST     0x9F       /**< Total: 32.  */
+
+#endif /* BLE_RANGES_H__ */
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/ble_types.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+  @addtogroup BLE_COMMON
+  @{
+  @defgroup ble_types Common types and macro definitions
+  @{
+
+  @brief Common types and macro definitions for the BLE SoftDevice.
+ */
+
+#ifndef BLE_TYPES_H__
+#define BLE_TYPES_H__
+
+#include <stdint.h>
+
+/** @addtogroup BLE_TYPES_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
+ * @{ */
+#define BLE_CONN_HANDLE_INVALID 0xFFFF  /**< Invalid Connection Handle. */
+#define BLE_CONN_HANDLE_ALL     0xFFFE  /**< Applies to all Connection Handles. */
+/** @} */
+
+
+#if 0 /* The following have been duplicated in blecommon.h */
+/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
+ * @{ */
+/* Generic UUIDs, applicable to all services */
+#define BLE_UUID_UNKNOWN                              0x0000 /**< Reserved UUID. */
+#define BLE_UUID_SERVICE_PRIMARY                      0x2800 /**< Primary Service. */
+#define BLE_UUID_SERVICE_SECONDARY                    0x2801 /**< Secondary Service. */
+#define BLE_UUID_SERVICE_INCLUDE                      0x2802 /**< Include. */
+#define BLE_UUID_CHARACTERISTIC                       0x2803 /**< Characteristic. */
+#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP             0x2900 /**< Characteristic Extended Properties Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC            0x2901 /**< Characteristic User Description Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG        0x2902 /**< Client Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG        0x2903 /**< Server Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT  0x2904 /**< Characteristic Presentation Format Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT     0x2905 /**< Characteristic Aggregate Format Descriptor. */
+/* GATT specific UUIDs */
+#define BLE_UUID_GATT                                 0x1801 /**< Generic Attribute Profile. */
+#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED  0x2A05 /**< Service Changed Characteristic. */
+/* GAP specific UUIDs */
+#define BLE_UUID_GAP                                  0x1800 /**< Generic Access Profile. */
+#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME       0x2A00 /**< Device Name Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE        0x2A01 /**< Appearance Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_PPF               0x2A02 /**< Peripheral Privacy Flag Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR       0x2A03 /**< Reconnection Address Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_PPCP              0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
+/** @} */
+#endif /* The following have been duplicated in blecommon.h */
+
+
+/** @defgroup BLE_UUID_TYPES Types of UUID
+ * @{ */
+#define BLE_UUID_TYPE_UNKNOWN       0x00 /**< Invalid UUID type. */
+#define BLE_UUID_TYPE_BLE           0x01 /**< Bluetooth SIG UUID (16-bit). */
+#define BLE_UUID_TYPE_VENDOR_BEGIN  0x02 /**< Vendor UUID types start at this index (128-bit). */
+/** @} */
+
+
+#if 0 /* The following have been duplicated in blecommon.h */
+/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
+ *  @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+ * @{ */
+#define BLE_APPEARANCE_UNKNOWN                                0 /**< Unknown. */
+#define BLE_APPEARANCE_GENERIC_PHONE                         64 /**< Generic Phone. */
+#define BLE_APPEARANCE_GENERIC_COMPUTER                     128 /**< Generic Computer. */
+#define BLE_APPEARANCE_GENERIC_WATCH                        192 /**< Generic Watch. */
+#define BLE_APPEARANCE_WATCH_SPORTS_WATCH                   193 /**< Watch: Sports Watch. */
+#define BLE_APPEARANCE_GENERIC_CLOCK                        256 /**< Generic Clock. */
+#define BLE_APPEARANCE_GENERIC_DISPLAY                      320 /**< Generic Display. */
+#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL               384 /**< Generic Remote Control. */
+#define BLE_APPEARANCE_GENERIC_EYE_GLASSES                  448 /**< Generic Eye-glasses. */
+#define BLE_APPEARANCE_GENERIC_TAG                          512 /**< Generic Tag. */
+#define BLE_APPEARANCE_GENERIC_KEYRING                      576 /**< Generic Keyring. */
+#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER                 640 /**< Generic Media Player. */
+#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER              704 /**< Generic Barcode Scanner. */
+#define BLE_APPEARANCE_GENERIC_THERMOMETER                  768 /**< Generic Thermometer. */
+#define BLE_APPEARANCE_THERMOMETER_EAR                      769 /**< Thermometer: Ear. */
+#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR            832 /**< Generic Heart rate Sensor. */
+#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT    833 /**< Heart Rate Sensor: Heart Rate Belt. */
+#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE               896 /**< Generic Blood Pressure. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM                   897 /**< Blood Pressure: Arm. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST                 898 /**< Blood Pressure: Wrist. */
+#define BLE_APPEARANCE_GENERIC_HID                          960 /**< Human Interface Device (HID). */
+#define BLE_APPEARANCE_HID_KEYBOARD                         961 /**< Keyboard (HID Subtype). */
+#define BLE_APPEARANCE_HID_MOUSE                            962 /**< Mouse (HID Subtype). */
+#define BLE_APPEARANCE_HID_JOYSTICK                         963 /**< Joystiq (HID Subtype). */
+#define BLE_APPEARANCE_HID_GAMEPAD                          964 /**< Gamepad (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE                 965 /**< Digitizer Tablet (HID Subtype). */
+#define BLE_APPEARANCE_HID_CARD_READER                      966 /**< Card Reader (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITAL_PEN                      967 /**< Digital Pen (HID Subtype). */
+#define BLE_APPEARANCE_HID_BARCODE                          968 /**< Barcode Scanner (HID Subtype). */
+#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER               1024 /**< Generic Glucose Meter. */
+#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR      1088 /**< Generic Running Walking Sensor. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE      1089 /**< Running Walking Sensor: In-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE      1090 /**< Running Walking Sensor: On-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP       1091 /**< Running Walking Sensor: On-Hip. */
+#define BLE_APPEARANCE_GENERIC_CYCLING                     1152 /**< Generic Cycling. */
+#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER            1153 /**< Cycling: Cycling Computer. */
+#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR                1154 /**< Cycling: Speed Sensor. */
+#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR              1155 /**< Cycling: Cadence Sensor. */
+#define BLE_APPEARANCE_CYCLING_POWER_SENSOR                1156 /**< Cycling: Power Sensor. */
+#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR        1157 /**< Cycling: Speed and Cadence Sensor. */
+#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER              3136 /**< Generic Pulse Oximeter. */
+#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP            3137 /**< Fingertip (Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN           3138 /**< Wrist Worn(Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE                3200 /**< Generic Weight Scale. */
+#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT          5184 /**< Generic Outdoor Sports Activity. */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP         5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD          5187 /**< Location Pod (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD  5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
+/** @} */
+#endif /* The following have been duplicated in blecommon.h */
+
+/** @brief Set .type and .uuid fields of ble_uuid_struct to specified uuid value. */
+#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
+            instance.type = BLE_UUID_TYPE_BLE; \
+            instance.uuid = value;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
+#define BLE_UUID_COPY_PTR(dst, src) do {\
+            (dst)->type = (src)->type; \
+            (dst)->uuid = (src)->uuid;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
+#define BLE_UUID_COPY_INST(dst, src) do {\
+            (dst).type = (src).type; \
+            (dst).uuid = (src).uuid;} while(0)
+
+/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
+            (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
+
+/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
+            (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
+
+/** @} */
+
+/** @addtogroup BLE_TYPES_STRUCTURES Structures
+ * @{ */
+
+/** @brief 128 bit UUID values. */
+typedef struct
+{ 
+    unsigned char uuid128[16]; /**< Little-Endian UUID bytes. */
+} ble_uuid128_t;
+
+/** @brief  Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
+typedef struct
+{
+    uint16_t    uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
+    uint8_t     type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
+} ble_uuid_t;
+
+/** @} */
+
+#endif /* BLE_TYPES_H__ */
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_error SoftDevice Global Error Codes
+  @{
+   
+  @brief Global Error definitions
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_H__
+#define NRF_ERROR_H__
+
+/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
+ * @{ */
+#define NRF_ERROR_BASE_NUM      (0x0)       ///< Global error base
+#define NRF_ERROR_SDM_BASE_NUM  (0x1000)    ///< SDM error base
+#define NRF_ERROR_SOC_BASE_NUM  (0x2000)    ///< SoC error base
+#define NRF_ERROR_STK_BASE_NUM  (0x3000)    ///< STK error base
+/** @} */
+
+#define NRF_SUCCESS                           (NRF_ERROR_BASE_NUM + 0)  ///< Successful command
+#define NRF_ERROR_SVC_HANDLER_MISSING         (NRF_ERROR_BASE_NUM + 1)  ///< SVC handler is missing
+#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED      (NRF_ERROR_BASE_NUM + 2)  ///< SoftDevice has not been enabled
+#define NRF_ERROR_INTERNAL                    (NRF_ERROR_BASE_NUM + 3)  ///< Internal Error
+#define NRF_ERROR_NO_MEM                      (NRF_ERROR_BASE_NUM + 4)  ///< No Memory for operation
+#define NRF_ERROR_NOT_FOUND                   (NRF_ERROR_BASE_NUM + 5)  ///< Not found
+#define NRF_ERROR_NOT_SUPPORTED               (NRF_ERROR_BASE_NUM + 6)  ///< Not supported
+#define NRF_ERROR_INVALID_PARAM               (NRF_ERROR_BASE_NUM + 7)  ///< Invalid Parameter
+#define NRF_ERROR_INVALID_STATE               (NRF_ERROR_BASE_NUM + 8)  ///< Invalid state, operation disallowed in this state
+#define NRF_ERROR_INVALID_LENGTH              (NRF_ERROR_BASE_NUM + 9)  ///< Invalid Length
+#define NRF_ERROR_INVALID_FLAGS               (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
+#define NRF_ERROR_INVALID_DATA                (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
+#define NRF_ERROR_DATA_SIZE                   (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit
+#define NRF_ERROR_TIMEOUT                     (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
+#define NRF_ERROR_NULL                        (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
+#define NRF_ERROR_FORBIDDEN                   (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
+#define NRF_ERROR_INVALID_ADDR                (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
+#define NRF_ERROR_BUSY                        (NRF_ERROR_BASE_NUM + 17) ///< Busy
+
+#endif // NRF_ERROR_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error_sdm.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+ /**
+  @addtogroup nrf_sdm_api
+  @{
+  @defgroup nrf_sdm_error SoftDevice Manager Error Codes
+  @{
+     
+  @brief Error definitions for the SDM API
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SDM_H__
+#define NRF_ERROR_SDM_H__
+
+#include "nrf_error.h"
+
+#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN              (NRF_ERROR_SDM_BASE_NUM + 0)  ///< Unknown lfclk source.
+#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1)  ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
+#define NRF_ERROR_SDM_INCORRECT_CLENR0                  (NRF_ERROR_SDM_BASE_NUM + 2)  ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing).
+
+#endif // NRF_ERROR_SDM_H__
+
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_error_soc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+  @addtogroup nrf_soc_api
+  @{
+  @defgroup nrf_soc_error SoC Library Error Codes
+  @{
+     
+  @brief Error definitions for the SoC library
+
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SOC_H__
+#define NRF_ERROR_SOC_H__
+
+#include "nrf_error.h"
+
+/* Mutex Errors */
+#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN                 (NRF_ERROR_SOC_BASE_NUM + 0)  ///< Mutex already taken
+
+/* NVIC errors */
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE        (NRF_ERROR_SOC_BASE_NUM + 1)  ///< NVIC interrupt not available
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2)  ///< NVIC interrupt priority not allowed
+#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN              (NRF_ERROR_SOC_BASE_NUM + 3)  ///< NVIC should not return
+
+/* Power errors */
+#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN                  (NRF_ERROR_SOC_BASE_NUM + 4)  ///< Power mode unknown
+#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN         (NRF_ERROR_SOC_BASE_NUM + 5)  ///< Power POF threshold unknown
+#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN         (NRF_ERROR_SOC_BASE_NUM + 6)  ///< Power off should not return
+
+/* Rand errors */
+#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES              (NRF_ERROR_SOC_BASE_NUM + 7)  ///< RAND not enough values
+
+/* PPI errors */
+#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL                 (NRF_ERROR_SOC_BASE_NUM + 8)  ///< Invalid PPI Channel
+#define NRF_ERROR_SOC_PPI_INVALID_GROUP                   (NRF_ERROR_SOC_BASE_NUM + 9)  ///< Invalid PPI Group
+
+#endif // NRF_ERROR_SOC_H__
+/**
+  @}
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_mbr.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_mbr_api Master Boot Record API
+  @{
+
+  @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+/* Header guard */
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE        (0x18)
+
+/**@brief Page size in words. */
+#define PAGE_SIZE_IN_WORDS 256
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+  SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+  SD_MBR_COMMAND_COPY_BL,               /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t */
+  SD_MBR_COMMAND_COPY_SD,               /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+  SD_MBR_COMMAND_INIT_SD,               /**< Init forwarding interrupts to SD, and run reset function in SD*/
+  SD_MBR_COMMAND_COMPARE,               /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+  SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the PROTENSET registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+  uint32_t *src;  /**< Pointer to the source of data to be copied.*/
+  uint32_t *dst;  /**< Pointer to the destination where the content is to be copied.*/
+  uint32_t len;   /**< Number of 32 bit words to copy. Must be a multiple of @ref PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+  uint32_t *ptr1; /**< Pointer to block of memory. */
+  uint32_t *ptr2; /**< Pointer to block of memory. */
+  uint32_t len;   /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *  With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR.
+ *
+ *  Destination is erased by this function.
+ *  If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ *  This function will use PROTENSET to protect the flash that is not intended to be written.
+ *
+ *  On Success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ */
+typedef struct
+{
+  uint32_t *bl_src;  /**< Pointer to the source of the Bootloader to be be copied.*/
+  uint32_t bl_len;   /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @param address set to 0.
+ * The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ */
+typedef struct
+{
+  uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+typedef struct
+{
+  uint32_t command;  /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */
+  union
+  {
+    sd_mbr_command_copy_sd_t copy_sd;  /**< Parameters for copy SoftDevice.*/
+    sd_mbr_command_copy_bl_t copy_bl;  /**< Parameters for copy BootLoader.*/
+    sd_mbr_command_compare_t compare;  /**< Parameters for verify.*/
+    sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/
+  } params;
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * @param[in]  param Pointer to a struct describing the command.
+ *
+ *@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t
+
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+#endif // NRF_MBR_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_sdm.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_sdm_api SoftDevice Manager API
+  @{
+     
+  @brief APIs for SoftDevice management.
+ 
+*/
+
+/* Header guard */
+#ifndef NRF_SDM_H__
+#define NRF_SDM_H__
+
+#include "nrf_svc.h"
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "nrf_error_sdm.h"
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+
+/** @brief SoftDevice Manager SVC Base number. */
+#define SDM_SVC_BASE 0x10   
+
+/** @} */
+
+/** @brief Defines the SoftDevice Information Structure location (address) as an offset from 
+the start of the softdevice (without MBR)*/
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. 
+This is the offset where the first byte of the softdevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @brief Defines the absolute Softdevice information structure location (address)*/
+#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
+
+/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/
+#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
+
+/** @brief Defines the offset for FWID value relative to Softdevice base address*/
+#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
+
+/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address
+           use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
+#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retreiving the actual FWID value from a given base address
+           use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/
+#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF)
+
+
+/** @addtogroup NRF_SDM_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF SoftDevice Manager API SVC numbers. */
+enum NRF_SD_SVCS
+{
+  SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
+  SD_SOFTDEVICE_DISABLE,               /**< ::sd_softdevice_disable */
+  SD_SOFTDEVICE_IS_ENABLED,            /**< ::sd_softdevice_is_enabled */
+  SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
+  SVC_SDM_LAST                         /**< Placeholder for last SDM SVC */
+};
+
+/**@brief Possible lfclk oscillator sources. */
+enum NRF_CLOCK_LFCLKSRCS
+{
+  NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM,                       /**< LFCLK Synthesized from HFCLK.                    */
+  NRF_CLOCK_LFCLKSRC_XTAL_500_PPM,                        /**< LFCLK crystal oscillator 500 PPM accuracy.       */
+  NRF_CLOCK_LFCLKSRC_XTAL_250_PPM,                        /**< LFCLK crystal oscillator 250 PPM accuracy.       */
+  NRF_CLOCK_LFCLKSRC_XTAL_150_PPM,                        /**< LFCLK crystal oscillator 150 PPM accuracy.       */
+  NRF_CLOCK_LFCLKSRC_XTAL_100_PPM,                        /**< LFCLK crystal oscillator 100 PPM accuracy.       */
+  NRF_CLOCK_LFCLKSRC_XTAL_75_PPM,                         /**< LFCLK crystal oscillator 75 PPM accuracy.        */
+  NRF_CLOCK_LFCLKSRC_XTAL_50_PPM,                         /**< LFCLK crystal oscillator 50 PPM accuracy.        */
+  NRF_CLOCK_LFCLKSRC_XTAL_30_PPM,                         /**< LFCLK crystal oscillator 30 PPM accuracy.        */
+  NRF_CLOCK_LFCLKSRC_XTAL_20_PPM,                         /**< LFCLK crystal oscillator 20 PPM accuracy.        */
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION,        /**< LFCLK RC oscillator, 250ms  calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION,        /**< LFCLK RC oscillator, 500ms  calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION,       /**< LFCLK RC oscillator, 1000ms calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION,       /**< LFCLK RC oscillator, 2000ms calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION,       /**< LFCLK RC oscillator, 4000ms calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION,       /**< LFCLK RC oscillator, 8000ms calibration interval.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION,  /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION,  /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION,  /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION,  /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/
+  NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_SDM_TYPES Types
+ * @{ */
+
+/**@brief Type representing lfclk oscillator source. */
+typedef uint32_t nrf_clock_lfclksrc_t;
+
+
+/**@brief SoftDevice Assertion Handler type.
+ *
+ * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback.
+ * The protocol stack will be in an undefined state when this happens and the only way to recover will be to
+ * perform a reset, using e.g. CMSIS NVIC_SystemReset().
+ *
+ * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback.
+ *       
+ * @param[in] pc The program counter of the failed assert.
+ * @param[in] line_number Line number where the assert failed.
+ * @param[in] file_name File name where the assert failed.
+ */
+typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name);
+
+/** @} */
+
+/** @addtogroup NRF_SDM_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enables the SoftDevice and by extension the protocol stack.
+ *
+ * Idempotent function to enable the SoftDevice.
+ *
+ * @note Some care must be taken if a low frequency clock source is already running when calling this function:
+ *       If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
+ *       clock source will be started.
+ *
+ * @note This function has no effect when returning with an error.
+ *
+ * @post If return code is ::NRF_SUCCESS 
+ *       - SoC library and protocol stack APIs are made available.
+ *       - A portion of RAM will be unavailable (see relevant SDS documentation).
+ *       - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
+ *       - Interrupts will not arrive from protected peripherals or interrupts.
+ *       - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice.
+ *       - Interrupt latency may be affected by the SoftDevice  (see relevant SDS documentation).
+ *       - Chosen low frequency clock source will be running.
+ *
+ * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock).
+ * @param assertion_handler Callback for SoftDevice assertions.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated.
+ * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level.
+ * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
+ */
+SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler));
+
+/**@brief Disables the SoftDevice and by extension the protocol stack.
+ * 
+ * Idempotent function to disable the SoftDevice.
+ *
+ * @post SoC library and protocol stack APIs are made unavailable.
+ * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
+ * @post All peripherals used by the SoftDevice will be reset to default values.
+ * @post All of RAM become available.
+ * @post All interrupts are forwarded to the application.
+ * @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
+
+/**@brief Check if the SoftDevice is enabled.
+ *
+ * @param[out]  p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
+ * 
+ * This function is only intended to be called when a bootloader is enabled.
+ *
+ * @param[in] address The base address of the interrupt vector table for forwarded interrupts.
+ 
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); 
+
+/** @} */
+
+#endif // NRF_SDM_H__
+
+/**
+  @}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_soc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,988 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 nrf_soc_api SoC Library API
+ * @{
+ * 
+ * @brief APIs for the SoC library.
+ * 
+ */
+
+#ifndef NRF_SOC_H__
+#define NRF_SOC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_svc.h"
+#include "nrf.h"
+#include "nrf_error_soc.h"
+
+/**@addtogroup NRF_SOC_DEFINES Defines
+ * @{ */
+
+/**@brief The number of the lowest SVC number reserved for the SoC library. */
+#define SOC_SVC_BASE               (0x20)
+#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B)
+
+/**@brief Guranteed time for application to process radio inactive notification. */
+#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US  (62)
+
+/**@brief The minimum allowed timeslot extension time. */
+#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
+
+#define SOC_ECB_KEY_LENGTH                (16)                       /**< ECB key length. */
+#define SOC_ECB_CLEARTEXT_LENGTH          (16)                       /**< ECB cleartext length. */
+#define SOC_ECB_CIPHERTEXT_LENGTH         (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
+
+#define SD_EVT_IRQn                       (SWI2_IRQn)        /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define SD_EVT_IRQHandler                 (SWI2_IRQHandler)  /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */
+#define RADIO_NOTIFICATION_IRQn           (SWI1_IRQn)        /**< The radio notification IRQ number. */
+#define RADIO_NOTIFICATION_IRQHandler     (SWI1_IRQHandler)  /**< The radio notification IRQ handler. */
+
+#define NRF_RADIO_LENGTH_MIN_US           (100)               /**< The shortest allowed radio timeslot, in microseconds. */
+#define NRF_RADIO_LENGTH_MAX_US           (100000)            /**< The longest allowed radio timeslot, in microseconds. */
+
+#define NRF_RADIO_DISTANCE_MAX_US         (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
+
+#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
+
+#define NRF_RADIO_START_JITTER_US         (2)                 /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
+
+/**@} */
+
+/**@addtogroup NRF_SOC_TYPES Types
+ * @{ */
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum NRF_SOC_SVCS
+{
+  SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
+  SD_PPI_CHANNEL_ENABLE_SET,
+  SD_PPI_CHANNEL_ENABLE_CLR,
+  SD_PPI_CHANNEL_ASSIGN,
+  SD_PPI_GROUP_TASK_ENABLE,
+  SD_PPI_GROUP_TASK_DISABLE,
+  SD_PPI_GROUP_ASSIGN,
+  SD_PPI_GROUP_GET,
+  SD_FLASH_PAGE_ERASE,
+  SD_FLASH_WRITE,
+  SD_FLASH_PROTECT,
+  SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
+  SD_MUTEX_ACQUIRE,
+  SD_MUTEX_RELEASE,
+  SD_NVIC_ENABLEIRQ,
+  SD_NVIC_DISABLEIRQ,
+  SD_NVIC_GETPENDINGIRQ,
+  SD_NVIC_SETPENDINGIRQ,
+  SD_NVIC_CLEARPENDINGIRQ,
+  SD_NVIC_SETPRIORITY,
+  SD_NVIC_GETPRIORITY,
+  SD_NVIC_SYSTEMRESET,
+  SD_NVIC_CRITICAL_REGION_ENTER,
+  SD_NVIC_CRITICAL_REGION_EXIT,
+  SD_RAND_APPLICATION_POOL_CAPACITY,
+  SD_RAND_APPLICATION_BYTES_AVAILABLE,
+  SD_RAND_APPLICATION_GET_VECTOR,
+  SD_POWER_MODE_SET,
+  SD_POWER_SYSTEM_OFF,
+  SD_POWER_RESET_REASON_GET,
+  SD_POWER_RESET_REASON_CLR,
+  SD_POWER_POF_ENABLE,
+  SD_POWER_POF_THRESHOLD_SET,
+  SD_POWER_RAMON_SET,
+  SD_POWER_RAMON_CLR,
+  SD_POWER_RAMON_GET,
+  SD_POWER_GPREGRET_SET,
+  SD_POWER_GPREGRET_CLR,
+  SD_POWER_GPREGRET_GET,
+  SD_POWER_DCDC_MODE_SET,
+  SD_APP_EVT_WAIT,
+  SD_CLOCK_HFCLK_REQUEST,
+  SD_CLOCK_HFCLK_RELEASE,
+  SD_CLOCK_HFCLK_IS_RUNNING,
+  SD_RADIO_NOTIFICATION_CFG_SET,
+  SD_ECB_BLOCK_ENCRYPT,
+  SD_RADIO_SESSION_OPEN,
+  SD_RADIO_SESSION_CLOSE,
+  SD_RADIO_REQUEST,
+  SD_EVT_GET,
+  SD_TEMP_GET,
+  SVC_SOC_LAST
+};
+
+/**@brief Possible values of a ::nrf_mutex_t. */
+enum NRF_MUTEX_VALUES
+{
+  NRF_MUTEX_FREE,
+  NRF_MUTEX_TAKEN
+};
+
+/**@brief Possible values of ::nrf_app_irq_priority_t. */
+enum NRF_APP_PRIORITIES
+{
+  NRF_APP_PRIORITY_HIGH = 1,
+  NRF_APP_PRIORITY_LOW = 3
+};
+
+/**@brief Possible values of ::nrf_power_mode_t. */
+enum NRF_POWER_MODES
+{
+  NRF_POWER_MODE_CONSTLAT,  /**< Constant latency mode. See power management in the reference manual. */
+  NRF_POWER_MODE_LOWPWR     /**< Low power mode. See power management in the reference manual. */
+};
+
+
+/**@brief Possible values of ::nrf_power_failure_threshold_t */
+enum NRF_POWER_THRESHOLDS
+{
+  NRF_POWER_THRESHOLD_V21,  /**< 2.1 Volts power failure threshold. */
+  NRF_POWER_THRESHOLD_V23,  /**< 2.3 Volts power failure threshold. */
+  NRF_POWER_THRESHOLD_V25,  /**< 2.5 Volts power failure threshold. */ 
+  NRF_POWER_THRESHOLD_V27   /**< 2.7 Volts power failure threshold. */
+};
+
+
+/**@brief Possible values of ::nrf_power_dcdc_mode_t. */
+enum NRF_POWER_DCDC_MODES
+{
+  NRF_POWER_DCDC_DISABLE,          /**< The DCDC is disabled. */
+  NRF_POWER_DCDC_ENABLE            /**< The DCDC is enabled.  */
+};
+
+/**@brief Possible values of ::nrf_radio_notification_distance_t. */
+enum NRF_RADIO_NOTIFICATION_DISTANCES
+{
+  NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_800US,    /**< The distance from the active notification to start of radio activity. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_1740US,   /**< The distance from the active notification to start of radio activity. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_2680US,   /**< The distance from the active notification to start of radio activity. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_3620US,   /**< The distance from the active notification to start of radio activity. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_4560US,   /**< The distance from the active notification to start of radio activity. */
+  NRF_RADIO_NOTIFICATION_DISTANCE_5500US    /**< The distance from the active notification to start of radio activity. */
+};
+
+
+/**@brief Possible values of ::nrf_radio_notification_type_t. */
+enum NRF_RADIO_NOTIFICATION_TYPES
+{
+  NRF_RADIO_NOTIFICATION_TYPE_NONE = 0,        /**< The event does not have a radio notification signal. */
+  NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE,   /**< Using interrupt for notification when the radio will be enabled. */
+  NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
+  NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH,     /**< Using interrupt for notification both when the radio will be enabled and disabled. */
+};
+
+/**@brief SoC Events. */
+enum NRF_SOC_EVTS
+{
+  NRF_EVT_HFCLKSTARTED,                         /**< Event indicating that the HFCLK has started. */
+  NRF_EVT_POWER_FAILURE_WARNING,                /**< Event indicating that a power failure warning has occurred. */
+  NRF_EVT_FLASH_OPERATION_SUCCESS,              /**< Event indicating that the ongoing flash operation has completed successfully. */
+  NRF_EVT_FLASH_OPERATION_ERROR,                /**< Event indicating that the ongoing flash operation has timed out with an error. */
+  NRF_EVT_RADIO_BLOCKED,                        /**< Event indicating that a radio timeslot was blocked. */
+  NRF_EVT_RADIO_CANCELED,                       /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
+  NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */
+  NRF_EVT_RADIO_SESSION_IDLE,                   /**< Event indicating that a radio session is idle. */
+  NRF_EVT_RADIO_SESSION_CLOSED,                 /**< Event indicating that a radio session is closed. */
+  NRF_EVT_NUMBER_OF_EVTS
+};
+
+/**@} */
+
+/**@addtogroup NRF_SOC_TYPES Types
+ * @{ */
+
+/**@brief Represents a mutex for use with the nrf_mutex functions.
+ * @note Accessing the value directly is not safe, use the mutex functions!
+ */
+typedef volatile uint8_t nrf_mutex_t;
+
+/**@brief The interrupt priorities available to the application while the softdevice is active. */
+typedef uint8_t nrf_app_irq_priority_t;
+
+/**@brief Represents a power mode, used in power mode functions */
+typedef uint8_t nrf_power_mode_t;
+
+/**@brief Represents a power failure threshold value. */
+typedef uint8_t nrf_power_failure_threshold_t;
+
+/**@brief Represents a DCDC mode value. */
+typedef uint32_t nrf_power_dcdc_mode_t;
+
+/**@brief Radio notification distances. */
+typedef uint8_t nrf_radio_notification_distance_t;
+
+/**@brief Radio notification types. */
+typedef uint8_t nrf_radio_notification_type_t;
+
+/**@brief The Radio signal callback types. */
+enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
+{
+  NRF_RADIO_CALLBACK_SIGNAL_TYPE_START,             /**< This signal indicates the start of the radio timeslot. */
+  NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0,            /**< This signal indicates the NRF_TIMER0 interrupt. */
+  NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO,             /**< This signal indicates the NRF_RADIO interrupt. */
+  NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED,     /**< This signal indicates extend action failed. */
+  NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED   /**< This signal indicates extend action succeeded. */
+};
+
+/**@brief The actions requested by the signal callback.
+ *
+ *  This code gives the SOC instructions about what action to take when the signal callback has
+ *  returned.
+ */
+enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
+{
+  NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE,            /**< Return without action. */
+  NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND,          /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */
+  NRF_RADIO_SIGNAL_CALLBACK_ACTION_END,             /**< End the current radio timeslot. */
+  NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END  /**< Request a new radio timeslot and end the current timeslot. */
+};
+
+/**@brief Radio timeslot high frequency clock source configuration. */
+enum NRF_RADIO_HFCLK_CFG
+{
+  NRF_RADIO_HFCLK_CFG_DEFAULT,                      /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */
+  NRF_RADIO_HFCLK_CFG_FORCE_XTAL,                   /**< Force external crystal to be used as HF clock source during whole the timeslot. */
+};
+
+/**@brief Radio timeslot priorities. */
+enum NRF_RADIO_PRIORITY
+{
+  NRF_RADIO_PRIORITY_HIGH,                          /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
+  NRF_RADIO_PRIORITY_NORMAL,                        /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */
+};
+
+/**@brief Radio timeslot request type. */
+enum NRF_RADIO_REQUEST_TYPE
+{
+  NRF_RADIO_REQ_TYPE_EARLIEST,                      /**< Request timeslot as early as possible. This should always be used for the first request in a session. */
+  NRF_RADIO_REQ_TYPE_NORMAL                         /**< Normal timeslot request. */
+};
+
+/**@brief Parameters for a request for a timeslot as early as possible. */
+typedef struct
+{
+  uint8_t       hfclk;                              /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+  uint8_t       priority;                           /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+  uint32_t      length_us;                          /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
+  uint32_t      timeout_us;                         /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
+} nrf_radio_request_earliest_t;
+
+/**@brief Parameters for a normal radio request. */
+typedef struct
+{
+  uint8_t       hfclk;                              /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+  uint8_t       priority;                           /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+  uint32_t      distance_us;                        /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
+  uint32_t      length_us;                          /**< The radio timeslot length (in the range [100..100,000] microseconds). */
+} nrf_radio_request_normal_t;
+
+/**@brief Radio request parameters. */
+typedef struct
+{
+  uint8_t                         request_type;     /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
+  union
+  {
+    nrf_radio_request_earliest_t  earliest;         /**< Parameters for a request for a timeslot as early as possible. */
+    nrf_radio_request_normal_t    normal;           /**< Parameters for a normal radio request. */
+  } params;
+} nrf_radio_request_t;
+
+/**@brief Return parameters of the radio timeslot signal callback. */
+typedef struct
+{
+  uint8_t               callback_action;            /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
+  union
+  {
+    struct
+    {
+      nrf_radio_request_t * p_next;                 /**< The request parameters for the next radio timeslot. */
+    } request;                                      /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
+    struct
+    {
+      uint32_t              length_us;              /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
+    } extend;                                       /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
+  } params;
+} nrf_radio_signal_callback_return_param_t;
+
+/**@brief The radio signal callback type.
+ *
+ * @note In case of invalid return parameters, the radio timeslot will automatically end
+ *       immediately after returning from the signal callback and the
+ *       @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
+ * @note The returned struct pointer must remain valid after the signal callback
+ *       function returns. For instance, this means that it must not point to a stack variable.
+ *
+ * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
+ *
+ * @return Pointer to structure containing action requested by the application.
+ */
+typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
+
+/**@brief AES ECB data structure */
+typedef struct
+{
+  uint8_t key[SOC_ECB_KEY_LENGTH];                  /**< Encryption key. */
+  uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH];      /**< Clear Text data. */
+  uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH];    /**< Cipher Text data. */
+} nrf_ecb_hal_data_t;
+
+/**@} */
+
+/**@addtogroup NRF_SOC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initialize a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to initialize.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
+
+/**@brief Attempt to acquire a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to acquire.
+ *
+ * @retval ::NRF_SUCCESS The mutex was successfully acquired.
+ * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
+ */
+SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
+
+/**@brief Release a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to release.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
+
+/**@brief Enable External Interrupt.
+ * @note Corresponds to NVIC_EnableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was enabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
+ */
+SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn));
+
+/**@brief  Disable External Interrupt.
+ * @note Corresponds to NVIC_DisableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was disabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ */
+SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn));
+
+/**@brief  Get Pending Interrupt.
+ * @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in]   IRQn          See the NVIC_GetPendingIRQ documentation in CMSIS.
+ * @param[out]  p_pending_irq Return value from NVIC_GetPendingIRQ.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq));
+
+/**@brief  Set Pending Interrupt.
+ * @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is set pending.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn));
+
+/**@brief  Clear Pending Interrupt.
+ * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn));
+
+/**@brief Set Interrupt Priority.
+ * @note Corresponds to NVIC_SetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ * @pre Priority is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn      See the NVIC_SetPriority documentation in CMSIS.
+ * @param[in] priority  A valid IRQ priority for use by the application.
+ *
+ * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
+ */
+SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority));
+
+/**@brief Get Interrupt Priority.
+ * @note Corresponds to NVIC_GetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in]  IRQn         See the NVIC_GetPriority documentation in CMSIS.
+ * @param[out] p_priority   Return value from NVIC_GetPriority.
+ *
+ * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
+ */
+SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority));
+
+/**@brief System Reset.
+ * @note Corresponds to NVIC_SystemReset in CMSIS.
+ *
+ * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
+ */
+SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void));
+
+/**@brief Enters critical region.
+ *
+ * @post Application interrupts will be disabled.
+ * @sa sd_nvic_critical_region_exit
+ *
+ * @param[out]  p_is_nested_critical_region  1: If in a nested critical region.
+ *                                           0: Otherwise.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region));
+
+/**@brief Exit critical region.
+ *
+ * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
+ * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. 
+ *
+ * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region));
+
+/**@brief Query the capacity of the application random pool.
+ *
+ * @param[out] p_pool_capacity The capacity of the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
+
+/**@brief Get number of random bytes available to the application.
+ *
+ * @param[out] p_bytes_available The number of bytes currently available in the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
+
+/**@brief Get random bytes from the application pool.
+ *
+ * @param[out]  p_buff  Pointer to unit8_t buffer for storing the bytes.
+ * @param[in]   length  Number of bytes to take from pool and place in p_buff.
+ *
+ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
+ * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
+*/
+SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
+
+/**@brief Gets the reset reason register. 
+ *
+ * @param[out]  p_reset_reason  Contents of the NRF_POWER->RESETREAS register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
+
+/**@brief Clears the bits of the reset reason register. 
+ *
+ * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
+
+/**@brief Sets the power mode when in CPU sleep.
+ *
+ * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait
+ *
+ * @retval ::NRF_SUCCESS The power mode was set.
+ * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
+ */
+SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode));
+
+/**@brief Puts the chip in System OFF mode. 
+ *
+ * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
+ */
+SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
+
+/**@brief Enables or disables the power-fail comparator.
+ *
+ * Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] pof_enable    True if the power-fail comparator should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
+
+/**@brief Sets the power-fail threshold value.
+ *
+ * @param[in] threshold The power-fail threshold value to use.
+ *
+ * @retval ::NRF_SUCCESS The power failure threshold was set.
+ * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
+ */
+SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold));
+
+/**@brief Sets bits in the NRF_POWER->RAMON register.
+ *
+ * @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon));
+
+/**@brief Clears bits in the NRF_POWER->RAMON register.
+ *
+ * @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon));
+
+/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks.
+ *
+ * @param[out] p_ramon Content of NRF_POWER->RAMON register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon));
+
+/**@brief Set bits in the NRF_POWER->GPREGRET register.
+ *
+ * @param[in] gpregret_msk Bits to be set in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk));
+
+/**@brief Clear bits in the NRF_POWER->GPREGRET register.
+ *
+ * @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk));
+
+/**@brief Get contents of the NRF_POWER->GPREGRET register.
+ *
+ * @param[out] p_gpregret Contents of the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret));
+
+/**@brief Sets the DCDC mode.
+ *
+ * This function is to enable or disable the DCDC periperhal.
+ *
+ * @param[in] dcdc_mode The mode of the DCDC.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
+ */
+SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode));
+
+/**@brief Request the high frequency crystal oscillator.
+ *
+ * Will start the high frequency crystal oscillator, the startup time of the crystal varies
+ * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_release
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
+
+/**@brief Releases the high frequency crystal oscillator.
+ *
+ * Will stop the high frequency crystal oscillator, this happens immediately.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_request
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
+
+/**@brief Checks if the high frequency crystal oscillator is running.
+ *
+ * @see sd_clock_hfclk_request
+ * @see sd_clock_hfclk_release
+ *
+ * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
+
+/**@brief Waits for an application event.
+ * 
+ * An application event is either an application interrupt or a pended interrupt when the
+ * interrupt is disabled. When the interrupt is enabled it will be taken immediately since
+ * this function will wait in thread mode, then the execution will return in the application's
+ * main thread. When an interrupt is disabled and gets pended it will return to the application's 
+ * thread main. The application must ensure that the pended flag is cleared using 
+ * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for
+ * disabled interrupts, as the interrupt handler will clear the pending flag automatically for
+ * enabled interrupts.
+ *
+ * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0
+ * System Control Register (SCR). @sa CMSIS_SCB
+ *
+ * @note If an application interrupt has happened since the last time sd_app_evt_wait was
+ *       called this function will return immediately and not go to sleep. This is to avoid race
+ *       conditions that can occur when a flag is updated in the interrupt handler and processed
+ *       in the main loop.
+ *
+ * @post An application interrupt has happened or a interrupt pending flag is set.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
+
+/**@brief Get PPI channel enable register contents.
+ *
+ * @param[out] p_channel_enable The contents of the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
+
+/**@brief Set PPI channel enable register.
+ *
+ * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
+
+/**@brief Clear PPI channel enable register.
+ *
+ * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
+
+/**@brief Assign endpoints to a PPI channel.
+ *
+ * @param[in] channel_num Number of the PPI channel to assign.
+ * @param[in] evt_endpoint Event endpoint of the PPI channel.
+ * @param[in] task_endpoint Task endpoint of the PPI channel.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
+
+/**@brief Task to enable a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
+
+/**@brief Task to disable a channel group.
+ *
+ * @param[in] group_num Number of the PPI group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
+
+/**@brief Assign PPI channels to a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[in] channel_msk Mask of the channels to assign to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
+
+/**@brief Gets the PPI channels of a channel group.
+ *
+ * @param[in]   group_num Number of the channel group.
+ * @param[out]  p_channel_msk Mask of the channels assigned to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
+
+/**@brief Configures the Radio Notification signal.
+ *
+ * @note
+ *      - The notification signal latency depends on the interrupt priority settings of SWI used
+ *        for notification signal.
+ *      - To ensure that the radio notification signal behaves in a consistent way, always 
+ *        configure radio notifications when there is no protocol stack or other SoftDevice 
+ *        activity in progress. It is recommended that the radio notification signal is 
+ *        configured directly after the SoftDevice has been enabled.
+ *      - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
+ *        will interrupt the application to do Radio Event preparation.
+ *      - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
+ *        to shorten the connection events to have time for the Radio Notification signals.
+ *
+ * @param[in]  type      Type of notification signal.
+ *                       @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
+ *                       notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
+ *                       recommended (but not required) to be used with
+ *                       @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
+ *
+ * @param[in]  distance  Distance between the notification signal and start of radio activity.
+ *                       This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or 
+ *                       @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance));
+
+/**@brief Encrypts a block according to the specified parameters.
+ *
+ * 128-bit AES encryption.
+ *
+ * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
+ *                            parameters and one output parameter).
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
+
+/**@brief Gets any pending events generated by the SoC API.
+ *
+ * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
+ *
+ * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
+ *
+ * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
+ * @retval ::NRF_ERROR_NOT_FOUND No pending events. 
+ */
+SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
+
+/**@brief Get the temperature measured on the chip
+ * 
+ * This function will block until the temperature measurement is done.
+ * It takes around 50us from call to return.
+ *
+ * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function.
+ *
+ * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius.
+ *
+ * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
+ */
+SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
+
+/**@brief Flash Write
+*
+* Commands to write a buffer to flash
+*
+* If the SoftDevice is enabled:
+*  This call initiates the flash access command, and its completion will be communicated to the
+*  application with exactly one of the following events:
+*      - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+*      - @ref NRF_EVT_FLASH_OPERATION_ERROR   - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the 
+ * write has been completed
+*
+* @note
+*      - This call takes control over the radio and the CPU during flash erase and write to make sure that
+*        they will not interfere with the flash access. This means that all interrupts will be blocked
+*        for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
+*        and the command parameters).
+*
+*
+* @param[in]  p_dst Pointer to start of flash location to be written.
+* @param[in]  p_src Pointer to buffer with data to be written.
+* @param[in]  size  Number of 32-bit words to write. Maximum size is 256 32bit words.
+*
+* @retval ::NRF_ERROR_INVALID_ADDR   Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
+* @retval ::NRF_ERROR_BUSY           The previous command has not yet completed.
+* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words.
+* @retval ::NRF_ERROR_FORBIDDEN      Tried to write to or read from protected location.
+* @retval ::NRF_SUCCESS              The command was accepted.
+*/
+SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size));
+
+
+/**@brief Flash Erase page
+*
+* Commands to erase a flash page
+* If the SoftDevice is enabled:
+*  This call initiates the flash access command, and its completion will be communicated to the
+*  application with exactly one of the following events:
+*      - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+*      - @ref NRF_EVT_FLASH_OPERATION_ERROR   - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the 
+* erase has been completed
+*
+* @note
+*      - This call takes control over the radio and the CPU during flash erase and write to make sure that
+*        they will not interfere with the flash access. This means that all interrupts will be blocked
+*        for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual
+*        and the command parameters).
+*
+*
+* @param[in]  page_number Pagenumber of the page to erase
+* @retval ::NRF_ERROR_INTERNAL      If a new session could not be opened due to an internal error.
+* @retval ::NRF_ERROR_INVALID_ADDR  Tried to erase to a non existing flash page.
+* @retval ::NRF_ERROR_BUSY          The previous command has not yet completed.
+* @retval ::NRF_ERROR_FORBIDDEN     Tried to erase a protected page.
+* @retval ::NRF_SUCCESS             The command was accepted.
+*/
+SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
+
+
+/**@brief Flash Protection set
+ *
+ * Commands to set the flash protection registers PROTENSETx
+ *
+ * @note To read the values in PROTENSETx you can read them directly. They are only write-protected.
+ *
+ * @param[in]  protenset0 Value to be written to PROTENSET0.
+ * @param[in]  protenset1 Value to be written to PROTENSET1.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice.
+ * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx.
+ */
+SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1));
+
+/**@brief Opens a session for radio requests.
+ *
+ * @note Only one session can be open at a time.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
+ *       starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
+ *       by the application.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
+ *       interrupt occurs.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
+ *       interrupt occurs.
+ * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
+ *       implies that none of the sd_* API calls can be used from p_radio_signal_callback().
+ *
+ * @param[in] p_radio_signal_callback The signal callback.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
+ * @retval ::NRF_ERROR_BUSY If session cannot be opened.
+ * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
+
+/**@brief Closes a session for radio requests.
+ *
+ * @note Any current radio timeslot will be finished before the session is closed.
+ * @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
+ * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
+ *       event is received.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened.
+ * @retval ::NRF_ERROR_BUSY If session is currently being closed.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
+
+/**@brief Requests a radio timeslot.
+ *
+ * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
+ *       and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type
+ *       @ref NRF_RADIO_REQ_TYPE_EARLIEST.
+ * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
+ *       p_request->distance_us and is given relative to the start of the previous timeslot. 
+ * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
+ * @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this
+ *       function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
+ *       The application may then try to schedule the first radio timeslot again.
+ * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
+ *       Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
+ * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
+ * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
+ *       specified radio timeslot start, but this does not affect the actual start time of the timeslot.
+ * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
+ *       (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is 
+ *       guaranteed to be clocked from the external crystal.
+ * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
+ *       during the radio timeslot.
+ *
+ * @param[in] p_request Pointer to the request parameters.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
+ * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
+ * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request ));
+
+/**@} */
+
+#endif // NRF_SOC_H__
+
+/**@} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/nrf_svc.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 NRF_SVC__
+#define NRF_SVC__
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#define SVCALL(number, return_type, signature) \
+  _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \
+  _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") \
+  _Pragma("GCC diagnostic push") \
+  _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+  __attribute__((naked)) static return_type signature \
+  { \
+    __asm( \
+        "svc %0\n" \
+        "bx r14" : : "I" ((uint32_t) number) : "r0" \
+    ); \
+  }    \
+  _Pragma("GCC diagnostic pop")
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = number) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature  
+#endif
+#endif  // SVCALL
+
+#endif  // SVCALL_AS_NORMAL_FUNCTION
+#endif  // NRF_SVC__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/nordic_sdk/components/softdevice/s130/headers/softdevice_assert.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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 must reproduce the above copyright notice, 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 other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/** @brief Utilities for verifying program logic
+ */
+
+#ifndef SOFTDEVICE_ASSERT_H_
+#define SOFTDEVICE_ASSERT_H_
+
+#include <stdint.h>
+
+/** @brief This function handles assertions.
+ *
+ *
+ * @note
+ * This function is called when an assertion has triggered.
+ * 
+ *
+ * @param line_num The line number where the assertion is called
+ * @param file_name Pointer to the file name
+ */
+void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name);
+
+
+/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ 
+/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \
+/** @brief Check intended for production code
+ *
+ * Check passes if "expr" evaluates to true. */
+#define ASSERT(expr) \
+if (expr)                                                                     \
+{                                                                             \
+}                                                                             \
+else                                                                          \
+{                                                                             \
+  assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__);        \
+  /*lint -unreachable */                                                      \
+}
+
+#endif /* SOFTDEVICE_ASSERT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/nrf51-sdk/source/supress-warnings.cmake	Mon Oct 17 12:41:20 2016 +0000
@@ -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 nrf51-sdk")
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+    set_target_properties(nrf51-sdk
+        PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function -Wno-missing-field-initializers"
+    )
+endif()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/softdevice_nrf51822_licence_agreement.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -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.
+ *
+ * /
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,264 @@
+/* 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 "ble_flash.h"
+#include "ble_conn_params.h"
+
+#include "btle_gap.h"
+#include "btle_advertising.h"
+#include "custom/custom_helper.h"
+
+#include "ble/GapEvents.h"
+#include "nRF5xn.h"
+
+extern "C" {
+#include "pstorage.h"
+#include "device_manager.h"
+#include "softdevice_handler.h"
+#include "ble_stack_handler_types.h"
+}
+
+#include "ble_hci.h"
+#include "btle_discovery.h"
+
+#include "nRF5xGattClient.h"
+#include "nRF5xServiceDiscovery.h"
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+
+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);
+
+static void btle_handler(ble_evt_t *p_ble_evt);
+static uint32_t gatt_table_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
+
+static void sys_evt_dispatch(uint32_t sys_evt)
+{
+    pstorage_sys_event_handler(sys_evt);
+}
+
+/**
+ * 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().
+ *
+ * In mbed OS, a callback for intern_softdevice_events_execute() is posted
+ * to the scheduler, which then executes in thread mode. In mbed-classic,
+ * event processing happens right-away in interrupt context (which is more
+ * risk-prone). In either case, the logic of event processing is identical.
+ */
+static uint32_t eventHandler()
+{
+#ifdef YOTTA_CFG_MBED_OS
+    minar::Scheduler::postCallback(intern_softdevice_events_execute);
+#else
+    intern_softdevice_events_execute();
+#endif
+
+    return NRF_SUCCESS;
+}
+
+error_t
+btle_set_gatt_table_size(uint32_t size)
+{
+    if (size >= BLE_GATTS_ATTR_TAB_SIZE_MIN)
+    {
+        gatt_table_size = size;
+        return ERROR_NONE;
+    }
+
+    return ERROR_INVALID_PARAM;
+}
+
+error_t btle_init(void)
+{
+    nrf_clock_lfclksrc_t clockSource;
+    if (NRF_CLOCK->LFCLKSRC & (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) {
+        clockSource = NRF_CLOCK_LFCLKSRC_XTAL_20_PPM;
+    } else {
+        clockSource = NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION;
+    }
+    SOFTDEVICE_HANDLER_INIT(clockSource, eventHandler);
+
+    // Enable BLE stack
+    /**
+     * 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.
+     */
+    static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true;
+    ble_enable_params_t enableParams = {
+        .gatts_enable_params = {
+            .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT,
+            .attr_tab_size = gatt_table_size
+        }
+    };
+    if (sd_ble_enable(&enableParams) != NRF_SUCCESS) {
+        return ERROR_INVALID_PARAM;
+    }
+
+    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;
+    }
+
+    ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
+    ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
+
+    return btle_gap_init();
+}
+
+static void btle_handler(ble_evt_t *p_ble_evt)
+{
+    /* Library service handlers */
+#if SDK_CONN_PARAMS_MODULE_ENABLE
+    ble_conn_params_on_ble_evt(p_ble_evt);
+#endif
+
+    dm_ble_evt_handler(p_ble_evt);
+
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+    bleGattcEventHandler(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<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;
+            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);
+            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;
+            }
+
+            // Close all pending discoveries for this connection
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+            nRF5xGattClient& gattClient = ble.getGattClient();
+            gattClient.characteristicDescriptorDiscoverer().terminate(handle, BLE_ERROR_INVALID_STATE);
+            gattClient.discovery().terminate(handle);
+#endif
+
+            gap.processDisconnectionEvent(handle, reason);
+            break;
+        }
+
+        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(false, (void) 0);
+}
+
+/*!
+    @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();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,36 @@
+/* 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 "ble.h"
+
+error_t     btle_init(void);
+error_t     btle_set_gatt_table_size(uint32_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ifndef _BTLE_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_advertising.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,46 @@
+/* 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 "ble_advdata.h"
+#include "btle.h"
+
+/**************************************************************************/
+/*!
+    @brief      Starts the advertising process
+
+    @returns
+*/
+/**************************************************************************/
+error_t btle_advertising_start(void)
+{
+    ble_gap_adv_params_t adv_para = {0};
+
+    /* Set the default advertising parameters */
+    adv_para.type        = BLE_GAP_ADV_TYPE_ADV_IND;
+    adv_para.p_peer_addr = NULL; /* Undirected advertising */
+    adv_para.fp          = BLE_GAP_ADV_FP_ANY;
+    adv_para.p_whitelist = NULL;
+    adv_para.interval    = (CFG_GAP_ADV_INTERVAL_MS * 8) / 5; /* Advertising
+                                                               * interval in
+                                                               * units of 0.625
+                                                               * ms */
+    adv_para.timeout     = CFG_GAP_ADV_TIMEOUT_S;
+
+    ASSERT_STATUS( sd_ble_gap_adv_start(&adv_para));
+
+    return ERROR_NONE;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_advertising.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ADVERTISING_H_
+#define _BTLE_ADVERTISING_H_
+
+#include "common/common.h"
+
+error_t btle_advertising_start(void);
+
+#endif // ifndef _BTLE_ADVERTISING_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_discovery.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,128 @@
+/* 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 "nRF5xServiceDiscovery.h"
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+#include "nRF5xGattClient.h"
+#include "nRF5xn.h"
+
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
+{
+    nRF5xn                &ble         = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
+    nRF5xGap              &gap         = (nRF5xGap &) ble.getGap();
+    nRF5xGattClient       &gattClient  = (nRF5xGattClient &) ble.getGattClient();
+    nRF5xServiceDiscovery &sdSingleton = gattClient.discovery();
+    nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer =
+        gattClient.characteristicDescriptorDiscoverer();
+
+    switch (p_ble_evt->header.evt_id) {
+        case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+                case BLE_GATT_STATUS_SUCCESS:
+                    sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
+                    break;
+
+                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+                default:
+                    sdSingleton.terminate();
+                    break;
+            }
+            break;
+
+        case BLE_GATTC_EVT_CHAR_DISC_RSP:
+            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+                case BLE_GATT_STATUS_SUCCESS:
+                    sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
+                    break;
+
+                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+                default:
+                    sdSingleton.terminateCharacteristicDiscovery(BLE_ERROR_NONE);
+                    break;
+            }
+            break;
+
+        case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+            if (sdSingleton.isActive()) {
+                sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
+            }
+            break;
+
+        case BLE_GATTC_EVT_READ_RSP: {
+                GattReadCallbackParams response = {
+                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
+                    .handle     = p_ble_evt->evt.gattc_evt.params.read_rsp.handle,
+                    .offset     = p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
+                    .len        = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
+                    .data       = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
+                };
+                gattClient.processReadResponse(&response);
+            }
+            break;
+
+        case BLE_GATTC_EVT_WRITE_RSP: {
+                GattWriteCallbackParams response = {
+                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
+                    .handle     = p_ble_evt->evt.gattc_evt.params.write_rsp.handle,
+                    .writeOp    = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op),
+                    .offset     = p_ble_evt->evt.gattc_evt.params.write_rsp.offset,
+                    .len        = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
+                    .data       = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
+                };
+                gattClient.processWriteResponse(&response);
+            }
+            break;
+
+        case BLE_GATTC_EVT_HVX: {
+                GattHVXCallbackParams params;
+                params.connHandle = p_ble_evt->evt.gattc_evt.conn_handle;
+                params.handle     = p_ble_evt->evt.gattc_evt.params.hvx.handle;
+                params.type       = static_cast<HVXType_t>(p_ble_evt->evt.gattc_evt.params.hvx.type);
+                params.len        = p_ble_evt->evt.gattc_evt.params.hvx.len;
+                params.data       = p_ble_evt->evt.gattc_evt.params.hvx.data;
+
+                gattClient.processHVXEvent(&params);
+            }
+            break;
+
+        case BLE_GATTC_EVT_DESC_DISC_RSP: {
+            uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+            uint16_t status = p_ble_evt->evt.gattc_evt.gatt_status;
+            const ble_gattc_evt_desc_disc_rsp_t& discovered_descriptors = p_ble_evt->evt.gattc_evt.params.desc_disc_rsp;
+
+            switch(status) {
+                case BLE_GATT_STATUS_SUCCESS:
+                    characteristicDescriptorDiscoverer.process(
+                        conn_handle,
+                        discovered_descriptors
+                    );
+                    break;
+                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+                    // end of discovery
+                    characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_NONE);
+                    break;
+                default:
+                    characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_UNSPECIFIED);
+                    break;
+            }
+        }   break;
+    }
+
+    sdSingleton.progressCharacteristicDiscovery();
+    sdSingleton.progressServiceDiscovery();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_discovery.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,22 @@
+/* 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_DISCOVERY_H_
+#define _BTLE_DISCOVERY_H_
+
+void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+
+#endif /*_BTLE_DISCOVERY_H_*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_gap.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -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 "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
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_gap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_security.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,316 @@
+/* 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 "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
+static ble_gap_sec_params_t securityParameters = {
+    .bond          = true,         /**< Perform bonding. */
+    .mitm          = true,         /**< Man In The Middle protection required. */
+    .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_periph  = {
+      .enc  = 1,                   /**< Long Term Key and Master Identification. */
+      .id   = 1,                   /**< Identity Resolving Key and Identity Address Information. */
+      .sign = 1,                   /**< Connection Signature Resolving Key. */
+    },                             /**< 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, &params);
+
+    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);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/btle_security.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,128 @@
+/* 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);
+
+/**
+ * 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);
+
+/**
+ * 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);
+
+#endif /* _BTLE_SECURITY_H_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/custom/custom_helper.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,380 @@
+/* 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"
+
+/*
+ * 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 const unsigned UUID_TABLE_MAX_ENTRIES = 4; /* This is the maximum number of 128-bit UUIDs with distinct bases that
+                                                   * we expect to be in use; increase this limit if needed. */
+static unsigned uuidTableEntries = 0; /* current usage of the table */
+converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES];
+
+/**
+ * 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,
+                                     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);
+		switch (requiredSecurity) {
+			case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
+				BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
+				break;
+			case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
+				BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
+				break;
+			case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
+				BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);
+				break;
+			case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
+				BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&cccd_md.write_perm);
+				break;
+			case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
+				BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&cccd_md.write_perm);
+				break;
+			default:
+				BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
+				break;
+		}
+	}
+
+    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;
+    }
+
+    /* 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;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/btle/custom/custom_helper.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,60 @@
+/* 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 "ble.h"
+#include "ble/UUID.h"
+#include "ble/GattCharacteristic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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,
+                                     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_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/ansi_escape.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ */
+
+/** @} */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/assertion.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/*!
+    @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(...)                      ASSERT_TRUE(__VA_ARGS__)
+#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_ */
+
+/** @} */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/binary.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ */
+
+/** @} */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/ble_error.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ */
+
+ /**  @} */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/common.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ */
+
+/**  @} */
+/**  @} */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/common/compiler.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,152 @@
+/**************************************************************************/
+/*!
+    @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
+
+#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))
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _COMPILER_GCC_H_ */
+
+/// @}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xCharacteristicDescriptorDiscoverer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,235 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+#include "ble_err.h"
+#include "ble/DiscoveredCharacteristicDescriptor.h"
+
+nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer() :
+    discoveryRunning() {
+    // nothing to do
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() {
+    // nothing to do
+}
+
+ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch(
+    const DiscoveredCharacteristic& characteristic,
+    const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+    const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
+) {
+    Gap::Handle_t connHandle = characteristic.getConnectionHandle();
+    // it is ok to deduce that the start handle for descriptors is after
+    // the characteristic declaration and the characteristic value declaration
+    // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3)
+    Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2;
+    Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle();
+
+    // check if there is any descriptor to discover
+    if (descriptorEndHandle < descriptorStartHandle) {
+        CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = {
+            characteristic,
+            BLE_ERROR_NONE
+        };
+        terminationCallback.call(&termParams);
+        return BLE_ERROR_NONE;
+    }
+
+    // check if we can run this discovery
+    if (isConnectionInUse(connHandle)) {
+        return BLE_STACK_BUSY;
+    }
+
+    // get a new discovery slot, if none are available, just return
+    Discovery* discovery = getAvailableDiscoverySlot();
+    if(discovery == NULL) {
+        return BLE_STACK_BUSY;
+    }
+
+    // try to launch the discovery
+    ble_error_t err = gattc_descriptors_discover(connHandle, descriptorStartHandle, descriptorEndHandle);
+    if(!err) {
+        // commit the new discovery to its slot
+        *discovery = Discovery(characteristic, discoveryCallback, terminationCallback);
+    }
+
+    return err;
+}
+
+bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const {
+    for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) {
+        if(discoveryRunning[i].getCharacteristic() == characteristic) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) {
+    Discovery* discovery = findRunningDiscovery(characteristic);
+    if(discovery) {
+        // call terminate anyway
+        terminate(discovery, BLE_ERROR_NONE);
+    }
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) {
+    Discovery* discovery = findRunningDiscovery(connectionHandle);
+    // the discovery has been removed
+    if(!discovery) {
+        return;
+    }
+
+    for (uint16_t i = 0; i < descriptors.count; ++i) {
+        discovery->process(
+            descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid)
+        );
+    }
+
+    // prepare the next discovery request (if needed)
+    uint16_t startHandle = descriptors.descs[descriptors.count - 1].handle + 1;
+    uint16_t endHandle = discovery->getCharacteristic().getLastHandle();
+
+    if(startHandle > endHandle) {
+        terminate(discovery, BLE_ERROR_NONE);
+        return;
+    }
+
+    ble_error_t err = gattc_descriptors_discover(connectionHandle, startHandle, endHandle);
+    if(err) {
+        terminate(discovery, err);
+        return;
+    }
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle, ble_error_t err) {
+    Discovery* discovery = findRunningDiscovery(handle);
+    // the discovery has already been terminated
+    if(!discovery) {
+        return;
+    }
+
+    terminate(discovery, err);
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::terminate(Discovery* discovery, ble_error_t err) {
+    // temporary copy, user code can try to launch a new discovery in the onTerminate
+    // callback. So, this discovery should not appear in such case.
+    Discovery tmp = *discovery;
+    *discovery = Discovery();
+    tmp.terminate(err);
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery*
+nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) {
+    for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) {
+        if((discoveryRunning[i].getCharacteristic() == characteristic) &&
+           (discoveryRunning[i].isEmpty() == false)) {
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery*
+nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) {
+    for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) {
+        if((discoveryRunning[i].getCharacteristic().getConnectionHandle() == handle) &&
+           (discoveryRunning[i].isEmpty() == false)) {
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery*
+nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() {
+    for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) {
+        if(discoveryRunning[i].isEmpty()) {
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}
+
+bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) {
+     return findRunningDiscovery(connHandle) != NULL;
+}
+
+ble_error_t nRF5xCharacteristicDescriptorDiscoverer::gattc_descriptors_discover(
+    uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle) {
+
+    ble_gattc_handle_range_t discoveryRange = {
+        start_handle,
+        end_handle
+    };
+    uint32_t err = sd_ble_gattc_descriptors_discover(connection_handle, &discoveryRange);
+
+    switch(err) {
+        case NRF_SUCCESS:
+            return BLE_ERROR_NONE;
+        case BLE_ERROR_INVALID_CONN_HANDLE:
+            return BLE_ERROR_INVALID_PARAM;
+        case NRF_ERROR_INVALID_ADDR:
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        case NRF_ERROR_BUSY:
+            return BLE_STACK_BUSY;
+        default:
+            return BLE_ERROR_UNSPECIFIED;
+    }
+}
+
+// implementation of nRF5xCharacteristicDescriptorDiscoverer::Discovery
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery() :
+    characteristic(), onDiscovery(), onTerminate() {
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery(
+    const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) :
+    characteristic(c), onDiscovery(dCb), onTerminate(tCb) {
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::Discovery::process(
+    GattAttribute::Handle_t handle, const UUID& uuid) {
+    CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
+        characteristic,
+        DiscoveredCharacteristicDescriptor(
+            characteristic.getGattClient(),
+            characteristic.getConnectionHandle(),
+            handle,
+            uuid
+        )
+    };
+    onDiscovery.call(&params);
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::Discovery::terminate(ble_error_t err) {
+    CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+        characteristic,
+        err
+    };
+
+    onTerminate.call(&params);
+}
+
+bool nRF5xCharacteristicDescriptorDiscoverer::Discovery::isEmpty() const {
+    return *this == Discovery();
+}
+
+const DiscoveredCharacteristic& nRF5xCharacteristicDescriptorDiscoverer::Discovery::getCharacteristic() const {
+    return characteristic;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xCharacteristicDescriptorDiscoverer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,214 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+
+#include "ble/Gap.h"
+#include "ble/DiscoveredCharacteristic.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "ble/GattClient.h"
+#include "ble_gattc.h"
+
+/**
+ * @brief Manage the discovery of Characteristic descriptors
+ * @details is a bridge between BLE API and Nordic stack regarding Characteristic
+ * Descriptor discovery. The BLE API can launch, monitor and ask for termination
+ * of a discovery. The Nordic stack will provide new descriptors and indicate when
+ * the discovery is done.
+ */
+class nRF5xCharacteristicDescriptorDiscoverer
+{
+    typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t;
+    typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t;
+
+public:
+    /**
+     * @brief Construct a new characteristic descriptor discoverer.
+     */
+    nRF5xCharacteristicDescriptorDiscoverer();
+
+    /**
+     * @brief Destroy a characteristic descriptor discoverer.
+     */
+    ~nRF5xCharacteristicDescriptorDiscoverer();
+
+    /**
+     * Launch a new characteristic descriptor discovery for a given DiscoveredCharacteristic.
+     * @param characteristic The characteristic owning the descriptors to discover.
+     * @param discoveryCallback The callback called when a descriptor is discovered.
+     * @param terminationCallback The callback called when the discovery process end.
+     * @return BLE_ERROR_NONE if characteristic descriptor discovery is launched successfully;
+     *         else an appropriate error.
+     * @note: this will be called by BLE API side.
+     */
+    ble_error_t launch(
+        const DiscoveredCharacteristic& characteristic,
+        const DiscoveryCallback_t& discoveryCallback,
+        const TerminationCallback_t& terminationCallback
+    );
+
+    /**
+     * @brief indicate if a characteristic descriptor discovery is active for a
+     * given DiscoveredCharacteristic.
+     * @param characteristic The characteristic for whom the descriptor might be
+     * currently discovered.
+     * @return true if descriptors of characteristic are discovered, false otherwise.
+     * @note: this will be called by BLE API side.
+     */
+    bool isActive(const DiscoveredCharacteristic& characteristic) const;
+
+    /**
+     * @brief request the termination of characteristic descriptor discovery
+     * for a give DiscoveredCharacteristic
+     * @param characteristic The characteristic for whom the descriptor discovery
+     * should be stopped.
+     * @note: this will be called by BLE API side.
+     */
+    void requestTerminate(const DiscoveredCharacteristic& characteristic);
+
+    /**
+     * @brief process descriptors discovered from the Nordic stack.
+     * @param connectionHandle The connection handle upon which descriptors has been
+     * discovered.
+     * @param descriptors Discovered descriptors.
+     * @note This will be called by the Nordic stack.
+     */
+    void process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors);
+
+    /**
+     * @brief Called by the Nordic stack when the discovery is over.
+     * @param The connection handle upon which the discovery process is done.
+     * @param err An error if the termination is due to an error.
+     */
+    void terminate(uint16_t connectionHandle, ble_error_t err);
+
+private:
+    // protection against copy construction and assignment
+    nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&);
+    nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&);
+
+    /**
+     * @brief Discovery process, it store the DiscoveredCharacteristic, the
+     * discovery callback and the termination callback.
+     */
+    class Discovery {
+    public:
+        /**
+         * @brief Construct an empty discovery, such can be considerate as a not running discovery.
+         * @note #isEmpty function will return true
+         */
+        Discovery();
+
+        /**
+         * @brief Construct a valid discovery process.
+         *
+         * @param c the characteristic from whom descriptors will be discovered.
+         * @param dCb The discovery callback called each time a descriptor is discovered.
+         * @param tCb The termination callback called when the discovery terminate.
+         *
+         * @note #isEmpty function will return false
+         */
+        Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb);
+
+        /**
+         * @brief Process the discovery of a descriptor.
+         *
+         * @param handle The attribute handle of the descriptor found
+         * @param uuid The UUID of the descriptor found.
+         */
+        void process(GattAttribute::Handle_t handle, const UUID& uuid);
+
+        /**
+         * @brief Terminate the discovery process.
+         *
+         * @param err Error associate with the termination
+         * @note after this call #isEmpty function will return true.
+         */
+        void terminate(ble_error_t err);
+
+        /**
+         * @brief check if the discovery process is empty or not. Empty discovery are
+         * not running.
+         *
+         * @detail Discovery are empty after:
+         *     - a default construction
+         *     - a copy construction form a default constructed
+         *     - an assignment from a default constructed Discovery
+         * @return true if the Discovery is empty and false otherwise.
+         */
+        bool isEmpty() const;
+
+        /**
+         * @brief return the characteristic from whom descriptors are discovered.
+         * @return the characteristic from whom descriptors are discovered.
+         */
+        const DiscoveredCharacteristic& getCharacteristic() const;
+
+        /**
+         * @brief equal to operator, test if two discovery process are equal
+         *
+         * @param lhs left hand side of the expression
+         * @param rhs right hand side of the expression
+         * @return true if lhs == rhs
+         */
+        friend bool operator==(const Discovery& lhs, const Discovery& rhs) {
+            return lhs.characteristic == rhs.characteristic &&
+                   lhs.onDiscovery == rhs.onDiscovery &&
+                   lhs.onTerminate == rhs.onTerminate;
+        }
+
+        /**
+         * @brief not equal to operator, test if two discovery process are not equal
+         *
+         * @param lhs left hand side of the expression
+         * @param rhs right hand side of the expression
+         * @return true if lhs != rhs
+         */
+        friend bool operator!=(const Discovery& lhs, const Discovery& rhs) {
+            return !(lhs == rhs);
+        }
+
+    private:
+        DiscoveredCharacteristic characteristic;
+        DiscoveryCallback_t onDiscovery;
+        TerminationCallback_t onTerminate;
+    };
+
+    // find a running discovery process
+    Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic);
+    Discovery* findRunningDiscovery(uint16_t handle);
+
+    // Called to terminate a discovery is over.
+    void terminate(Discovery* discovery, ble_error_t err);
+
+    // get one slot for a discovery process
+    Discovery* getAvailableDiscoverySlot();
+
+    // indicate if a connection is already running a discovery
+    bool isConnectionInUse(uint16_t connHandle);
+
+    // low level start of a discovery
+    static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle);
+
+    // count of concurrent connections which can run a descriptor discovery process
+    static const size_t MAXIMUM_CONCURRENT_CONNECTIONS_COUNT = 3;
+
+    // array of running discoveries
+    Discovery discoveryRunning[MAXIMUM_CONCURRENT_CONNECTIONS_COUNT];
+};
+
+#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xDiscoveredCharacteristic.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,63 @@
+/* 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 "nRF5xDiscoveredCharacteristic.h"
+#include "nRF5xGattClient.h"
+#include "ble_gatt.h"
+
+void
+nRF5xDiscoveredCharacteristic::setup(nRF5xGattClient         *gattcIn,
+                                     Gap::Handle_t            connectionHandleIn,
+                                     ble_gatt_char_props_t    propsIn,
+                                     GattAttribute::Handle_t  declHandleIn,
+                                     GattAttribute::Handle_t  valueHandleIn)
+{
+    gattc       = gattcIn;
+    connHandle  = connectionHandleIn;
+    declHandle  = declHandleIn;
+    valueHandle = valueHandleIn;
+
+    props._broadcast       = propsIn.broadcast;
+    props._read            = propsIn.read;
+    props._writeWoResp     = propsIn.write_wo_resp;
+    props._write           = propsIn.write;
+    props._notify          = propsIn.notify;
+    props._indicate        = propsIn.indicate;
+    props._authSignedWrite = propsIn.auth_signed_wr;
+}
+
+void
+nRF5xDiscoveredCharacteristic::setup(nRF5xGattClient         *gattcIn,
+                                      Gap::Handle_t            connectionHandleIn,
+                                     UUID::ShortUUIDBytes_t   uuidIn,
+                                     ble_gatt_char_props_t    propsIn,
+                                     GattAttribute::Handle_t  declHandleIn,
+                                     GattAttribute::Handle_t  valueHandleIn)
+{
+    gattc       = gattcIn;
+    connHandle  = connectionHandleIn;
+    uuid        = uuidIn;
+    declHandle  = declHandleIn;
+    valueHandle = valueHandleIn;
+
+    props._broadcast       = propsIn.broadcast;
+    props._read            = propsIn.read;
+    props._writeWoResp     = propsIn.write_wo_resp;
+    props._write           = propsIn.write;
+    props._notify          = propsIn.notify;
+    props._indicate        = propsIn.indicate;
+    props._authSignedWrite = propsIn.auth_signed_wr;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xDiscoveredCharacteristic.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,45 @@
+/* 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 __NRF_DISCOVERED_CHARACTERISTIC_H__
+#define __NRF_DISCOVERED_CHARACTERISTIC_H__
+
+#include "ble/DiscoveredCharacteristic.h"
+#include "ble_gatt.h"
+
+class nRF5xGattClient; /* forward declaration */
+
+class nRF5xDiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+    void setup(nRF5xGattClient         *gattcIn,
+               Gap::Handle_t            connectionHandleIn,
+               ble_gatt_char_props_t    propsIn,
+               GattAttribute::Handle_t  declHandleIn,
+               GattAttribute::Handle_t  valueHandleIn);
+
+    void setup(nRF5xGattClient         *gattcIn,
+               Gap::Handle_t            connectionHandleIn,
+               UUID::ShortUUIDBytes_t   uuidIn,
+               ble_gatt_char_props_t    propsIn,
+               GattAttribute::Handle_t  declHandleIn,
+               GattAttribute::Handle_t  valueHandleIn);
+
+    void setLastHandle(GattAttribute::Handle_t last) {
+      lastHandle = last;
+    }
+};
+
+#endif /* __NRF_DISCOVERED_CHARACTERISTIC_H__ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGap.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,938 @@
+/* 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 "nRF5xn.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif
+#include "ble/BLE.h"
+
+#include "common/common.h"
+#include "ble_advdata.h"
+#include "ble_hci.h"
+
+void radioNotificationStaticCallback(bool param) {
+    nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
+    gap.processRadioNotificationEvent(param);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the advertising parameters and payload for the device
+
+    @param[in]  params
+                Basic advertising details, including the advertising
+                delay, timeout and how the device should be advertised
+    @params[in] advData
+                The primary advertising data payload
+    @params[in] scanResponse
+                The optional Scan Response payload if the advertising
+                type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
+                in \ref GapAdveritinngParams
+
+    @returns    \ref ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @retval     BLE_ERROR_BUFFER_OVERFLOW
+                The proposed action would cause a buffer overflow.  All
+                advertising payloads must be <= 31 bytes, for example.
+
+    @retval     BLE_ERROR_NOT_IMPLEMENTED
+                A feature was requested that is not yet supported in the
+                nRF51 firmware or hardware.
+
+    @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
+                One of the proposed values is outside the valid range.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
+{
+    /* Make sure we don't exceed the advertising payload length */
+    if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+        return BLE_ERROR_BUFFER_OVERFLOW;
+    }
+
+    /* Make sure we have a payload! */
+    if (advData.getPayloadLen() == 0) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /* Check the scan response payload limits */
+    //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
+    //{
+    //    /* Check if we're within the upper limit */
+    //    if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
+    //    {
+    //        return BLE_ERROR_BUFFER_OVERFLOW;
+    //    }
+    //    /* Make sure we have a payload! */
+    //    if (advData.getPayloadLen() == 0)
+    //    {
+    //        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    //    }
+    //}
+
+    /* Send advertising data! */
+    ASSERT(ERROR_NONE ==
+           sd_ble_gap_adv_data_set(advData.getPayload(),
+                                   advData.getPayloadLen(),
+                                   scanResponse.getPayload(),
+                                   scanResponse.getPayloadLen()),
+           BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    /* Make sure the GAP Service appearance value is aligned with the
+     *appearance from GapAdvertisingData */
+    ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
+           BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
+    /* contains a flags AD type, etc. */
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Starts the BLE HW, initialising any services that were
+            added before this function was called.
+
+    @note   All services must be added before calling this function!
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
+{
+    /* Make sure we support the advertising type */
+    if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
+        /* ToDo: This requires a propery security implementation, etc. */
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /* Check interval range */
+    if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
+        /* Min delay is slightly longer for unconnectable devices */
+        if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
+            (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+    } else {
+        if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
+            (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+    }
+
+    /* Check timeout is zero for Connectable Directed */
+    if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
+        /* Timeout must be 0 with this type, although we'll never get here */
+        /* since this isn't implemented yet anyway */
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /* Check timeout for other advertising types */
+    if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
+        (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /* Allocate the stack's whitelist statically */
+    ble_gap_whitelist_t  whitelist;
+    ble_gap_addr_t      *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
+    ble_gap_irk_t       *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
+    /* Initialize the whitelist */
+    whitelist.pp_addrs   = whitelistAddressPtrs;
+    whitelist.pp_irks    = whitelistIrkPtrs;
+    whitelist.addr_count = 0;
+    whitelist.irk_count  = 0;
+
+    /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
+    if (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) {
+        ble_error_t error = generateStackWhitelist(whitelist);
+        if (error != BLE_ERROR_NONE) {
+            return error;
+        }
+    }
+
+    /* Start Advertising */
+    ble_gap_adv_params_t adv_para = {0};
+
+    adv_para.type        = params.getAdvertisingType();
+    adv_para.p_peer_addr = NULL;                           // Undirected advertisement
+    adv_para.fp          = advertisingPolicyMode;
+    adv_para.p_whitelist = &whitelist;
+    adv_para.interval    = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms)
+    adv_para.timeout     = params.getTimeout();
+
+    ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    state.advertising = 1;
+
+    return BLE_ERROR_NONE;
+}
+
+/* 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)
+ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
+{
+    /* Allocate the stack's whitelist statically */
+    ble_gap_whitelist_t  whitelist;
+    ble_gap_addr_t      *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
+    ble_gap_irk_t       *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
+    /* Initialize the whitelist */
+    whitelist.pp_addrs   = whitelistAddressPtrs;
+    whitelist.pp_irks    = whitelistIrkPtrs;
+    whitelist.addr_count = 0;
+    whitelist.irk_count  = 0;
+
+    /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
+    if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
+        ble_error_t error = generateStackWhitelist(whitelist);
+        if (error != BLE_ERROR_NONE) {
+            return error;
+        }
+    }
+
+    ble_gap_scan_params_t scanParams = {
+        .active      = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */
+        .selective   = scanningPolicyMode,    /**< If 1, ignore unknown devices (non whitelisted). */
+        .p_whitelist = &whitelist, /**< Pointer to whitelist, NULL if none is given. */
+        .interval    = scanningParams.getInterval(),  /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        .window      = scanningParams.getWindow(),    /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        .timeout     = scanningParams.getTimeout(),   /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+    };
+
+    if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::stopScan(void) {
+    if (sd_ble_gap_scan_stop() == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    }
+
+    return BLE_STACK_BUSY;
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief  Stops the BLE HW and disconnects from any devices
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::stopAdvertising(void)
+{
+    /* Stop Advertising */
+    ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    state.advertising = 0;
+
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::connect(const Address_t             peerAddr,
+                              BLEProtocol::AddressType_t  peerAddrType,
+                              const ConnectionParams_t   *connectionParams,
+                              const GapScanningParams    *scanParamsIn)
+{
+    ble_gap_addr_t addr;
+    addr.addr_type = peerAddrType;
+    memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
+
+    ble_gap_conn_params_t connParams;
+    if (connectionParams != NULL) {
+        connParams.min_conn_interval = connectionParams->minConnectionInterval;
+        connParams.max_conn_interval = connectionParams->maxConnectionInterval;
+        connParams.slave_latency     = connectionParams->slaveLatency;
+        connParams.conn_sup_timeout  = connectionParams->connectionSupervisionTimeout;
+    } else {
+        connParams.min_conn_interval = 50;
+        connParams.max_conn_interval = 100;
+        connParams.slave_latency     = 0;
+        connParams.conn_sup_timeout  = 600;
+    }
+
+    /* Allocate the stack's whitelist statically */
+    ble_gap_whitelist_t  whitelist;
+    ble_gap_addr_t      *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
+    ble_gap_irk_t       *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
+    /* Initialize the whitelist */
+    whitelist.pp_addrs   = whitelistAddressPtrs;
+    whitelist.pp_irks    = whitelistIrkPtrs;
+    whitelist.addr_count = 0;
+    whitelist.irk_count  = 0;
+
+    /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
+    if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
+        ble_error_t error = generateStackWhitelist(whitelist);
+        if (error != BLE_ERROR_NONE) {
+            return error;
+        }
+    }
+
+    ble_gap_scan_params_t scanParams;
+    scanParams.selective   = scanningPolicyMode;    /**< If 1, ignore unknown devices (non whitelisted). */
+    scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
+    if (scanParamsIn != NULL) {
+        scanParams.active      = scanParamsIn->getActiveScanning();   /**< If 1, perform active scanning (scan requests). */
+        scanParams.interval    = scanParamsIn->getInterval();         /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        scanParams.window      = scanParamsIn->getWindow();           /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        scanParams.timeout     = scanParamsIn->getTimeout();          /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+    } else {
+        scanParams.active      = _scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
+        scanParams.interval    = _scanningParams.getInterval();       /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        scanParams.window      = _scanningParams.getWindow();         /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+        scanParams.timeout     = _scanningParams.getTimeout();        /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+    }
+
+    uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams);
+    if (rc == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    }
+    switch (rc) {
+        case NRF_ERROR_INVALID_ADDR:
+            return BLE_ERROR_INVALID_PARAM;
+        case NRF_ERROR_INVALID_PARAM:
+            return BLE_ERROR_INVALID_PARAM;
+        case NRF_ERROR_INVALID_STATE:
+            return BLE_ERROR_INVALID_STATE;
+        case BLE_ERROR_GAP_INVALID_BLE_ADDR:
+            return BLE_ERROR_INVALID_PARAM;
+        case NRF_ERROR_NO_MEM:
+            return BLE_ERROR_NO_MEM;
+        case NRF_ERROR_BUSY:
+            return BLE_STACK_BUSY;
+        default:
+        case BLE_ERROR_GAP_WHITELIST_IN_USE:
+            return BLE_ERROR_UNSPECIFIED;
+    }
+}
+
+ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
+{
+    state.advertising = 0;
+    state.connected   = 0;
+
+    uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
+    switch (reason) {
+        case REMOTE_USER_TERMINATED_CONNECTION:
+            code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
+            break;
+        case CONN_INTERVAL_UNACCEPTABLE:
+            code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE;
+            break;
+        default:
+            break;
+    }
+
+    /* Disconnect if we are connected to a central device */
+    ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    return BLE_ERROR_NONE;
+}
+
+/*!
+    @brief  Disconnects if we are connected to a central device
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+ble_error_t nRF5xGap::disconnect(DisconnectionReason_t reason)
+{
+    return disconnect(m_connectionHandle, reason);
+}
+
+ble_error_t nRF5xGap::getPreferredConnectionParams(ConnectionParams_t *params)
+{
+    ASSERT_INT(NRF_SUCCESS,
+        sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)),
+        BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::setPreferredConnectionParams(const ConnectionParams_t *params)
+{
+    ASSERT_INT(NRF_SUCCESS,
+        sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)),
+        BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
+{
+    uint32_t rc;
+
+    rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams)));
+    if (rc == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear nRF5xGap's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::reset(void)
+{
+    /* Clear all state that is from the parent, including private members */
+    if (Gap::reset() != BLE_ERROR_NONE) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    /* Clear derived class members */
+    m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+
+    /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+    advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+    scanningPolicyMode    = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+    /* Clear the internal whitelist */
+    whitelistAddressesSize = 0;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the 16-bit connection handle
+*/
+/**************************************************************************/
+void nRF5xGap::setConnectionHandle(uint16_t con_handle)
+{
+    m_connectionHandle = con_handle;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the 16-bit connection handle
+*/
+/**************************************************************************/
+uint16_t nRF5xGap::getConnectionHandle(void)
+{
+    return m_connectionHandle;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sets the BLE device address
+
+    @returns    ble_error_t
+
+    @section EXAMPLE
+
+    @code
+
+    uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
+    nrf.getGap().setAddress(Gap::BLEProtocol::AddressType::RANDOM_STATIC, device_address);
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
+{
+    uint8_t cycle_mode;
+    ble_gap_addr_t dev_addr;
+
+    /* When using Public or Static addresses, the cycle mode must be None.
+       When using Random Private addresses, the cycle mode must be Auto.
+       In auto mode, the given address is ignored.
+    */
+    if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC))
+    {
+        cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
+        memcpy(dev_addr.addr, address, ADDR_LEN);
+    }
+    else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE))
+    {
+        cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO;
+        // address is ignored when in auto mode
+    }
+    else
+    {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    dev_addr.addr_type = type;
+    ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
+{
+    ble_gap_addr_t dev_addr;
+    if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    if (typeP != NULL) {
+        *typeP = static_cast<AddressType_t>(dev_addr.addr_type);
+    }
+    if (address != NULL) {
+        memcpy(address, dev_addr.addr, ADDR_LEN);
+    }
+    return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::setDeviceName(const uint8_t *deviceName)
+{
+    ble_gap_conn_sec_mode_t sec_mode;
+    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
+
+    if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+ble_error_t nRF5xGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
+{
+    if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance)
+{
+    if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+ble_error_t nRF5xGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
+{
+    if ((sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP)) == NRF_SUCCESS)) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+/* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
+ble_error_t nRF5xGap::setTxPower(int8_t txPower)
+{
+    unsigned rc;
+    if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) {
+        switch (rc) {
+            case NRF_ERROR_BUSY:
+                return BLE_STACK_BUSY;
+            case NRF_ERROR_INVALID_PARAM:
+            default:
+                return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
+{
+    static const int8_t permittedTxValues[] = {
+        -40, -30, -20, -16, -12, -8, -4, 0, 4
+    };
+
+    *valueArrayPP = permittedTxValues;
+    *countP = sizeof(permittedTxValues) / sizeof(int8_t);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the capacity of the internal whitelist maintained by this
+            implementation.
+
+    @returns    The capacity of the internal whitelist.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+uint8_t nRF5xGap::getMaxWhitelistSize(void) const
+{
+    return YOTTA_CFG_WHITELIST_MAX_SIZE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get a copy of the implementation's internal whitelist.
+
+    @param[out] whitelistOut
+                A \ref Gap::Whitelist_t structure containing a copy of the
+                addresses in the implemenetation's internal whitelist.
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
+{
+    uint8_t i;
+    for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
+        memcpy(&whitelistOut.addresses[i], &whitelistAddresses[i], sizeof(BLEProtocol::Address_t));
+    }
+    whitelistOut.size = i;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the whitelist that will be used in the next call to
+            startAdvertising().
+
+    @param[in]  whitelistIn
+                A reference to a \ref Gap::Whitelist_t structure
+                representing a whitelist containing all the white listed
+                BLE addresses.
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_INVALID_PARAM
+                The supplied whitelist contains a private non-resolvable
+                address
+
+                BLE_ERROR_PARAM_OUT_OF_RANGE
+                The size of the supplied whitelist exceeds the maximum
+                capacity of the implementation's internal whitelist.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
+{
+    if (whitelistIn.size > getMaxWhitelistSize()) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /* Test for invalid parameters before we change the internal state */
+    for (uint8_t i = 0; i < whitelistIn.size; ++i) {
+        if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
+            /* This is not allowed because it is completely meaningless */
+            return BLE_ERROR_INVALID_PARAM;
+        }
+    }
+
+    whitelistAddressesSize = 0;
+    for (uint8_t i = 0; i < whitelistIn.size; ++i) {
+        memcpy(&whitelistAddresses[whitelistAddressesSize], &whitelistIn.addresses[i], sizeof(BLEProtocol::Address_t));
+        whitelistAddressesSize++;
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the advertising policy filter mode that will be used in
+            the next call to startAdvertising().
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_NOT_IMPLEMENTED
+                This feature is currently note implemented.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
+{
+    advertisingPolicyMode = mode;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the scanning policy filter mode that will be used in
+            the next call to startAdvertising().
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_NOT_IMPLEMENTED
+                This feature is currently note implemented.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
+{
+    scanningPolicyMode = mode;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the initiator policy filter mode that will be used in
+            the next call to startAdvertising()
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_NOT_IMPLEMENTED
+                This feature is currently note implemented.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setInitiatorPolicyMode(Gap::InitiatorPolicyMode_t mode)
+{
+    return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the current advertising policy filter mode.
+
+    @returns    The advertising policy filter mode.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+Gap::AdvertisingPolicyMode_t nRF5xGap::getAdvertisingPolicyMode(void) const
+{
+    return advertisingPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the current scanning policy filter mode.
+
+    @returns    The scanning policy filter mode.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+Gap::ScanningPolicyMode_t nRF5xGap::getScanningPolicyMode(void) const
+{
+    return scanningPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the current initiator policy filter mode.
+
+    @returns    The initiator policy filter mode.
+
+    @note   Currently initiator filtering using the whitelist is not
+            implemented in this module.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const
+{
+    return Gap::INIT_POLICY_IGNORE_WHITELIST;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Helper function used to populate the ble_gap_whitelist_t that
+            will be used by the SoftDevice for filtering requests.
+
+    @returns    \ref ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @retval     BLE_ERROR_INVALID_STATE
+                The internal stack was not initialized correctly.
+
+    @note  Both the SecurityManager and Gap must initialize correctly for
+           this function to succeed.
+
+    @note  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.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
+{
+    ble_gap_whitelist_t  whitelistFromBondTable;
+    ble_gap_addr_t      *addressPtr[1];
+    ble_gap_irk_t       *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
+
+    nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager();
+
+    if (securityManager.hasInitialized()) {
+        /* We do not care about the addresses, set the count to 0 */
+        whitelistFromBondTable.addr_count = 0;
+        /* The Nordic SDK will return a failure if we set pp_addr to NULL */
+        whitelistFromBondTable.pp_addrs   = addressPtr;
+        /* We want all the IRKs we can get because we do not know which ones match the addresses */
+        whitelistFromBondTable.irk_count  = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
+        whitelistFromBondTable.pp_irks    = irkPtr;
+
+        /* Use the security manager to get the IRKs from the bond table */
+        ble_error_t error = securityManager.createWhitelistFromBondTable(whitelistFromBondTable);
+        if (error != BLE_ERROR_NONE) {
+            return error;
+        }
+    } else  {
+        /**
+         * If there is no security manager then we cannot access the bond table,
+         * so disable IRK matching
+         */
+        whitelistFromBondTable.addr_count = 0;
+        whitelistFromBondTable.irk_count  = 0;
+    }
+
+    /**
+     * For every private resolvable address in the local whitelist check if
+     * there is an IRK for said address in the bond table and add it to the
+     * local IRK list.
+     */
+    whitelist.irk_count  = 0;
+    whitelist.addr_count = 0;
+    for (uint8_t i = 0; i < whitelistAddressesSize; ++i) {
+        if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) {
+            /* Test if there is a matching IRK for this private resolvable address */
+            for (uint8_t j = 0; j < whitelistFromBondTable.irk_count; ++j) {
+                if (securityManager.matchAddressAndIrk(&whitelistAddresses[i], whitelistFromBondTable.pp_irks[j])) {
+                    /* Found the corresponding IRK, add it to our local whitelist */
+                    whitelist.pp_irks[whitelist.irk_count] = whitelistFromBondTable.pp_irks[j];
+                    whitelist.irk_count++;
+                    /* Make sure we do not look at this IRK again */
+                    if (j != whitelistFromBondTable.irk_count - 1) {
+                        /**
+                         * This is not the last IRK, so replace the pointer
+                         * with the last pointer in the array
+                         */
+                        whitelistFromBondTable.pp_irks[j] =
+                            whitelistFromBondTable.pp_irks[whitelistFromBondTable.irk_count - 1];
+                    }
+                    /**
+                     * If the IRK is the last pointer in the array simply
+                     * decrement the total IRK count
+                     */
+                    whitelistFromBondTable.irk_count--;
+                    break;
+                }
+            }
+        } else {
+            /* Include the address into the whitelist */
+            whitelist.pp_addrs[whitelist.addr_count] = &whitelistAddresses[i];
+            whitelist.addr_count++;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGap.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,246 @@
+/* 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
+    #define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
+#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 "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 "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 {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);}
+    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(NRF_APP_PRIORITY_HIGH, 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];
+
+    /*
+     * 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);
+
+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(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__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGattClient.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,50 @@
+/* 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 "nRF5xGattClient.h"
+
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+ble_error_t
+nRF5xGattClient::launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                        ServiceDiscovery::ServiceCallback_t         sc,
+                                        ServiceDiscovery::CharacteristicCallback_t  cc,
+                                        const UUID                                 &matchingServiceUUIDIn,
+                                        const UUID                                 &matchingCharacteristicUUIDIn)
+{
+    return _discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn);
+}
+
+ble_error_t nRF5xGattClient::discoverCharacteristicDescriptors(
+    const DiscoveredCharacteristic& characteristic,
+    const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+    const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback)
+{
+    return _characteristicDescriptorDiscoverer.launch(
+        characteristic, 
+        discoveryCallback, 
+        terminationCallback
+    );
+}
+
+bool nRF5xGattClient::isCharacteristicDescriptorsDiscoveryActive(const DiscoveredCharacteristic& characteristic) const {
+    return _characteristicDescriptorDiscoverer.isActive(characteristic);   
+}
+
+void nRF5xGattClient::terminateCharacteristicDescriptorsDiscovery(const DiscoveredCharacteristic& characteristic) { 
+    return _characteristicDescriptorDiscoverer.requestTerminate(characteristic);
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGattClient.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,218 @@
+/* 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_CLIENT_H__
+#define __NRF51822_GATT_CLIENT_H__
+
+#include "ble/GattClient.h"
+#include "nRF5xServiceDiscovery.h"
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+
+class nRF5xGattClient : public GattClient
+{
+public:
+    /**
+     * When using S110, all Gatt client features will return
+     * BLE_ERROR_NOT_IMPLEMENTED
+     */
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+
+    /**
+     * Launch service discovery. Once launched, service discovery will remain
+     * active with callbacks being issued back into the application for matching
+     * services/characteristics. isActive() can be used to determine status; and
+     * a termination callback (if setup) will be invoked at the end. Service
+     * discovery can be terminated prematurely if needed using terminate().
+     *
+     * @param  connectionHandle
+     *           Handle for the connection with the peer.
+     * @param  sc
+     *           This is the application callback for matching service. Taken as
+     *           NULL by default. Note: service discovery may still be active
+     *           when this callback is issued; calling asynchronous BLE-stack
+     *           APIs from within this application callback might cause the
+     *           stack to abort service discovery. If this becomes an issue, it
+     *           may be better to make local copy of the discoveredService and
+     *           wait for service discovery to terminate before operating on the
+     *           service.
+     * @param  cc
+     *           This is the application callback for matching characteristic.
+     *           Taken as NULL by default. Note: service discovery may still be
+     *           active when this callback is issued; calling asynchronous
+     *           BLE-stack APIs from within this application callback might cause
+     *           the stack to abort service discovery. If this becomes an issue,
+     *           it may be better to make local copy of the discoveredCharacteristic
+     *           and wait for service discovery to terminate before operating on the
+     *           characteristic.
+     * @param  matchingServiceUUID
+     *           UUID based filter for specifying a service in which the application is
+     *           interested. By default it is set as the wildcard UUID_UNKNOWN,
+     *           in which case it matches all services. If characteristic-UUID
+     *           filter (below) is set to the wildcard value, then a service
+     *           callback will be invoked for the matching service (or for every
+     *           service if the service filter is a wildcard).
+     * @param  matchingCharacteristicUUIDIn
+     *           UUID based filter for specifying characteristic in which the application
+     *           is interested. By default it is set as the wildcard UUID_UKNOWN
+     *           to match against any characteristic. If both service-UUID
+     *           filter and characteristic-UUID filter are used with non- wildcard
+     *           values, then only a single characteristic callback is
+     *           invoked for the matching characteristic.
+     *
+     * @Note     Using wildcard values for both service-UUID and characteristic-
+     *           UUID will result in complete service discovery--callbacks being
+     *           called for every service and characteristic.
+     *
+     * @return
+     *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+     */
+    virtual ble_error_t launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                               ServiceDiscovery::ServiceCallback_t         sc = NULL,
+                                               ServiceDiscovery::CharacteristicCallback_t  cc = NULL,
+                                               const UUID                                 &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+                                               const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+    virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+        _discovery.onTermination(callback);
+    }
+
+    /**
+     * Is service-discovery currently active?
+     */
+    virtual bool isServiceDiscoveryActive(void) const {
+        return _discovery.isActive();
+    }
+
+    /**
+     * Terminate an ongoing service-discovery. This should result in an
+     * invocation of the TerminationCallback if service-discovery is active.
+     */
+    virtual void terminateServiceDiscovery(void) {
+        _discovery.terminate();
+    }
+
+    /**
+     * @brief Implementation of GattClient::discoverCharacteristicDescriptors
+     * @see GattClient::discoverCharacteristicDescriptors
+     */
+    virtual ble_error_t discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
+    );
+
+    /**
+     * @brief Implementation of GattClient::isCharacteristicDiscoveryActive
+     * @see GattClient::isCharacteristicDiscoveryActive
+     */
+    virtual bool isCharacteristicDescriptorsDiscoveryActive(const DiscoveredCharacteristic& characteristic) const;
+
+    /**
+     * @brief Implementation of GattClient::terminateCharacteristicDiscovery
+     * @see GattClient::terminateCharacteristicDiscovery
+     */
+    virtual void terminateCharacteristicDescriptorsDiscovery(const DiscoveredCharacteristic& characteristic);
+
+    virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const {
+        uint32_t rc = sd_ble_gattc_read(connHandle, attributeHandle, offset);
+        if (rc == NRF_SUCCESS) {
+            return BLE_ERROR_NONE;
+        }
+        switch (rc) {
+            case NRF_ERROR_BUSY:
+                return BLE_STACK_BUSY;
+            case BLE_ERROR_INVALID_CONN_HANDLE:
+            case NRF_ERROR_INVALID_STATE:
+            case NRF_ERROR_INVALID_ADDR:
+            default:
+                return BLE_ERROR_INVALID_STATE;
+        }
+    }
+
+    virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const {
+        ble_gattc_write_params_t writeParams;
+        writeParams.write_op = cmd;
+        writeParams.flags    = 0; /* this is inconsequential */
+        writeParams.handle   = attributeHandle;
+        writeParams.offset   = 0;
+        writeParams.len      = length;
+        writeParams.p_value  = const_cast<uint8_t *>(value);
+
+        uint32_t rc = sd_ble_gattc_write(connHandle, &writeParams);
+        if (rc == NRF_SUCCESS) {
+            return BLE_ERROR_NONE;
+        }
+        switch (rc) {
+            case NRF_ERROR_BUSY:
+                return BLE_STACK_BUSY;
+            case BLE_ERROR_NO_TX_BUFFERS:
+                return BLE_ERROR_NO_MEM;
+            case BLE_ERROR_INVALID_CONN_HANDLE:
+            case NRF_ERROR_INVALID_STATE:
+            case NRF_ERROR_INVALID_ADDR:
+            default:
+                return BLE_ERROR_INVALID_STATE;
+        }
+    }
+
+    /**
+     * @brief  Clear nRF5xGattClient's state.
+     *
+     * @return
+     *           BLE_ERROR_NONE if successful.
+     */
+    virtual ble_error_t reset(void) {
+        /* Clear all state that is from the parent, including private members */
+        if (GattClient::reset() != BLE_ERROR_NONE) {
+            return BLE_ERROR_INVALID_STATE;
+        }
+
+        /* Clear derived class members */
+        _discovery.reset();
+
+        return BLE_ERROR_NONE;
+    }
+
+public:
+    /*
+     * Allow instantiation from nRF5xn when required.
+     */
+    friend class nRF5xn;
+
+    nRF5xGattClient() : _discovery(this) {
+        /* empty */
+    }
+
+    nRF5xServiceDiscovery& discovery() {
+        return _discovery;
+    }
+
+    nRF5xCharacteristicDescriptorDiscoverer& characteristicDescriptorDiscoverer() {
+        return _characteristicDescriptorDiscoverer;
+    }
+
+private:
+    nRF5xGattClient(const nRF5xGattClient &);
+    const nRF5xGattClient& operator=(const nRF5xGattClient &);
+
+private:
+    nRF5xServiceDiscovery _discovery;
+    nRF5xCharacteristicDescriptorDiscoverer _characteristicDescriptorDiscoverer;
+
+#endif // if !S110
+};
+
+#endif // ifndef __NRF51822_GATT_CLIENT_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGattServer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,549 @@
+/* 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"
+
+/**************************************************************************/
+/*!
+    @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( 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);
+
+        /* 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 descriptor is a special case which needs to be
+         * handled at the time of adding the characteristic. The following block
+         * is meant to discover its presence. */
+        const uint8_t *userDescriptionDescriptorValuePtr = NULL;
+        uint16_t userDescriptionDescriptorValueLen = 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) {
+                userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
+                userDescriptionDescriptorValueLen = p_desc->getLength();
+            }
+        }
+
+        ASSERT ( 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,
+                                              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);
+        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-descriptor here; this has already been handled when adding the characteristic (above). */
+            if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
+                continue;
+            }
+
+            nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
+
+            ASSERT(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]);
+        }
+    }
+
+    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( 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();
+        }
+        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 = BLE_ERROR_INVALID_STATE; // if assert is not used
+        ASSERT_INT( ERROR_NONE,
+                    sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
+                    BLE_ERROR_PARAM_OUT_OF_RANGE );
+    }
+
+    return returnValue;
+}
+
+/**
+ * Perform an explicit BLE notification of a given attribute.
+ *
+ * @param[in] attributeHandle
+ *              Handle for the value attribute of the Characteristic.
+ * @param[in] value
+ *              A pointer to a buffer holding the new value
+ * @param[in] size
+ *              Size of the new value (in bytes).
+ *
+ * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
+ */
+ble_error_t nRF5xGattServer::notify(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len)
+{
+    uint16_t gapConnectionHandle = ((nRF5xGap &)nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap()).getConnectionHandle();
+    ble_gatts_hvx_params_t hvx_params;
+
+    hvx_params.handle = attributeHandle;
+    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    hvx_params.offset = 0;
+    hvx_params.p_data = const_cast<uint8_t *>(buffer);
+    hvx_params.p_len  = &len;
+
+    error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);
+
+    if (error == ERROR_NONE)  
+	    return BLE_ERROR_NONE;
+    else
+	    return BLE_STACK_BUSY;
+}
+
+
+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)
+{
+    int characteristicIndex = resolveValueHandleToCharIndex(characteristic.getValueHandle());
+    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;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback handler for events getting pushed up from the SD
+*/
+/**************************************************************************/
+void nRF5xGattServer::hwCallback(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;
+
+        case BLE_EVT_TX_COMPLETE: {
+            handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
+            return;
+        }
+
+        case BLE_GATTS_EVT_SYS_ATTR_MISSING: 
+        case BLE_GAP_EVT_CONN_SEC_UPDATE:
+        {
+            GattSysAttrMissingCallbackParams cbParams = {gattsEventP->conn_handle};
+            handleSysAttrMissingEvent(&cbParams);
+            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;
+
+        default:
+            return;
+    }
+
+    int characteristicIndex = resolveValueHandleToCharIndex(handle_value);
+    if (characteristicIndex == -1) {
+        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: {
+            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)
+                    }
+                }
+            };
+            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;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xGattServer.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,104 @@
+/* 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 "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 notify(GattAttribute::Handle_t, const uint8_t[], uint16_t);
+    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(ble_evt_t *p_ble_evt);
+
+
+private:
+    const static unsigned BLE_TOTAL_CHARACTERISTICS = 30;
+    const static unsigned BLE_TOTAL_DESCRIPTORS     = 20;
+
+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;
+    }
+
+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];
+
+    /*
+     * Allow instantiation from nRF5xn when required.
+     */
+    friend class nRF5xn;
+
+    nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() {
+        /* empty */
+    }
+
+private:
+    nRF5xGattServer(const nRF5xGattServer &);
+    const nRF5xGattServer& operator=(const nRF5xGattServer &);
+};
+
+#endif // ifndef __NRF51822_GATT_SERVER_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xSecurityManager.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,177 @@
+/* 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();
+    }
+
+    /**
+     * @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;
+            addresses.bonds = 0;
+            return error;
+        }
+
+        addresses.bonds = whitelistFromBondTable.irk_count;
+
+        /* 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;
+    }
+
+    /**
+     * @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 &);
+
+    /*
+     * 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);
+    }
+
+    /*
+     * 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__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xServiceDiscovery.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,310 @@
+/* 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 "nRF5xServiceDiscovery.h"
+
+ble_error_t
+nRF5xServiceDiscovery::launchCharacteristicDiscovery(Gap::Handle_t connectionHandle,
+                                                     Gap::Handle_t startHandle,
+                                                     Gap::Handle_t endHandle)
+{
+    characteristicDiscoveryStarted(connectionHandle);
+
+    ble_gattc_handle_range_t handleRange = {
+        .start_handle = startHandle,
+        .end_handle   = endHandle
+    };
+    uint32_t rc = sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange);
+    ble_error_t err = BLE_ERROR_NONE;
+
+    switch (rc) {
+        case NRF_SUCCESS:
+            err = BLE_ERROR_NONE;
+            break;
+        case BLE_ERROR_INVALID_CONN_HANDLE:
+        case NRF_ERROR_INVALID_ADDR:
+            err = BLE_ERROR_INVALID_PARAM;
+            break;
+        case NRF_ERROR_BUSY:
+            err = BLE_STACK_BUSY;
+            break;
+        case NRF_ERROR_INVALID_STATE:
+            err = BLE_ERROR_INVALID_STATE;
+            break;
+        default:
+            err = BLE_ERROR_UNSPECIFIED;
+            break;
+    }
+
+    if (err) {
+        terminateCharacteristicDiscovery(err);
+    }
+    return err;
+}
+
+void
+nRF5xServiceDiscovery::setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response)
+{
+    serviceIndex = 0;
+    numServices  = response->count;
+
+    /* Account for the limitation on the number of discovered services we can handle at a time. */
+    if (numServices > BLE_DB_DISCOVERY_MAX_SRV) {
+        numServices = BLE_DB_DISCOVERY_MAX_SRV;
+    }
+
+    serviceUUIDDiscoveryQueue.reset();
+    for (unsigned serviceIndex = 0; serviceIndex < numServices; serviceIndex++) {
+        if (response->services[serviceIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
+            serviceUUIDDiscoveryQueue.enqueue(serviceIndex);
+            services[serviceIndex].setup(response->services[serviceIndex].handle_range.start_handle,
+                                         response->services[serviceIndex].handle_range.end_handle);
+        } else {
+            services[serviceIndex].setup(response->services[serviceIndex].uuid.uuid,
+                                         response->services[serviceIndex].handle_range.start_handle,
+                                         response->services[serviceIndex].handle_range.end_handle);
+        }
+    }
+
+    /* Trigger discovery of service UUID if necessary. */
+    if (serviceUUIDDiscoveryQueue.getCount()) {
+        serviceUUIDDiscoveryQueue.triggerFirst();
+    }
+}
+
+void
+nRF5xServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response)
+{
+    numCharacteristics  = response->count;
+
+    /* Account for the limitation on the number of discovered characteristics we can handle at a time. */
+    if (numCharacteristics > BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV) {
+        numCharacteristics = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
+    }
+
+    charUUIDDiscoveryQueue.reset();
+    for (unsigned charIndex = 0; charIndex < numCharacteristics; charIndex++) {
+        if (response->chars[charIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
+            charUUIDDiscoveryQueue.enqueue(charIndex);
+            characteristics[charIndex].setup(gattc,
+                                             connHandle,
+                                             response->chars[charIndex].char_props,
+                                             response->chars[charIndex].handle_decl,
+                                             response->chars[charIndex].handle_value);
+        } else {
+            characteristics[charIndex].setup(gattc,
+                                             connHandle,
+                                             response->chars[charIndex].uuid.uuid,
+                                             response->chars[charIndex].char_props,
+                                             response->chars[charIndex].handle_decl,
+                                             response->chars[charIndex].handle_value);
+        }
+    }
+
+    /* Trigger discovery of char UUID if necessary. */
+    if (charUUIDDiscoveryQueue.getCount()) {
+        charUUIDDiscoveryQueue.triggerFirst();
+    }
+}
+
+void
+nRF5xServiceDiscovery::progressCharacteristicDiscovery(void)
+{
+    if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
+        return;
+    }
+
+    if ((discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) && (numCharacteristics > 0)) {
+        discoveredCharacteristic.setLastHandle(characteristics[0].getDeclHandle() - 1);
+
+        if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+            ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) &&
+             (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
+            if (characteristicCallback) {
+                characteristicCallback(&discoveredCharacteristic);
+            }
+        }
+    }
+
+    for (uint8_t i = 0; i < numCharacteristics; ++i) {
+        if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
+            return;
+        }
+
+        if (i == (numCharacteristics - 1)) {
+            discoveredCharacteristic = characteristics[i];
+            break;
+        } else {
+            characteristics[i].setLastHandle(characteristics[i + 1].getDeclHandle() - 1);
+        }
+
+        if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+            ((matchingCharacteristicUUID == characteristics[i].getUUID()) &&
+             (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
+            if (characteristicCallback) {
+                characteristicCallback(&characteristics[i]);
+            }
+        }
+    }
+
+    if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) {
+        return;
+    }
+
+    Gap::Handle_t startHandle = (numCharacteristics > 0) ? characteristics[numCharacteristics - 1].getValueHandle() + 1 : SRV_DISC_END_HANDLE;
+    Gap::Handle_t endHandle   = services[serviceIndex].getEndHandle();
+    resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */
+
+    if (startHandle < endHandle) {
+        ble_gattc_handle_range_t handleRange = {
+            .start_handle = startHandle,
+            .end_handle   = endHandle
+        };
+        if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) {
+            terminateCharacteristicDiscovery(BLE_ERROR_UNSPECIFIED);
+        }
+    } else {
+        terminateCharacteristicDiscovery(BLE_ERROR_NONE);
+    }
+}
+
+void
+nRF5xServiceDiscovery::progressServiceDiscovery(void)
+{
+    /* Iterate through the previously discovered services cached in services[]. */
+    while ((state == SERVICE_DISCOVERY_ACTIVE) && (serviceIndex < numServices)) {
+        if ((matchingServiceUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+            (matchingServiceUUID == services[serviceIndex].getUUID())) {
+
+            if (serviceCallback && (matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN))) {
+                serviceCallback(&services[serviceIndex]);
+            }
+
+            if ((state == SERVICE_DISCOVERY_ACTIVE) && characteristicCallback) {
+                launchCharacteristicDiscovery(connHandle, services[serviceIndex].getStartHandle(), services[serviceIndex].getEndHandle());
+            } else {
+                serviceIndex++;
+            }
+        } else {
+            serviceIndex++;
+        }
+    }
+
+    /* Relaunch discovery of new services beyond the last entry cached in services[]. */
+    if ((state == SERVICE_DISCOVERY_ACTIVE) && (numServices > 0) && (serviceIndex > 0)) {
+        /* Determine the ending handle of the last cached service. */
+        Gap::Handle_t endHandle = services[serviceIndex - 1].getEndHandle();
+        resetDiscoveredServices(); /* Note: resetDiscoveredServices() must come after fetching endHandle. */
+
+        if (endHandle == SRV_DISC_END_HANDLE) {
+            terminateServiceDiscovery();
+        } else {
+            if (sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL) != NRF_SUCCESS) {
+                terminateServiceDiscovery();
+            }
+        }
+    }
+}
+
+void
+nRF5xServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
+{
+    while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
+        parentDiscoveryObject->state = DISCOVER_SERVICE_UUIDS;
+
+        unsigned serviceIndex = getFirst();
+        ble_uuid_t uuid = {
+            .uuid = BLE_UUID_SERVICE_PRIMARY,
+            .type = BLE_UUID_TYPE_BLE,
+        };
+        ble_gattc_handle_range_t handleRange = {
+            .start_handle = parentDiscoveryObject->services[serviceIndex].getStartHandle(),
+            .end_handle   = parentDiscoveryObject->services[serviceIndex].getEndHandle(),
+        };
+        if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
+            return;
+        }
+
+        /* Skip this service if we fail to launch a read for its service-declaration
+         * attribute. Its UUID will remain INVALID, and it may not match any filters. */
+        dequeue();
+    }
+
+    /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
+    if (parentDiscoveryObject->state == DISCOVER_SERVICE_UUIDS) {
+        parentDiscoveryObject->state = SERVICE_DISCOVERY_ACTIVE;
+    }
+}
+
+void
+nRF5xServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
+{
+    while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
+        parentDiscoveryObject->state = DISCOVER_CHARACTERISTIC_UUIDS;
+
+        unsigned charIndex = getFirst();
+        ble_uuid_t uuid = {
+            .uuid = BLE_UUID_CHARACTERISTIC,
+            .type = BLE_UUID_TYPE_BLE,
+        };
+        ble_gattc_handle_range_t handleRange = { };
+        handleRange.start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle();
+        handleRange.end_handle   = parentDiscoveryObject->characteristics[charIndex].getDeclHandle() + 1;
+        if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
+            return;
+        }
+
+        /* Skip this service if we fail to launch a read for its service-declaration
+         * attribute. Its UUID will remain INVALID, and it may not match any filters. */
+        dequeue();
+    }
+
+    /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
+    if (parentDiscoveryObject->state == DISCOVER_CHARACTERISTIC_UUIDS) {
+        parentDiscoveryObject->state = CHARACTERISTIC_DISCOVERY_ACTIVE;
+    }
+}
+
+void
+nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
+{
+    if (state == DISCOVER_SERVICE_UUIDS) {
+        if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
+            UUID::LongUUIDBytes_t uuid;
+            memcpy(uuid, response->handle_value[0].p_value, UUID::LENGTH_OF_LONG_UUID);
+
+            unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
+            services[serviceIndex].setupLongUUID(uuid, UUID::LSB);
+
+            serviceUUIDDiscoveryQueue.triggerFirst();
+        } else {
+            serviceUUIDDiscoveryQueue.dequeue();
+        }
+    } else if (state == DISCOVER_CHARACTERISTIC_UUIDS) {
+        if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
+            UUID::LongUUIDBytes_t uuid;
+
+            memcpy(uuid, &(response->handle_value[0].p_value[3]), UUID::LENGTH_OF_LONG_UUID);
+
+            unsigned charIndex = charUUIDDiscoveryQueue.dequeue();
+            characteristics[charIndex].setupLongUUID(uuid, UUID::LSB);
+
+            charUUIDDiscoveryQueue.triggerFirst();
+        } else {
+            charUUIDDiscoveryQueue.dequeue();
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xServiceDiscovery.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,366 @@
+/* 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 __NRF_SERVICE_DISCOVERY_H__
+#define __NRF_SERVICE_DISCOVERY_H__
+
+#include "ble/ServiceDiscovery.h"
+#include "ble/DiscoveredService.h"
+#include "nRF5xDiscoveredCharacteristic.h"
+
+#include "ble.h"
+#include "ble_gattc.h"
+
+class nRF5xGattClient; /* forward declaration */
+
+class nRF5xServiceDiscovery : public ServiceDiscovery
+{
+public:
+    static const uint16_t SRV_DISC_START_HANDLE             = 0x0001; /**< The start handle value used during service discovery. */
+    static const uint16_t SRV_DISC_END_HANDLE               = 0xFFFF; /**< The end handle value used during service discovery. */
+
+public:
+    static const unsigned BLE_DB_DISCOVERY_MAX_SRV          = 4;      /**< Maximum number of services we can retain information for after a single discovery. */
+    static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4;      /**< Maximum number of characteristics per service we can retain information for. */
+
+public:
+    nRF5xServiceDiscovery(nRF5xGattClient *gattcIn) :
+        gattc(gattcIn),
+        serviceIndex(0),
+        numServices(0),
+        numCharacteristics(0),
+        state(INACTIVE),
+        services(),
+        characteristics(),
+        serviceUUIDDiscoveryQueue(this),
+        charUUIDDiscoveryQueue(this),
+        onTerminationCallback(NULL) {
+        /* empty */
+    }
+
+    virtual ble_error_t launch(Gap::Handle_t                               connectionHandle,
+                               ServiceDiscovery::ServiceCallback_t         sc,
+                               ServiceDiscovery::CharacteristicCallback_t  cc,
+                               const UUID                                 &matchingServiceUUIDIn,
+                               const UUID                                 &matchingCharacteristicUUIDIn)
+    {
+        if (isActive()) {
+            return BLE_ERROR_INVALID_STATE;
+        }
+
+        serviceCallback            = sc;
+        characteristicCallback     = cc;
+        matchingServiceUUID        = matchingServiceUUIDIn;
+        matchingCharacteristicUUID = matchingCharacteristicUUIDIn;
+
+        serviceDiscoveryStarted(connectionHandle);
+
+        uint32_t rc;
+        if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) {
+            terminate();
+            switch (rc) {
+                case NRF_ERROR_INVALID_PARAM:
+                case BLE_ERROR_INVALID_CONN_HANDLE:
+                    return BLE_ERROR_INVALID_PARAM;
+                case NRF_ERROR_BUSY:
+                    return BLE_STACK_BUSY;
+                default:
+                case NRF_ERROR_INVALID_STATE:
+                    return BLE_ERROR_INVALID_STATE;
+            }
+        }
+
+        return BLE_ERROR_NONE;
+    }
+
+    virtual bool isActive(void) const {
+        return state != INACTIVE;
+    }
+
+    virtual void terminate(void) {
+        terminateServiceDiscovery();
+    }
+
+    void terminate(Gap::Handle_t connectionHandle) {
+        if(connHandle == connectionHandle) {
+            terminate();
+        }
+    }
+
+    virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) {
+        onTerminationCallback = callback;
+    }
+
+    /**
+     * @brief  Clear nRF5xServiceDiscovery's state.
+     *
+     * @return
+     *           BLE_ERROR_NONE if successful.
+     */
+    virtual ble_error_t reset(void) {
+        /* Clear all state that is from the parent, including private members */
+        if (ServiceDiscovery::reset() != BLE_ERROR_NONE) {
+            return BLE_ERROR_INVALID_STATE;
+        }
+
+        /* Clear derived class members */
+        serviceIndex = 0;
+        numServices = 0;
+        numCharacteristics = 0;
+
+        state = INACTIVE;
+
+        serviceUUIDDiscoveryQueue.reset();
+        charUUIDDiscoveryQueue.reset();
+
+        onTerminationCallback = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+private:
+    ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
+
+private:
+    void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
+    void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
+
+    void triggerServiceUUIDDiscovery(void);
+    void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
+    void removeFirstServiceNeedingUUIDDiscovery(void);
+
+    void terminateServiceDiscovery(void) {
+        discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
+
+        bool wasActive = isActive();
+        state = INACTIVE;
+
+        if (wasActive && onTerminationCallback) {
+            onTerminationCallback(connHandle);
+        }
+    }
+
+    void terminateCharacteristicDiscovery(ble_error_t err) {
+        if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
+            if(discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) {
+               if(err == BLE_ERROR_NONE) {
+                    // fullfill the last characteristic
+                    discoveredCharacteristic.setLastHandle(services[serviceIndex].getEndHandle());
+
+                    if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+                        ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) &&
+                         (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
+                        if (characteristicCallback) {
+                            characteristicCallback(&discoveredCharacteristic);
+                        }
+                    }
+               }
+               discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
+            }
+
+            state = SERVICE_DISCOVERY_ACTIVE;
+        }
+        serviceIndex++; /* Progress service index to keep discovery alive. */
+    }
+
+private:
+    void resetDiscoveredServices(void) {
+        numServices  = 0;
+        serviceIndex = 0;
+    }
+
+    void resetDiscoveredCharacteristics(void) {
+        numCharacteristics  = 0;
+    }
+
+private:
+    void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
+        connHandle = connectionHandle;
+        resetDiscoveredServices();
+        state = SERVICE_DISCOVERY_ACTIVE;
+    }
+
+private:
+    void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
+        connHandle = connectionHandle;
+        resetDiscoveredCharacteristics();
+        state = CHARACTERISTIC_DISCOVERY_ACTIVE;
+    }
+
+private:
+    /**
+     * A datatype to contain service-indices for which long UUIDs need to be
+     * discovered using read_val_by_uuid().
+     */
+    class ServiceUUIDDiscoveryQueue {
+    public:
+        ServiceUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) :
+            numIndices(0),
+            serviceIndices(),
+            parentDiscoveryObject(parent) {
+            /* empty */
+        }
+
+    public:
+        void reset(void) {
+            numIndices = 0;
+            for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
+                serviceIndices[i] = INVALID_INDEX;
+            }
+        }
+        void enqueue(int serviceIndex) {
+            serviceIndices[numIndices++] = serviceIndex;
+        }
+        int dequeue(void) {
+            if (numIndices == 0) {
+                return INVALID_INDEX;
+            }
+
+            unsigned valueToReturn = serviceIndices[0];
+            numIndices--;
+            for (unsigned i = 0; i < numIndices; i++) {
+                serviceIndices[i] = serviceIndices[i + 1];
+            }
+
+            return valueToReturn;
+        }
+        unsigned getFirst(void) const {
+            return serviceIndices[0];
+        }
+        size_t getCount(void) const {
+            return numIndices;
+        }
+
+        /**
+         * Trigger UUID discovery for the first of the enqueued ServiceIndices.
+         */
+        void triggerFirst(void);
+
+    private:
+        static const int INVALID_INDEX = -1;
+
+    private:
+        size_t numIndices;
+        int    serviceIndices[BLE_DB_DISCOVERY_MAX_SRV];
+
+        nRF5xServiceDiscovery *parentDiscoveryObject;
+    };
+    friend class ServiceUUIDDiscoveryQueue;
+
+    /**
+     * A datatype to contain characteristic-indices for which long UUIDs need to
+     * be discovered using read_val_by_uuid().
+     */
+    class CharUUIDDiscoveryQueue {
+    public:
+        CharUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) :
+            numIndices(0),
+            charIndices(),
+            parentDiscoveryObject(parent) {
+            /* empty */
+        }
+
+    public:
+        void reset(void) {
+            numIndices = 0;
+            for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
+                charIndices[i] = INVALID_INDEX;
+            }
+        }
+        void enqueue(int serviceIndex) {
+            charIndices[numIndices++] = serviceIndex;
+        }
+        int dequeue(void) {
+            if (numIndices == 0) {
+                return INVALID_INDEX;
+            }
+
+            unsigned valueToReturn = charIndices[0];
+            numIndices--;
+            for (unsigned i = 0; i < numIndices; i++) {
+                charIndices[i] = charIndices[i + 1];
+            }
+
+            return valueToReturn;
+        }
+        unsigned getFirst(void) const {
+            return charIndices[0];
+        }
+        size_t getCount(void) const {
+            return numIndices;
+        }
+
+        /**
+         * Trigger UUID discovery for the first of the enqueued charIndices.
+         */
+        void triggerFirst(void);
+
+    private:
+        static const int INVALID_INDEX = -1;
+
+    private:
+        size_t numIndices;
+        int    charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
+
+        nRF5xServiceDiscovery *parentDiscoveryObject;
+    };
+    friend class CharUUIDDiscoveryQueue;
+
+private:
+    friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+    void progressCharacteristicDiscovery(void);
+    void progressServiceDiscovery(void);
+
+private:
+    nRF5xGattClient *gattc;
+
+private:
+    uint8_t  serviceIndex;        /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
+    uint8_t  numServices;         /**< Number of services at the peers GATT database.*/
+    uint8_t  numCharacteristics;  /**< Number of characteristics within the service.*/
+
+    enum State_t {
+        INACTIVE,
+        SERVICE_DISCOVERY_ACTIVE,
+        CHARACTERISTIC_DISCOVERY_ACTIVE,
+        DISCOVER_SERVICE_UUIDS,
+        DISCOVER_CHARACTERISTIC_UUIDS,
+    } state;
+
+    DiscoveredService           services[BLE_DB_DISCOVERY_MAX_SRV];  /**< Information related to the current service being discovered.
+                                                                      *  This is intended for internal use during service discovery. */
+    nRF5xDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
+
+    ServiceUUIDDiscoveryQueue   serviceUUIDDiscoveryQueue;
+    CharUUIDDiscoveryQueue      charUUIDDiscoveryQueue;
+
+    TerminationCallback_t       onTerminationCallback;
+
+    /*
+     * The currently discovered characteristic. Discovery of a characteristic
+     * is a two phase process.
+     * First, declaration handle is fetched, it provide the UUID, the value handle and
+     * the properties of a characteristic.
+     * Second, the next declaration handle is fetched, with its declaration handle, it is
+     * possible to compute the last handle of the discovered characteristic and fill the
+     * missing part of the object.
+     * If there is no remaining characteristic to discover, the last handle of the
+     * discovered characteristic will be set to the last handle of its enclosing service.
+     */
+    nRF5xDiscoveredCharacteristic discoveredCharacteristic;
+};
+
+#endif /*__NRF_SERVICE_DISCOVERY_H__*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xn.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,212 @@
+/* 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 "nrf_delay.h"
+
+extern "C" {
+#include "softdevice_handler.h"
+}
+
+/**
+ * The singleton which represents the nRF51822 transport for the BLE.
+ */
+static nRF5xn *deviceInstance = NULL;
+
+/**
+ * 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)
+{
+    if (deviceInstance == NULL)
+        deviceInstance = new nRF5xn();
+
+    return *deviceInstance;
+}
+
+nRF5xn::nRF5xn(void) :
+    initialized(false),
+    instanceID(BLE::DEFAULT_INSTANCE),
+    gapInstance(),
+    gattServerInstance(NULL),
+    gattClientInstance(NULL),
+    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 (softdevice_handler_sd_disable() != NRF_SUCCESS) {
+        return BLE_STACK_BUSY;
+    }
+
+
+    /* 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)
+    if (gattClientInstance != NULL) {
+        error = gattClientInstance->reset();
+        if (error != BLE_ERROR_NONE) {
+            return error;
+        }
+    }
+#endif
+
+    /* Gap instance is always present */
+    error = gapInstance.reset();
+    if (error != BLE_ERROR_NONE) {
+        return error;
+    }
+
+    initialized = false;
+    return BLE_ERROR_NONE;
+}
+
+void
+nRF5xn::waitForEvent(void)
+{
+    sd_app_evt_wait();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/nRF5xn.h	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,182 @@
+/* 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 "nRF5xGap.h"
+#include "nRF5xGattServer.h"
+#include "nRF5xGattClient.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 nRF5xGattClient &getGattClient() {
+        if (gattClientInstance == NULL) {
+            gattClientInstance = new nRF5xGattClient();
+        }
+        return *gattClientInstance;
+    }
+
+    /**
+     * 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);
+
+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. */
+    mutable nRF5xGattClient      *gattClientInstance;      /**< Pointer to the GattClient object instance.
+                                                            *   If NULL, then GattClient has not been initialized.
+                                                            *   The pointer has been declared as 'mutable' so that
+                                                            *   it can be assigned inside a 'const' function. */
+    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
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/projectconfig.h	Mon Oct 17 12:41:20 2016 +0000
@@ -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_ */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/nRF51822/source/supress-warnings.cmake	Mon Oct 17 12:41:20 2016 +0000
@@ -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()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/CMakeLists.txt	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,105 @@
+# This file is no longer auto-generated to make the repository builds with GCC
+# and ARMCC no matter what.
+
+cmake_minimum_required(VERSION 2.8.12)
+
+enable_language(ASM)
+
+set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES
+    "core/MemberFunctionCallback.cpp"
+    "core/MicroBitCompat.cpp"
+    "core/MicroBitDevice.cpp"
+    "core/MicroBitFiber.cpp"
+    "core/MicroBitFont.cpp"
+    "core/MicroBitHeapAllocator.cpp"
+    "core/MicroBitListener.cpp"
+    "core/MicroBitSystemTimer.cpp"
+
+    "types/ManagedString.cpp"
+    "types/Matrix4.cpp"
+    "types/MicroBitEvent.cpp"
+    "types/MicroBitImage.cpp"
+    "types/PacketBuffer.cpp"
+    "types/RefCounted.cpp"
+
+    "drivers/DynamicPwm.cpp"
+    "drivers/MicroBitAccelerometer.cpp"
+    "drivers/MicroBitButton.cpp"
+    "drivers/MicroBitCompass.cpp"
+    "drivers/MicroBitCompassCalibrator.cpp"
+    "drivers/MicroBitDisplay.cpp"
+    "drivers/MicroBitI2C.cpp"
+    "drivers/MicroBitIO.cpp"
+    "drivers/MicroBitLightSensor.cpp"
+    "drivers/MicroBitMessageBus.cpp"
+    "drivers/MicroBitMultiButton.cpp"
+    "drivers/MicroBitPin.cpp"
+    "drivers/MicroBitRadio.cpp"
+    "drivers/MicroBitRadioDatagram.cpp"
+    "drivers/MicroBitRadioEvent.cpp"
+    "drivers/MicroBitSerial.cpp"
+    "drivers/MicroBitStorage.cpp"
+    "drivers/MicroBitThermometer.cpp"
+    "drivers/TimedInterruptIn.cpp"
+
+    "bluetooth/MicroBitAccelerometerService.cpp"
+    "bluetooth/MicroBitBLEManager.cpp"
+    "bluetooth/MicroBitButtonService.cpp"
+    "bluetooth/MicroBitDFUService.cpp"
+    "bluetooth/MicroBitEventService.cpp"
+    "bluetooth/MicroBitIOPinService.cpp"
+    "bluetooth/MicroBitLEDService.cpp"
+    "bluetooth/MicroBitMagnetometerService.cpp"
+    "bluetooth/MicroBitTemperatureService.cpp"
+    "bluetooth/MicroBitUARTService.cpp"
+)
+
+execute_process(WORKING_DIRECTORY "../../yotta_modules/${PROJECT_NAME}" COMMAND "git" "log" "--pretty=format:%h" "-n" "1" OUTPUT_VARIABLE git_hash)
+execute_process(WORKING_DIRECTORY "../../yotta_modules/${PROJECT_NAME}" COMMAND "git" "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE git_branch OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if ("${git_branch}" STREQUAL "master")
+    set(MICROBIT_DAL_VERSION_STRING "${YOTTA_MICROBIT_DAL_VERSION_STRING}")
+else()
+    set(MICROBIT_DAL_VERSION_STRING "${YOTTA_MICROBIT_DAL_VERSION_STRING}-${git_branch}-g${git_hash}")
+endif()
+
+set(MICROBIT_DAL_VERSION_FLAGS "-DMICROBIT_DAL_VERSION=\\\"${MICROBIT_DAL_VERSION_STRING}\\\"")
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MICROBIT_DAL_VERSION_FLAGS}")
+
+if (YOTTA_CFG_MICROBIT_CONFIGFILE)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${YOTTA_FORCE_INCLUDE_FLAG} \"${YOTTA_CFG_MICROBIT_CONFIGFILE}\"")
+endif ()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+  file(REMOVE "asm/CortexContextSwitch.s")
+  configure_file("asm/CortexContextSwitch.s.gcc" "asm/CortexContextSwitch.s" COPYONLY)
+else()
+  file(REMOVE "asm/CortexContextSwitch.s")
+  configure_file("asm/CortexContextSwitch.s.armcc" "asm/CortexContextSwitch.s" COPYONLY)
+endif()
+
+set(YOTTA_AUTO_MICROBIT-DAL_S_FILES
+    "asm/CortexContextSwitch.s"
+)
+
+add_library(microbit-dal
+    ${YOTTA_AUTO_MICROBIT-DAL_CPP_FILES}
+    ${YOTTA_AUTO_MICROBIT-DAL_S_FILES}
+)
+
+yotta_postprocess_target(LIBRARY microbit-dal)
+
+target_link_libraries(microbit-dal
+    mbed-classic
+    ble
+    ble-nrf51822
+)
+
+if(CMAKE_COMPILER_IS_GNUCC)
+    message("suppressing ALL warnings from mbed-classic, ble, ble-nrf51822 & nrf51-sdk")
+    target_compile_options(mbed-classic PRIVATE "-w")
+    target_compile_options(ble PRIVATE "-w")
+    target_compile_options(ble-nrf51822 PRIVATE "-w")
+    target_compile_options(nrf51-sdk PRIVATE "-w")
+endif()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/asm/CortexContextSwitch.s	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,293 @@
+; The MIT License (MIT)
+
+; Copyright (c) 2016 British Broadcasting Corporation.
+; This software is provided by Lancaster University by arrangement with the BBC.
+
+; Permission is hereby granted, free of charge, to any person obtaining a
+; copy of this software and associated documentation files (the "Software"),
+; to deal in the Software without restriction, including without limitation
+; the rights to use, copy, modify, merge, publish, distribute, sublicense,
+; and/or sell copies of the Software, and to permit persons to whom the
+; Software is furnished to do so, subject to the following conditions:
+
+; The above copyright notice and this permission notice shall be included in
+; all copies or substantial portions of the Software.
+
+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+; DEALINGS IN THE SOFTWARE.
+
+   AREA asm_func, CODE, READONLY
+
+; Export our context switching subroutine as a C function for use in mbed
+    EXPORT swap_context
+    EXPORT save_context
+    EXPORT save_register_context
+    EXPORT restore_register_context
+
+    ALIGN
+
+; R0 Contains a pointer to the TCB of the fibre being scheduled out.
+; R1 Contains a pointer to the TCB of the fibre being scheduled in.
+; R2 Contains a pointer to the base of the stack of the fibre being scheduled out.
+; R3 Contains a pointer to the base of the stack of the fibre being scheduled in.
+
+swap_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    ; Skip this is we're given a NULL parameter for the TCB
+    CMP     R0, #0
+    BEQ     store_context_complete
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+store_context_complete
+    ; Finally, Copy the stack. We do this to reduce RAM footprint, as stack is usually very small at the point
+    ; of scheduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    ; Skip this is we're given a NULL parameter for the stack.
+    CMP     R2, #0
+    BEQ     store_stack_complete
+
+    LDR     R4, [R0,#60]         ; Load R4 with the fiber's defined stack_base.
+store_stack
+    SUBS    R4, #4
+    SUBS    R2, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R2]
+
+    CMP     R4, R6
+    BNE     store_stack
+
+store_stack_complete
+
+    ;
+    ; Now page in the new context.
+    ; Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    ;
+    LDR     R4, [R1, #56]
+    MOV     LR, R4
+    LDR     R6, [R1, #52]
+    MOV     SP, R6
+
+    ; Copy the stack in.
+    ; n.b. we do this after setting the SP to make comparisons easier.
+
+    ; Skip this is we're given a NULL parameter for the stack.
+    CMP     R3, #0
+    BEQ     restore_stack_complete
+
+    LDR     R4, [R1,#60]         ; Load R4 with the fiber's defined stack_base.
+
+restore_stack
+    SUBS    R4, #4
+    SUBS    R3, #4
+
+    LDR     R5, [R3]
+    STR     R5, [R4]
+
+    CMP     R4, R6
+    BNE     restore_stack
+
+restore_stack_complete
+    LDR     R4, [R1, #48]
+    MOV     R12, R4
+    LDR     R4, [R1, #44]
+    MOV     R11, R4
+    LDR     R4, [R1, #40]
+    MOV     R10, R4
+    LDR     R4, [R1, #36]
+    MOV     R9, R4
+    LDR     R4, [R1, #32]
+    MOV     R8, R4
+
+    LDR     R7, [R1, #28]
+    LDR     R6, [R1, #24]
+    LDR     R5, [R1, #20]
+    LDR     R4, [R1, #16]
+    LDR     R3, [R1, #12]
+    LDR     R2, [R1, #8]
+    LDR     R0, [R1, #0]
+    LDR     R1, [R1, #4]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+; R0 Contains a pointer to the TCB of the fibre to snapshot
+; R1 Contains a pointer to the base of the stack of the fibre being snapshotted
+
+save_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    ; Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point
+    ; of sceduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    LDR     R4, [R0,#60]         ; Load R4 with the fiber's defined stack_base.
+
+store_stack1
+    SUBS    R4, #4
+    SUBS    R1, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R1]
+
+    CMP     R4, R6
+    BNE     store_stack1
+
+    ; Restore scratch registers.
+
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+; R0 Contains a pointer to the TCB of the fiber to snapshot
+save_register_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack Pointer and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R4, SP
+    STR     R4, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    ; Restore scratch registers.
+    LDR     R4, [R0, #16]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+restore_register_context
+
+    ;
+    ; Now page in the new context.
+    ; Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    ;
+    LDR     R4, [R0, #56]
+    MOV     LR, R4
+    LDR     R4, [R0, #52]
+    MOV     SP, R4
+
+    ; High registers...
+    LDR     R4, [R0, #48]
+    MOV     R12, R4
+    LDR     R4, [R0, #44]
+    MOV     R11, R4
+    LDR     R4, [R0, #40]
+    MOV     R10, R4
+    LDR     R4, [R0, #36]
+    MOV     R9, R4
+    LDR     R4, [R0, #32]
+    MOV     R8, R4
+
+    ; Low registers...
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+    LDR     R3, [R0, #12]
+    LDR     R2, [R0, #8]
+    LDR     R0, [R0, #0]
+    LDR     R1, [R0, #4]
+
+    ; Return to caller (normally the scheduler).
+    BX      LR
+
+    ALIGN
+    END
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/asm/CortexContextSwitch.s.armcc	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,293 @@
+; The MIT License (MIT)
+
+; Copyright (c) 2016 British Broadcasting Corporation.
+; This software is provided by Lancaster University by arrangement with the BBC.
+
+; Permission is hereby granted, free of charge, to any person obtaining a
+; copy of this software and associated documentation files (the "Software"),
+; to deal in the Software without restriction, including without limitation
+; the rights to use, copy, modify, merge, publish, distribute, sublicense,
+; and/or sell copies of the Software, and to permit persons to whom the
+; Software is furnished to do so, subject to the following conditions:
+
+; The above copyright notice and this permission notice shall be included in
+; all copies or substantial portions of the Software.
+
+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+; DEALINGS IN THE SOFTWARE.
+
+   AREA asm_func, CODE, READONLY
+
+; Export our context switching subroutine as a C function for use in mbed
+    EXPORT swap_context
+    EXPORT save_context
+    EXPORT save_register_context
+    EXPORT restore_register_context
+
+    ALIGN
+
+; R0 Contains a pointer to the TCB of the fibre being scheduled out.
+; R1 Contains a pointer to the TCB of the fibre being scheduled in.
+; R2 Contains a pointer to the base of the stack of the fibre being scheduled out.
+; R3 Contains a pointer to the base of the stack of the fibre being scheduled in.
+
+swap_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    ; Skip this is we're given a NULL parameter for the TCB
+    CMP     R0, #0
+    BEQ     store_context_complete
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+store_context_complete
+    ; Finally, Copy the stack. We do this to reduce RAM footprint, as stack is usually very small at the point
+    ; of scheduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    ; Skip this is we're given a NULL parameter for the stack.
+    CMP     R2, #0
+    BEQ     store_stack_complete
+
+    LDR     R4, [R0,#60]         ; Load R4 with the fiber's defined stack_base.
+store_stack
+    SUBS    R4, #4
+    SUBS    R2, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R2]
+
+    CMP     R4, R6
+    BNE     store_stack
+
+store_stack_complete
+
+    ;
+    ; Now page in the new context.
+    ; Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    ;
+    LDR     R4, [R1, #56]
+    MOV     LR, R4
+    LDR     R6, [R1, #52]
+    MOV     SP, R6
+
+    ; Copy the stack in.
+    ; n.b. we do this after setting the SP to make comparisons easier.
+
+    ; Skip this is we're given a NULL parameter for the stack.
+    CMP     R3, #0
+    BEQ     restore_stack_complete
+
+    LDR     R4, [R1,#60]         ; Load R4 with the fiber's defined stack_base.
+
+restore_stack
+    SUBS    R4, #4
+    SUBS    R3, #4
+
+    LDR     R5, [R3]
+    STR     R5, [R4]
+
+    CMP     R4, R6
+    BNE     restore_stack
+
+restore_stack_complete
+    LDR     R4, [R1, #48]
+    MOV     R12, R4
+    LDR     R4, [R1, #44]
+    MOV     R11, R4
+    LDR     R4, [R1, #40]
+    MOV     R10, R4
+    LDR     R4, [R1, #36]
+    MOV     R9, R4
+    LDR     R4, [R1, #32]
+    MOV     R8, R4
+
+    LDR     R7, [R1, #28]
+    LDR     R6, [R1, #24]
+    LDR     R5, [R1, #20]
+    LDR     R4, [R1, #16]
+    LDR     R3, [R1, #12]
+    LDR     R2, [R1, #8]
+    LDR     R0, [R1, #0]
+    LDR     R1, [R1, #4]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+; R0 Contains a pointer to the TCB of the fibre to snapshot
+; R1 Contains a pointer to the base of the stack of the fibre being snapshotted
+
+save_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    ; Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point
+    ; of sceduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    LDR     R4, [R0,#60]         ; Load R4 with the fiber's defined stack_base.
+
+store_stack1
+    SUBS    R4, #4
+    SUBS    R1, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R1]
+
+    CMP     R4, R6
+    BNE     store_stack1
+
+    ; Restore scratch registers.
+
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+; R0 Contains a pointer to the TCB of the fiber to snapshot
+save_register_context
+
+    ; Write our core registers into the TCB
+    ; First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    ; Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    ; Now the Stack Pointer and Link Register.
+    ; As this context is only intended for use with a fiber scheduler,
+    ; we don't need the PC.
+    MOV     R4, SP
+    STR     R4, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    ; Restore scratch registers.
+    LDR     R4, [R0, #16]
+
+    ; Return to caller (scheduler).
+    BX      LR
+
+
+restore_register_context
+
+    ;
+    ; Now page in the new context.
+    ; Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    ;
+    LDR     R4, [R0, #56]
+    MOV     LR, R4
+    LDR     R4, [R0, #52]
+    MOV     SP, R4
+
+    ; High registers...
+    LDR     R4, [R0, #48]
+    MOV     R12, R4
+    LDR     R4, [R0, #44]
+    MOV     R11, R4
+    LDR     R4, [R0, #40]
+    MOV     R10, R4
+    LDR     R4, [R0, #36]
+    MOV     R9, R4
+    LDR     R4, [R0, #32]
+    MOV     R8, R4
+
+    ; Low registers...
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+    LDR     R3, [R0, #12]
+    LDR     R2, [R0, #8]
+    LDR     R0, [R0, #0]
+    LDR     R1, [R0, #4]
+
+    ; Return to caller (normally the scheduler).
+    BX      LR
+
+    ALIGN
+    END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/asm/CortexContextSwitch.s.gcc	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,292 @@
+@ The MIT License (MIT)
+
+@ Copyright (c) 2016 British Broadcasting Corporation.
+@ This software is provided by Lancaster University by arrangement with the BBC.
+
+@ Permission is hereby granted, free of charge, to any person obtaining a
+@ copy of this software and associated documentation files (the "Software"),
+@ to deal in the Software without restriction, including without limitation
+@ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+@ and/or sell copies of the Software, and to permit persons to whom the
+@ Software is furnished to do so, subject to the following conditions:
+
+@ The above copyright notice and this permission notice shall be included in
+@ all copies or substantial portions of the Software.
+
+@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+@ DEALINGS IN THE SOFTWARE.
+
+    .syntax unified
+    .cpu cortex-m0
+    .thumb
+    .text
+    .align 2
+
+@ Export our context switching subroutine as a C function for use in mbed
+    .global swap_context
+    .global save_context
+    .global save_register_context
+    .global restore_register_context
+
+@ R0 Contains a pointer to the TCB of the fibre being scheduled out.
+@ R1 Contains a pointer to the TCB of the fibre being scheduled in.
+@ R2 Contains a pointer to the base of the stack of the fibre being scheduled out.
+@ R3 Contains a pointer to the base of the stack of the fibre being scheduled in.
+
+swap_context:
+
+    @ Write our core registers into the TCB
+    @ First, store the general registers
+
+    @ Skip this is we're given a NULL parameter for the TCB
+    CMP     R0, #0
+    BEQ     store_context_complete
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    @ Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    @ Now the Stack and Link Register.
+    @ As this context is only intended for use with a fiber scheduler,
+    @ we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+store_context_complete:
+    @ Finally, Copy the stack. We do this to reduce RAM footprint, as stack is usually very small at the point
+    @ of scheduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    @ Skip this is we're given a NULL parameter for the stack.
+    CMP     R2, #0
+    BEQ     store_stack_complete
+
+    LDR     R4, [R0,#60]         @ Load R4 with the fiber's defined stack_base.
+store_stack:
+    SUBS    R4, #4
+    SUBS    R2, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R2]
+
+    CMP     R4, R6
+    BNE     store_stack
+
+store_stack_complete:
+
+    @
+    @ Now page in the new context.
+    @ Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    @
+    LDR     R4, [R1, #56]
+    MOV     LR, R4
+    LDR     R6, [R1, #52]
+    MOV     SP, R6
+
+    @ Copy the stack in.
+    @ n.b. we do this after setting the SP to make comparisons easier.
+
+    @ Skip this is we're given a NULL parameter for the stack.
+    CMP     R3, #0
+    BEQ     restore_stack_complete
+
+    LDR     R4, [R1,#60]         @ Load R4 with the fiber's defined stack_base.
+
+restore_stack:
+    SUBS    R4, #4
+    SUBS    R3, #4
+
+    LDR     R5, [R3]
+    STR     R5, [R4]
+
+    CMP     R4, R6
+    BNE     restore_stack
+
+restore_stack_complete:
+    LDR     R4, [R1, #48]
+    MOV     R12, R4
+    LDR     R4, [R1, #44]
+    MOV     R11, R4
+    LDR     R4, [R1, #40]
+    MOV     R10, R4
+    LDR     R4, [R1, #36]
+    MOV     R9, R4
+    LDR     R4, [R1, #32]
+    MOV     R8, R4
+
+    LDR     R7, [R1, #28]
+    LDR     R6, [R1, #24]
+    LDR     R5, [R1, #20]
+    LDR     R4, [R1, #16]
+    LDR     R3, [R1, #12]
+    LDR     R2, [R1, #8]
+    LDR     R0, [R1, #0]
+    LDR     R1, [R1, #4]
+
+    @ Return to caller (scheduler).
+    BX      LR
+
+
+@ R0 Contains a pointer to the TCB of the fibre to snapshot
+@ R1 Contains a pointer to the base of the stack of the fibre being snapshotted
+
+save_context:
+
+    @ Write our core registers into the TCB
+    @ First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    @ Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    @ Now the Stack and Link Register.
+    @ As this context is only intended for use with a fiber scheduler,
+    @ we don't need the PC.
+    MOV     R6, SP
+    STR     R6, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    @ Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point
+    @ of sceduling, but we need a lot of capacity for interrupt handling and other functions.
+
+    LDR     R4, [R0,#60]         @ Load R4 with the fiber's defined stack_base.
+
+store_stack1:
+    SUBS    R4, #4
+    SUBS    R1, #4
+
+    LDR     R5, [R4]
+    STR     R5, [R1]
+
+    CMP     R4, R6
+    BNE     store_stack1
+
+    @ Restore scratch registers.
+
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+
+    @ Return to caller (scheduler).
+    BX      LR
+
+
+@ R0 Contains a pointer to the TCB of the fiber to snapshot
+save_register_context:
+
+    @ Write our core registers into the TCB
+    @ First, store the general registers
+
+    STR     R0, [R0,#0]
+    STR     R1, [R0,#4]
+    STR     R2, [R0,#8]
+    STR     R3, [R0,#12]
+    STR     R4, [R0,#16]
+    STR     R5, [R0,#20]
+    STR     R6, [R0,#24]
+    STR     R7, [R0,#28]
+
+    @ Now the high general purpose registers
+    MOV     R4, R8
+    STR     R4, [R0,#32]
+    MOV     R4, R9
+    STR     R4, [R0,#36]
+    MOV     R4, R10
+    STR     R4, [R0,#40]
+    MOV     R4, R11
+    STR     R4, [R0,#44]
+    MOV     R4, R12
+    STR     R4, [R0,#48]
+
+    @ Now the Stack Pointer and Link Register.
+    @ As this context is only intended for use with a fiber scheduler,
+    @ we don't need the PC.
+    MOV     R4, SP
+    STR     R4, [R0,#52]
+    MOV     R4, LR
+    STR     R4, [R0,#56]
+
+    @ Restore scratch registers.
+    LDR     R4, [R0, #16]
+
+    @ Return to caller (scheduler).
+    BX      LR
+
+
+restore_register_context:
+
+    @
+    @ Now page in the new context.
+    @ Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler.
+    @
+    LDR     R4, [R0, #56]
+    MOV     LR, R4
+    LDR     R4, [R0, #52]
+    MOV     SP, R4
+
+    @ High registers...
+    LDR     R4, [R0, #48]
+    MOV     R12, R4
+    LDR     R4, [R0, #44]
+    MOV     R11, R4
+    LDR     R4, [R0, #40]
+    MOV     R10, R4
+    LDR     R4, [R0, #36]
+    MOV     R9, R4
+    LDR     R4, [R0, #32]
+    MOV     R8, R4
+
+    @ Low registers...
+    LDR     R7, [R0, #28]
+    LDR     R6, [R0, #24]
+    LDR     R5, [R0, #20]
+    LDR     R4, [R0, #16]
+    LDR     R3, [R0, #12]
+    LDR     R2, [R0, #8]
+    LDR     R0, [R0, #0]
+    LDR     R1, [R0, #4]
+
+    @ Return to caller (normally the scheduler).
+    BX      LR
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitAccelerometerService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,121 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit Accelerometer Service.
+  * Provides a BLE service to remotely read the state of the accelerometer, and configure its behaviour.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitAccelerometerService.h"
+
+/**
+  * Constructor.
+  * Create a representation of the AccelerometerService
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _accelerometer An instance of MicroBitAccelerometer.
+  */
+MicroBitAccelerometerService::MicroBitAccelerometerService(BLEDevice &_ble, MicroBitAccelerometer &_accelerometer) :
+        ble(_ble), accelerometer(_accelerometer)
+{
+    // Create the data structures that represent each of our characteristics in Soft Device.
+    GattCharacteristic  accelerometerDataCharacteristic(MicroBitAccelerometerServiceDataUUID, (uint8_t *)accelerometerDataCharacteristicBuffer, 0,
+    sizeof(accelerometerDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  accelerometerPeriodCharacteristic(MicroBitAccelerometerServicePeriodUUID, (uint8_t *)&accelerometerPeriodCharacteristicBuffer, 0,
+    sizeof(accelerometerPeriodCharacteristicBuffer),
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    // Initialise our characteristic values.
+    accelerometerDataCharacteristicBuffer[0] = 0;
+    accelerometerDataCharacteristicBuffer[1] = 0;
+    accelerometerDataCharacteristicBuffer[2] = 0;
+    accelerometerPeriodCharacteristicBuffer = accelerometer.getPeriod();
+
+    // Set default security requirements
+    accelerometerDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    accelerometerPeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&accelerometerDataCharacteristic, &accelerometerPeriodCharacteristic};
+    GattService         service(MicroBitAccelerometerServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    accelerometerDataCharacteristicHandle = accelerometerDataCharacteristic.getValueHandle();
+    accelerometerPeriodCharacteristicHandle = accelerometerPeriodCharacteristic.getValueHandle();
+
+    ble.gattServer().write(accelerometerDataCharacteristicHandle,(uint8_t *)accelerometerDataCharacteristicBuffer, sizeof(accelerometerDataCharacteristicBuffer));
+    ble.gattServer().write(accelerometerPeriodCharacteristicHandle, (const uint8_t *)&accelerometerPeriodCharacteristicBuffer, sizeof(accelerometerPeriodCharacteristicBuffer));
+
+    ble.onDataWritten(this, &MicroBitAccelerometerService::onDataWritten);
+
+    if (EventModel::defaultEventBus)
+        EventModel::defaultEventBus->listen(MICROBIT_ID_ACCELEROMETER, MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE, this, &MicroBitAccelerometerService::accelerometerUpdate,  MESSAGE_BUS_LISTENER_IMMEDIATE);
+}
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitAccelerometerService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    if (params->handle == accelerometerPeriodCharacteristicHandle && params->len >= sizeof(accelerometerPeriodCharacteristicBuffer))
+    {
+        accelerometerPeriodCharacteristicBuffer = *((uint16_t *)params->data);
+        accelerometer.setPeriod(accelerometerPeriodCharacteristicBuffer);
+
+        // The accelerometer will choose the nearest period to that requested that it can support
+        // Read back the ACTUAL period it is using, and report this back.
+        accelerometerPeriodCharacteristicBuffer = accelerometer.getPeriod();
+        ble.gattServer().write(accelerometerPeriodCharacteristicHandle, (const uint8_t *)&accelerometerPeriodCharacteristicBuffer, sizeof(accelerometerPeriodCharacteristicBuffer));
+    }
+}
+
+/**
+  * Accelerometer update callback
+  */
+void MicroBitAccelerometerService::accelerometerUpdate(MicroBitEvent)
+{
+    if (ble.getGapState().connected)
+    {
+        accelerometerDataCharacteristicBuffer[0] = accelerometer.getX();
+        accelerometerDataCharacteristicBuffer[1] = accelerometer.getY();
+        accelerometerDataCharacteristicBuffer[2] = accelerometer.getZ();
+
+        ble.gattServer().notify(accelerometerDataCharacteristicHandle,(uint8_t *)accelerometerDataCharacteristicBuffer, sizeof(accelerometerDataCharacteristicBuffer));
+    }
+}
+
+const uint8_t  MicroBitAccelerometerServiceUUID[] = {
+    0xe9,0x5d,0x07,0x53,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitAccelerometerServiceDataUUID[] = {
+    0xe9,0x5d,0xca,0x4b,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitAccelerometerServicePeriodUUID[] = {
+    0xe9,0x5d,0xfb,0x24,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitBLEManager.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,627 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitBLEManager.h"
+#include "MicroBitStorage.h"
+#include "MicroBitFiber.h"
+
+
+/* The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ.
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include "ble.h"
+
+extern "C"
+{
+#include "device_manager.h"
+uint32_t btle_set_gatt_table_size(uint32_t size);
+}
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic pop
+#endif
+
+#define MICROBIT_PAIRING_FADE_SPEED		4
+
+const char* MICROBIT_BLE_MANUFACTURER = NULL;
+const char* MICROBIT_BLE_MODEL = "BBC micro:bit";
+const char* MICROBIT_BLE_HARDWARE_VERSION = NULL;
+const char* MICROBIT_BLE_FIRMWARE_VERSION = MICROBIT_DAL_VERSION;
+const char* MICROBIT_BLE_SOFTWARE_VERSION = NULL;
+const int8_t MICROBIT_BLE_POWER_LEVEL[] = {-30, -20, -16, -12, -8, -4, 0, 4};
+
+/*
+ * Many of the mbed interfaces we need to use only support callbacks to plain C functions, rather than C++ methods.
+ * So, we maintain a pointer to the MicroBitBLEManager that's in use. Ths way, we can still access resources on the micro:bit
+ * whilst keeping the code modular.
+ */
+static MicroBitBLEManager *manager = NULL;                      // Singleton reference to the BLE manager. many mbed BLE API callbacks still do not support member funcions yet. :-(
+static uint8_t deviceID = 255;                                  // Unique ID for the peer that has connected to us.
+static Gap::Handle_t pairingHandle = 0;                         // The connection handle used during a pairing process. Used to ensure that connections are dropped elegantly.
+
+static void storeSystemAttributes(Gap::Handle_t handle)
+{
+    if(manager->storage != NULL && deviceID < MICROBIT_BLE_MAXIMUM_BONDS)
+    {
+        ManagedString key("bleSysAttrs");
+
+        KeyValuePair* bleSysAttrs = manager->storage->get(key);
+
+        BLESysAttribute attrib;
+        BLESysAttributeStore attribStore;
+
+        uint16_t len = sizeof(attrib.sys_attr);
+
+        sd_ble_gatts_sys_attr_get(handle, attrib.sys_attr, &len, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+
+        //copy our stored sysAttrs
+        if(bleSysAttrs != NULL)
+        {
+            memcpy(&attribStore, bleSysAttrs->value, sizeof(BLESysAttributeStore));
+            delete bleSysAttrs;
+        }
+
+        //check if we need to update
+        if(memcmp(attribStore.sys_attrs[deviceID].sys_attr, attrib.sys_attr, len) != 0)
+        {
+            attribStore.sys_attrs[deviceID] = attrib;
+            manager->storage->put(key, (uint8_t *)&attribStore, sizeof(attribStore));
+        }
+    }
+}
+
+/**
+  * Callback when a BLE GATT disconnect occurs.
+  */
+static void bleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *reason)
+{
+    MicroBitEvent(MICROBIT_ID_BLE,MICROBIT_BLE_EVT_DISCONNECTED);
+
+    storeSystemAttributes(reason->handle);
+
+    if (manager)
+	    manager->advertise();
+}
+
+/**
+  * Callback when a BLE connection is established.
+  */
+static void bleConnectionCallback(const Gap::ConnectionCallbackParams_t*)
+{
+    MicroBitEvent(MICROBIT_ID_BLE,MICROBIT_BLE_EVT_CONNECTED);
+}
+
+/**
+  * Callback when a BLE SYS_ATTR_MISSING.
+  */
+static void bleSysAttrMissingCallback(const GattSysAttrMissingCallbackParams *params)
+{
+    int complete = 0;
+    deviceID = 255;
+
+    dm_handle_t dm_handle = {0,0,0,0};
+
+    int ret = dm_handle_get(params->connHandle, &dm_handle);
+
+    if (ret == 0)
+        deviceID = dm_handle.device_id;
+
+    if(manager->storage != NULL && deviceID < MICROBIT_BLE_MAXIMUM_BONDS)
+    {
+        ManagedString key("bleSysAttrs");
+
+        KeyValuePair* bleSysAttrs = manager->storage->get(key);
+
+        BLESysAttributeStore attribStore;
+        BLESysAttribute attrib;
+
+        if(bleSysAttrs != NULL)
+        {
+            //restore our sysAttrStore
+            memcpy(&attribStore, bleSysAttrs->value, sizeof(BLESysAttributeStore));
+            delete bleSysAttrs;
+
+            attrib = attribStore.sys_attrs[deviceID];
+
+            ret = sd_ble_gatts_sys_attr_set(params->connHandle, attrib.sys_attr, sizeof(attrib.sys_attr), BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+
+            complete = 1;
+
+            if(ret == 0)
+                ret = sd_ble_gatts_service_changed(params->connHandle, 0x000c, 0xffff);
+        }
+    }
+
+    if (!complete)
+        sd_ble_gatts_sys_attr_set(params->connHandle, NULL, 0, 0);
+
+}
+
+static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
+{
+    (void) handle; /* -Wunused-param */
+
+	ManagedString passKey((const char *)passkey, SecurityManager::PASSKEY_LEN);
+
+    if (manager)
+	    manager->pairingRequested(passKey);
+}
+
+static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
+{
+    (void) handle; /* -Wunused-param */
+
+    dm_handle_t dm_handle = {0,0,0,0};
+    int ret = dm_handle_get(handle, &dm_handle);
+
+    if (ret == 0)
+        deviceID = dm_handle.device_id;
+
+    if (manager)
+    {
+        pairingHandle = handle;
+	    manager->pairingComplete(status == SecurityManager::SEC_STATUS_SUCCESS);
+    }
+}
+
+/**
+ * Constructor.
+ *
+ * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
+ *
+ * @param _storage an instance of MicroBitStorage used to persist sys attribute information. (This is required for compatability with iOS).
+ *
+ * @note The BLE stack *cannot*  be brought up in a static context (the software simply hangs or corrupts itself).
+ * Hence, the init() member function should be used to initialise the BLE stack.
+ */
+MicroBitBLEManager::MicroBitBLEManager(MicroBitStorage& _storage) :
+    storage(&_storage)
+{
+    manager = this;
+	this->ble = NULL;
+	this->pairingStatus = 0;
+}
+
+/**
+ * Constructor.
+ *
+ * Configure and manage the micro:bit's Bluetooth Low Energy (BLE) stack.
+ *
+ * @note The BLE stack *cannot*  be brought up in a static context (the software simply hangs or corrupts itself).
+ * Hence, the init() member function should be used to initialise the BLE stack.
+ */
+MicroBitBLEManager::MicroBitBLEManager() :
+    storage(NULL)
+{
+    manager = this;
+	this->ble = NULL;
+	this->pairingStatus = 0;
+}
+
+/**
+ * When called, the micro:bit will begin advertising for a predefined period,
+ * MICROBIT_BLE_ADVERTISING_TIMEOUT seconds to bonded devices.
+ */
+void MicroBitBLEManager::advertise()
+{
+    if(ble)
+        ble->gap().startAdvertising();
+}
+
+/**
+  * Post constructor initialisation method as the BLE stack cannot be brought
+  * up in a static context.
+  *
+  * @param deviceName The name used when advertising
+  * @param serialNumber The serial number exposed by the device information service
+  * @param messageBus An instance of an EventModel, used during pairing.
+  * @param enableBonding If true, the security manager enabled bonding.
+  *
+  * @code
+  * bleManager.init(uBit.getName(), uBit.getSerial(), uBit.messageBus, true);
+  * @endcode
+  */
+void MicroBitBLEManager::init(ManagedString deviceName, ManagedString serialNumber, EventModel& messageBus, bool enableBonding)
+{
+	ManagedString BLEName("BBC micro:bit");
+	this->deviceName = deviceName;
+
+#if !(CONFIG_ENABLED(MICROBIT_BLE_WHITELIST))
+	ManagedString namePrefix(" [");
+	ManagedString namePostfix("]");
+	BLEName = BLEName + namePrefix + deviceName + namePostfix;
+#endif
+
+    // Start the BLE stack.
+#if CONFIG_ENABLED(MICROBIT_HEAP_REUSE_SD)
+    btle_set_gatt_table_size(MICROBIT_SD_GATT_TABLE_SIZE);
+#endif
+
+    ble = new BLEDevice();
+    ble->init();
+
+    // automatically restart advertising after a device disconnects.
+    ble->gap().onDisconnection(bleDisconnectionCallback);
+    ble->gattServer().onSysAttrMissing(bleSysAttrMissingCallback);
+
+    // generate an event when a Bluetooth connection is established
+    ble->gap().onConnection(bleConnectionCallback);
+
+    // Configure the stack to hold onto the CPU during critical timing events.
+    // mbed-classic performs __disable_irq() calls in its timers that can cause
+    // MIC failures on secure BLE channels...
+    ble_common_opt_radio_cpu_mutex_t opt;
+    opt.enable = 1;
+    sd_ble_opt_set(BLE_COMMON_OPT_RADIO_CPU_MUTEX, (const ble_opt_t *)&opt);
+
+#if CONFIG_ENABLED(MICROBIT_BLE_PRIVATE_ADDRESSES)
+	// Configure for private addresses, so kids' behaviour can't be easily tracked.
+	ble->gap().setAddress(BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE, {0});
+#endif
+
+    // Setup our security requirements.
+    ble->securityManager().onPasskeyDisplay(passkeyDisplayCallback);
+    ble->securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
+    ble->securityManager().init(enableBonding, (SecurityManager::MICROBIT_BLE_SECURITY_LEVEL == SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM), SecurityManager::IO_CAPS_DISPLAY_ONLY);
+
+    if (enableBonding)
+    {
+        // If we're in pairing mode, review the size of the bond table.
+        int bonds = getBondCount();
+
+        // TODO: It would be much better to implement some sort of LRU/NFU policy here,
+        // but this isn't currently supported in mbed, so we'd need to layer break...
+
+        // If we're full, empty the bond table.
+        if (bonds >= MICROBIT_BLE_MAXIMUM_BONDS)
+            ble->securityManager().purgeAllBondingState();
+    }
+
+#if CONFIG_ENABLED(MICROBIT_BLE_WHITELIST)
+    // Configure a whitelist to filter all connection requetss from unbonded devices.
+    // Most BLE stacks only permit one connection at a time, so this prevents denial of service attacks.
+    BLEProtocol::Address_t bondedAddresses[MICROBIT_BLE_MAXIMUM_BONDS];
+    Gap::Whitelist_t whitelist;
+    whitelist.addresses = bondedAddresses;
+    whitelist.capacity = MICROBIT_BLE_MAXIMUM_BONDS;
+
+    ble->securityManager().getAddressesFromBondTable(whitelist);
+
+    ble->gap().setWhitelist(whitelist);
+    ble->gap().setScanningPolicyMode(Gap::SCAN_POLICY_IGNORE_WHITELIST);
+    ble->gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_FILTER_CONN_REQS);
+#endif
+
+    // Configure the radio at our default power level
+    setTransmitPower(MICROBIT_BLE_DEFAULT_TX_POWER);
+
+    // Bring up core BLE services.
+#if CONFIG_ENABLED(MICROBIT_BLE_DFU_SERVICE)
+    new MicroBitDFUService(*ble);
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
+    DeviceInformationService ble_device_information_service (*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, serialNumber.toCharArray(), MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
+#else
+    (void)serialNumber;
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_BLE_EVENT_SERVICE)
+    new MicroBitEventService(*ble, messageBus);
+#else
+    (void)messageBus;
+#endif
+
+
+    // Configure for high speed mode where possible.
+    Gap::ConnectionParams_t fast;
+    ble->getPreferredConnectionParams(&fast);
+    fast.minConnectionInterval = 8; // 10 ms
+    fast.maxConnectionInterval = 16; // 20 ms
+    fast.slaveLatency = 0;
+    ble->setPreferredConnectionParams(&fast);
+
+    // Setup advertising.
+#if CONFIG_ENABLED(MICROBIT_BLE_WHITELIST)
+    ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+#else
+    ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+#endif
+
+    ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)BLEName.toCharArray(), BLEName.length());
+    ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble->setAdvertisingInterval(200);
+
+#if (MICROBIT_BLE_ADVERTISING_TIMEOUT > 0)
+    ble->gap().setAdvertisingTimeout(MICROBIT_BLE_ADVERTISING_TIMEOUT);
+#endif
+
+    // If we have whitelisting enabled, then prevent only enable advertising of we have any binded devices...
+    // This is to further protect kids' privacy. If no-one initiates BLE, then the device is unreachable.
+    // If whiltelisting is disabled, then we always advertise.
+#if CONFIG_ENABLED(MICROBIT_BLE_WHITELIST)
+    if (whitelist.size > 0)
+#endif
+        ble->startAdvertising();
+}
+
+/**
+ * Change the output power level of the transmitter to the given value.
+ *
+ * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
+ *
+ * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
+ *
+ * @code
+ * // maximum transmission power.
+ * bleManager.setTransmitPower(7);
+ * @endcode
+ */
+int MicroBitBLEManager::setTransmitPower(int power)
+{
+    if (power < 0 || power >= MICROBIT_BLE_POWER_LEVELS)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (ble->gap().setTxPower(MICROBIT_BLE_POWER_LEVEL[power]) != NRF_SUCCESS)
+        return MICROBIT_NOT_SUPPORTED;
+
+    return MICROBIT_OK;
+}
+
+/**
+ * Determines the number of devices currently bonded with this micro:bit.
+ * @return The number of active bonds.
+ */
+int MicroBitBLEManager::getBondCount()
+{
+    BLEProtocol::Address_t bondedAddresses[MICROBIT_BLE_MAXIMUM_BONDS];
+    Gap::Whitelist_t whitelist;
+    whitelist.addresses = bondedAddresses;
+    whitelist.capacity = MICROBIT_BLE_MAXIMUM_BONDS;
+    ble->securityManager().getAddressesFromBondTable(whitelist);
+
+    return whitelist.bonds;
+}
+
+/**
+ * A request to pair has been received from a BLE device.
+ * If we're in pairing mode, display the passkey to the user.
+ * Also, purge the bonding table if it has reached capacity.
+ *
+ * @note for internal use only.
+ */
+void MicroBitBLEManager::pairingRequested(ManagedString passKey)
+{
+    // Update our mode to display the passkey.
+	this->passKey = passKey;
+	this->pairingStatus = MICROBIT_BLE_PAIR_REQUEST;
+}
+
+/**
+ * A pairing request has been sucessfully completed.
+ * If we're in pairing mode, display a success or failure message.
+ *
+ * @note for internal use only.
+ */
+void MicroBitBLEManager::pairingComplete(bool success)
+{
+	this->pairingStatus = MICROBIT_BLE_PAIR_COMPLETE;
+
+	if(success)
+    {
+		this->pairingStatus |= MICROBIT_BLE_PAIR_SUCCESSFUL;
+        fiber_add_idle_component(this);
+    }
+}
+
+/**
+ * Periodic callback in thread context.
+ * We use this here purely to safely issue a disconnect operation after a pairing operation is complete.
+ */
+void MicroBitBLEManager::idleTick()
+{
+    if (ble)
+        ble->disconnect(pairingHandle, Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF);
+
+    fiber_remove_idle_component(this);
+}
+
+/**
+ * Enter pairing mode. This is mode is called to initiate pairing, and to enable FOTA programming
+ * of the micro:bit in cases where BLE is disabled during normal operation.
+ *
+ * @param display An instance of MicroBitDisplay used when displaying pairing information.
+ * @param authorizationButton The button to use to authorise a pairing request.
+ *
+ * @code
+ * // initiate pairing mode
+ * bleManager.pairingMode(uBit.display, uBit.buttonA);
+ * @endcode
+ */
+void MicroBitBLEManager::pairingMode(MicroBitDisplay& display, MicroBitButton& authorisationButton)
+{
+	ManagedString namePrefix("BBC micro:bit [");
+	ManagedString namePostfix("]");
+	ManagedString BLEName = namePrefix + deviceName + namePostfix;
+
+	ManagedString msg("PAIRING MODE!");
+
+	int timeInPairingMode = 0;
+	int brightness = 255;
+	int fadeDirection = 0;
+
+    ble->gap().stopAdvertising();
+
+    // Clear the whitelist (if we have one), so that we're discoverable by all BLE devices.
+#if CONFIG_ENABLED(MICROBIT_BLE_WHITELIST)
+    BLEProtocol::Address_t addresses[MICROBIT_BLE_MAXIMUM_BONDS];
+    Gap::Whitelist_t whitelist;
+    whitelist.addresses = addresses;
+    whitelist.capacity = MICROBIT_BLE_MAXIMUM_BONDS;
+    whitelist.size = 0;
+    ble->gap().setWhitelist(whitelist);
+    ble->gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST);
+#endif
+
+	// Update the advertised name of this micro:bit to include the device name
+    ble->clearAdvertisingPayload();
+
+    ble->accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)BLEName.toCharArray(), BLEName.length());
+    ble->setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble->setAdvertisingInterval(200);
+
+    ble->gap().setAdvertisingTimeout(0);
+    ble->gap().startAdvertising();
+
+	// Stop any running animations on the display
+	display.stopAnimation();
+	display.scroll(msg);
+
+	// Display our name, visualised as a histogram in the display to aid identification.
+	showNameHistogram(display);
+
+	while(1)
+	{
+		if (pairingStatus & MICROBIT_BLE_PAIR_REQUEST)
+		{
+			timeInPairingMode = 0;
+			MicroBitImage arrow("0,0,255,0,0\n0,255,0,0,0\n255,255,255,255,255\n0,255,0,0,0\n0,0,255,0,0\n");
+			display.print(arrow,0,0,0);
+
+			if (fadeDirection == 0)
+				brightness -= MICROBIT_PAIRING_FADE_SPEED;
+			else
+				brightness += MICROBIT_PAIRING_FADE_SPEED;
+
+			if (brightness <= 40)
+				display.clear();
+
+			if (brightness <= 0)
+				fadeDirection = 1;
+
+			if (brightness >= 255)
+				fadeDirection = 0;
+
+			if (authorisationButton.isPressed())
+			{
+				pairingStatus &= ~MICROBIT_BLE_PAIR_REQUEST;
+				pairingStatus |= MICROBIT_BLE_PAIR_PASSCODE;
+			}
+		}
+
+		if (pairingStatus & MICROBIT_BLE_PAIR_PASSCODE)
+		{
+			timeInPairingMode = 0;
+			display.setBrightness(255);
+			for (int i=0; i<passKey.length(); i++)
+			{
+				display.image.print(passKey.charAt(i),0,0);
+				fiber_sleep(800);
+				display.clear();
+				fiber_sleep(200);
+
+				if (pairingStatus & MICROBIT_BLE_PAIR_COMPLETE)
+					break;
+			}
+
+			fiber_sleep(1000);
+		}
+
+		if (pairingStatus & MICROBIT_BLE_PAIR_COMPLETE)
+		{
+			if (pairingStatus & MICROBIT_BLE_PAIR_SUCCESSFUL)
+			{
+				MicroBitImage tick("0,0,0,0,0\n0,0,0,0,255\n0,0,0,255,0\n255,0,255,0,0\n0,255,0,0,0\n");
+				display.print(tick,0,0,0);
+                fiber_sleep(15000);
+		        timeInPairingMode = MICROBIT_BLE_PAIRING_TIMEOUT * 30;
+
+                /*
+                 * Disabled, as the API to return the number of active bonds is not reliable at present...
+                 *
+                display.clear();
+                ManagedString c(getBondCount());
+                ManagedString c2("/");
+                ManagedString c3(MICROBIT_BLE_MAXIMUM_BONDS);
+                ManagedString c4("USED");
+
+                display.scroll(c+c2+c3+c4);
+                *
+                *
+                */
+			}
+			else
+			{
+				MicroBitImage cross("255,0,0,0,255\n0,255,0,255,0\n0,0,255,0,0\n0,255,0,255,0\n255,0,0,0,255\n");
+				display.print(cross,0,0,0);
+			}
+		}
+
+		fiber_sleep(100);
+		timeInPairingMode++;
+
+		if (timeInPairingMode >= MICROBIT_BLE_PAIRING_TIMEOUT * 30)
+			microbit_reset();
+	}
+}
+
+/**
+ * Displays the device's ID code as a histogram on the provided MicroBitDisplay instance.
+ *
+ * @param display The display instance used for displaying the histogram.
+ */
+void MicroBitBLEManager::showNameHistogram(MicroBitDisplay &display)
+{
+    uint32_t n = NRF_FICR->DEVICEID[1];
+    int ld = 1;
+    int d = MICROBIT_DFU_HISTOGRAM_HEIGHT;
+    int h;
+
+    display.clear();
+    for (int i=0; i<MICROBIT_DFU_HISTOGRAM_WIDTH;i++)
+    {
+        h = (n % d) / ld;
+
+        n -= h;
+        d *= MICROBIT_DFU_HISTOGRAM_HEIGHT;
+        ld *= MICROBIT_DFU_HISTOGRAM_HEIGHT;
+
+        for (int j=0; j<h+1; j++)
+            display.image.setPixelValue(MICROBIT_DFU_HISTOGRAM_WIDTH-i-1, MICROBIT_DFU_HISTOGRAM_HEIGHT-j-1, 255);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitButtonService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,143 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit Button Service.
+  * Provides a BLE service to remotely read the state of each button, and configure its behaviour.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitButtonService.h"
+#include "MicroBitButton.h"
+
+/**
+  * Constructor.
+  * Create a representation of the ButtonService
+  * @param _ble The instance of a BLE device that we're running on.
+  */
+MicroBitButtonService::MicroBitButtonService(BLEDevice &_ble) :
+        ble(_ble)
+{
+    // Create the data structures that represent each of our characteristics in Soft Device.
+    GattCharacteristic  buttonADataCharacteristic(MicroBitButtonAServiceDataUUID, (uint8_t *)&buttonADataCharacteristicBuffer, 0,
+    sizeof(buttonADataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  buttonBDataCharacteristic(MicroBitButtonBServiceDataUUID, (uint8_t *)&buttonBDataCharacteristicBuffer, 0,
+    sizeof(buttonBDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+
+    // Initialise our characteristic values.
+    buttonADataCharacteristicBuffer = 0;
+    buttonBDataCharacteristicBuffer = 0;
+
+    // Set default security requirements
+    buttonADataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    buttonBDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&buttonADataCharacteristic, &buttonBDataCharacteristic};
+    GattService         service(MicroBitButtonServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    buttonADataCharacteristicHandle = buttonADataCharacteristic.getValueHandle();
+    buttonBDataCharacteristicHandle = buttonBDataCharacteristic.getValueHandle();
+
+    ble.gattServer().write(buttonADataCharacteristicHandle,(uint8_t *)&buttonADataCharacteristicBuffer, sizeof(buttonADataCharacteristicBuffer));
+    ble.gattServer().write(buttonBDataCharacteristicHandle,(uint8_t *)&buttonBDataCharacteristicBuffer, sizeof(buttonBDataCharacteristicBuffer));
+
+    if (EventModel::defaultEventBus)
+    {
+        EventModel::defaultEventBus->listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, this, &MicroBitButtonService::buttonAUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
+        EventModel::defaultEventBus->listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, this, &MicroBitButtonService::buttonBUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
+    }
+}
+
+
+/**
+  * Button B update callback
+  */
+void MicroBitButtonService::buttonAUpdate(MicroBitEvent e)
+{
+    if (ble.getGapState().connected)
+    {
+        if (e.value == MICROBIT_BUTTON_EVT_UP)
+        {
+            buttonADataCharacteristicBuffer = 0;
+            ble.gattServer().notify(buttonADataCharacteristicHandle,(uint8_t *)&buttonADataCharacteristicBuffer, sizeof(buttonADataCharacteristicBuffer));
+        }
+
+        if (e.value == MICROBIT_BUTTON_EVT_DOWN)
+        {
+            buttonADataCharacteristicBuffer = 1;
+            ble.gattServer().notify(buttonADataCharacteristicHandle,(uint8_t *)&buttonADataCharacteristicBuffer, sizeof(buttonADataCharacteristicBuffer));
+        }
+
+        if (e.value == MICROBIT_BUTTON_EVT_HOLD)
+        {
+            buttonADataCharacteristicBuffer = 2;
+            ble.gattServer().notify(buttonADataCharacteristicHandle,(uint8_t *)&buttonADataCharacteristicBuffer, sizeof(buttonADataCharacteristicBuffer));
+        }
+    }
+}
+
+/**
+  * Button A update callback
+  */
+void MicroBitButtonService::buttonBUpdate(MicroBitEvent e)
+{
+    if (ble.getGapState().connected)
+    {
+        if (e.value == MICROBIT_BUTTON_EVT_UP)
+        {
+            buttonBDataCharacteristicBuffer = 0;
+            ble.gattServer().notify(buttonBDataCharacteristicHandle,(uint8_t *)&buttonBDataCharacteristicBuffer, sizeof(buttonBDataCharacteristicBuffer));
+        }
+
+        if (e.value == MICROBIT_BUTTON_EVT_DOWN)
+        {
+            buttonBDataCharacteristicBuffer = 1;
+            ble.gattServer().notify(buttonBDataCharacteristicHandle,(uint8_t *)&buttonBDataCharacteristicBuffer, sizeof(buttonBDataCharacteristicBuffer));
+        }
+
+        if (e.value == MICROBIT_BUTTON_EVT_HOLD)
+        {
+            buttonBDataCharacteristicBuffer = 2;
+            ble.gattServer().notify(buttonBDataCharacteristicHandle,(uint8_t *)&buttonBDataCharacteristicBuffer, sizeof(buttonBDataCharacteristicBuffer));
+        }
+    }
+}
+
+const uint8_t  MicroBitButtonServiceUUID[] = {
+    0xe9,0x5d,0x98,0x82,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitButtonAServiceDataUUID[] = {
+    0xe9,0x5d,0xda,0x90,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+}
+;
+const uint8_t  MicroBitButtonBServiceDataUUID[] = {
+    0xe9,0x5d,0xda,0x91,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitDFUService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,137 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+ * Class definition for a MicroBit Device Firmware Update loader.
+ *
+ * This is actually just a frontend to a memory resident nordic DFU loader.
+ *
+ * We rely on the BLE standard pairing processes to provide encryption and authentication.
+ * We assume any device that is paied with the micro:bit is authorized to reprogram the device.
+ *
+ */
+#include "MicroBitConfig.h"
+#include "MicroBitDFUService.h"
+#include "ble/UUID.h"
+#include "MicroBitConfig.h"
+
+#if !defined(__arm)
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+/*
+ * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+extern "C" {
+#include "dfu_app_handler.h"
+}
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic pop
+#endif
+
+
+/**
+  * Constructor.
+  * Initialise the Device Firmware Update service.
+  * @param _ble The instance of a BLE device that we're running on.
+  */
+MicroBitDFUService::MicroBitDFUService(BLEDevice &_ble) :
+    ble(_ble)
+{
+    // Opcodes can be issued here to control the MicroBitDFU Service, as defined above.
+    GattCharacteristic  microBitDFUServiceControlCharacteristic(MicroBitDFUServiceControlCharacteristicUUID, &controlByte, 0, sizeof(uint8_t),
+            GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    controlByte = 0x00;
+
+    // Set default security requirements
+    microBitDFUServiceControlCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&microBitDFUServiceControlCharacteristic};
+    GattService         service(MicroBitDFUServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    microBitDFUServiceControlCharacteristicHandle = microBitDFUServiceControlCharacteristic.getValueHandle();
+
+    ble.gattServer().write(microBitDFUServiceControlCharacteristicHandle, &controlByte, sizeof(uint8_t));
+    ble.gattServer().onDataWritten(this, &MicroBitDFUService::onDataWritten);
+}
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitDFUService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    if (params->handle == microBitDFUServiceControlCharacteristicHandle)
+    {
+        if(params->len > 0 && params->data[0] == MICROBIT_DFU_OPCODE_START_DFU)
+        {
+            // TODO: Raise a SYSTEM event here.
+            //uBit.display.stopAnimation();
+            //uBit.display.clear();
+
+#if CONFIG_ENABLED(MICROBIT_DBG)
+            printf("  ACTIVATING BOOTLOADER.\n");
+#endif
+
+            // Perform an explicit disconnection to assist our peer to reconnect to the DFU service
+            ble.disconnect(Gap::REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF);
+
+            wait_ms(1000);
+
+            // Call bootloader_start implicitly trough a event handler call
+            // it is a work around for bootloader_start not being public in sdk 8.1
+            ble_dfu_t p_dfu;
+            ble_dfu_evt_t p_evt;
+
+            p_dfu.conn_handle = params->connHandle;
+            p_evt.ble_dfu_evt_type = BLE_DFU_START;
+
+            dfu_app_on_dfu_evt(&p_dfu, &p_evt);
+        }
+    }
+}
+
+
+/**
+  * UUID definitions for BLE Services and Characteristics.
+  */
+const uint8_t              MicroBitDFUServiceUUID[] = {
+    0xe9,0x5d,0x93,0xb0,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t              MicroBitDFUServiceControlCharacteristicUUID[] = {
+    0xe9,0x5d,0x93,0xb1,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitEventService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,188 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a MicroBit BLE Event Service.
+  * Provides a BLE gateway onto an Event Model.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitEventService.h"
+#include "ble/UUID.h"
+#include "ExternalEvents.h"
+#include "MicroBitFiber.h"
+
+/**
+  * Constructor.
+  * Create a representation of the EventService
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _messageBus An instance of an EventModel which events will be mirrored from.
+  */
+MicroBitEventService::MicroBitEventService(BLEDevice &_ble, EventModel &_messageBus) :
+        ble(_ble),messageBus(_messageBus)
+{
+    GattCharacteristic  microBitEventCharacteristic(MicroBitEventServiceMicroBitEventCharacteristicUUID, (uint8_t *)&microBitEventBuffer, 0, sizeof(EventServiceEvent),
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  clientEventCharacteristic(MicroBitEventServiceClientEventCharacteristicUUID, (uint8_t *)&clientEventBuffer, 0, sizeof(EventServiceEvent),
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    GattCharacteristic  clientRequirementsCharacteristic(MicroBitEventServiceClientRequirementsCharacteristicUUID, (uint8_t *)&clientRequirementsBuffer, 0, sizeof(EventServiceEvent), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    microBitRequirementsCharacteristic = new GattCharacteristic(MicroBitEventServiceMicroBitRequirementsCharacteristicUUID, (uint8_t *)&microBitRequirementsBuffer, 0, sizeof(EventServiceEvent), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    microBitRequirementsCharacteristic->setReadAuthorizationCallback(this, &MicroBitEventService::onRequirementsRead);
+
+    clientEventBuffer.type = 0x00;
+    clientEventBuffer.reason = 0x00;
+
+    microBitEventBuffer = microBitRequirementsBuffer = clientRequirementsBuffer = clientEventBuffer;
+
+    messageBusListenerOffset = 0;
+
+    // Set default security requirements
+    microBitEventCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    clientEventCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    clientRequirementsCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    microBitRequirementsCharacteristic->requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&microBitEventCharacteristic, &clientEventCharacteristic, &clientRequirementsCharacteristic, microBitRequirementsCharacteristic};
+    GattService         service(MicroBitEventServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    microBitEventCharacteristicHandle = microBitEventCharacteristic.getValueHandle();
+    clientEventCharacteristicHandle = clientEventCharacteristic.getValueHandle();
+    clientRequirementsCharacteristicHandle = clientRequirementsCharacteristic.getValueHandle();
+
+    ble.onDataWritten(this, &MicroBitEventService::onDataWritten);
+
+    fiber_add_idle_component(this);
+}
+
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitEventService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    int len = params->len;
+    EventServiceEvent *e = (EventServiceEvent *)params->data;
+
+    if (params->handle == clientEventCharacteristicHandle) {
+
+        // Read and fire all events...
+        while (len >= 4)
+        {
+            MicroBitEvent evt(e->type, e->reason);
+            len-=4;
+            e++;
+        }
+        return;
+    }
+
+    if (params->handle == clientRequirementsCharacteristicHandle) {
+        // Read and register for all the events given...
+        while (len >= 4)
+        {
+            messageBus.listen(e->type, e->reason, this, &MicroBitEventService::onMicroBitEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
+
+            len-=4;
+            e++;
+        }
+        return;
+    }
+}
+
+/**
+  * Callback. Invoked when any events are sent on the microBit message bus.
+  */
+void MicroBitEventService::onMicroBitEvent(MicroBitEvent evt)
+{
+    EventServiceEvent *e = &microBitEventBuffer;
+
+    if (ble.getGapState().connected) {
+        e->type = evt.source;
+        e->reason = evt.value;
+
+        ble.gattServer().notify(microBitEventCharacteristicHandle, (const uint8_t *)e, sizeof(EventServiceEvent));
+    }
+}
+
+/**
+  * Periodic callback from MicroBit scheduler.
+  * If we're no longer connected, remove any registered Message Bus listeners.
+  */
+void MicroBitEventService::idleTick()
+{
+    if (!ble.getGapState().connected && messageBusListenerOffset >0) {
+        messageBusListenerOffset = 0;
+        messageBus.ignore(MICROBIT_ID_ANY, MICROBIT_EVT_ANY, this, &MicroBitEventService::onMicroBitEvent);
+    }
+}
+
+/**
+  * Read callback on microBitRequirements characteristic.
+  *
+  * Used to iterate through the events that the code on this micro:bit is interested in.
+  */
+void MicroBitEventService::onRequirementsRead(GattReadAuthCallbackParams *params)
+{
+    if (params->handle == microBitRequirementsCharacteristic->getValueHandle())
+    {
+        // Walk through the lsit of message bus listeners.
+        // We send one at a time, and our client can keep reading from this characterisitic until we return an emtpy value.
+        MicroBitListener *l = messageBus.elementAt(messageBusListenerOffset++);
+
+        if (l != NULL)
+        {
+            microBitRequirementsBuffer.type = l->id;
+            microBitRequirementsBuffer.reason = l->value;
+            ble.gattServer().write(microBitRequirementsCharacteristic->getValueHandle(), (uint8_t *)&microBitRequirementsBuffer, sizeof(EventServiceEvent));
+        } else {
+            ble.gattServer().write(microBitRequirementsCharacteristic->getValueHandle(), (uint8_t *)&microBitRequirementsBuffer, 0);
+        }
+    }
+}
+
+const uint8_t  MicroBitEventServiceUUID[] = {
+    0xe9,0x5d,0x93,0xaf,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitEventServiceMicroBitEventCharacteristicUUID[] = {
+    0xe9,0x5d,0x97,0x75,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitEventServiceClientEventCharacteristicUUID[] = {
+    0xe9,0x5d,0x54,0x04,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitEventServiceMicroBitRequirementsCharacteristicUUID[] = {
+    0xe9,0x5d,0xb8,0x4c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitEventServiceClientRequirementsCharacteristicUUID[] = {
+    0xe9,0x5d,0x23,0xc4,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitIOPinService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,330 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit IOPin Service.
+  * Provides a BLE service to remotely read the state of the I/O Pin, and configure its behaviour.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitIOPinService.h"
+#include "MicroBitFiber.h"
+
+/**
+  * Constructor.
+  * Create a representation of the IOPinService
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _io An instance of MicroBitIO that this service will use to perform
+  *            I/O operations.
+  */
+MicroBitIOPinService::MicroBitIOPinService(BLEDevice &_ble, MicroBitIO &_io) :
+        ble(_ble), io(_io)
+{
+    // Create the AD characteristic, that defines whether each pin is treated as analogue or digital
+    GattCharacteristic ioPinServiceADCharacteristic(MicroBitIOPinServiceADConfigurationUUID, (uint8_t *)&ioPinServiceADCharacteristicBuffer, 0, sizeof(ioPinServiceADCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    // Create the IO characteristic, that defines whether each pin is treated as input or output
+    GattCharacteristic ioPinServiceIOCharacteristic(MicroBitIOPinServiceIOConfigurationUUID, (uint8_t *)&ioPinServiceIOCharacteristicBuffer, 0, sizeof(ioPinServiceIOCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    // Create the Data characteristic, that allows the actual read and write operations.
+    ioPinServiceDataCharacteristic = new GattCharacteristic(MicroBitIOPinServiceDataUUID, (uint8_t *)ioPinServiceDataCharacteristicBuffer, 0, sizeof(ioPinServiceDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    ioPinServiceDataCharacteristic->setReadAuthorizationCallback(this, &MicroBitIOPinService::onDataRead);
+
+    ioPinServiceADCharacteristicBuffer = 0;
+    ioPinServiceIOCharacteristicBuffer = 0;
+    memset(ioPinServiceIOData, 0, sizeof(ioPinServiceIOData));
+
+    // Set default security requirements
+    ioPinServiceADCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    ioPinServiceIOCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    ioPinServiceDataCharacteristic->requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&ioPinServiceADCharacteristic, &ioPinServiceIOCharacteristic, ioPinServiceDataCharacteristic};
+    GattService         service(MicroBitIOPinServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    ioPinServiceADCharacteristicHandle = ioPinServiceADCharacteristic.getValueHandle();
+    ioPinServiceIOCharacteristicHandle = ioPinServiceIOCharacteristic.getValueHandle();
+
+    ble.gattServer().write(ioPinServiceADCharacteristicHandle, (const uint8_t *)&ioPinServiceADCharacteristicBuffer, sizeof(ioPinServiceADCharacteristicBuffer));
+    ble.gattServer().write(ioPinServiceIOCharacteristicHandle, (const uint8_t *)&ioPinServiceIOCharacteristicBuffer, sizeof(ioPinServiceIOCharacteristicBuffer));
+
+    ble.onDataWritten(this, &MicroBitIOPinService::onDataWritten);
+    fiber_add_idle_component(this);
+}
+
+/**
+  * Determines if the given pin was configured as a digital pin by the BLE ADPinConfigurationCharacterisitic.
+  *
+  * @param i the enumeration of the pin to test
+  * @return 1 if this pin is configured as digital, 0 otherwise
+  */
+int MicroBitIOPinService::isDigital(int i)
+{
+    return ((ioPinServiceADCharacteristicBuffer & (1 << i)) == 0);
+}
+
+/**
+  * Determines if the given pin was configured as an analog pin by the BLE ADPinConfigurationCharacterisitic.
+  *
+  * @param i the enumeration of the pin to test
+  * @return 1 if this pin is configured as analog, 0 otherwise
+  */
+int MicroBitIOPinService::isAnalog(int i)
+{
+    return ((ioPinServiceADCharacteristicBuffer & (1 << i)) != 0);
+}
+
+/**
+  * Determines if the given pin was configured as an input by the BLE IOPinConfigurationCharacterisitic.
+  *
+  * @param i the enumeration of the pin to test
+  * @return 1 if this pin is configured as an input, 0 otherwise
+  */
+int MicroBitIOPinService::isInput(int i)
+{
+    return ((ioPinServiceIOCharacteristicBuffer & (1 << i)) != 0);
+}
+
+/**
+  * Determines if the given pin was configured as output by the BLE IOPinConfigurationCharacterisitic.
+  *
+  * @param i the enumeration of the pin to test
+  * @return 1 if this pin is configured as an output, 0 otherwise
+  */
+int MicroBitIOPinService::isOutput(int i)
+{
+    return ((ioPinServiceIOCharacteristicBuffer & (1 << i)) == 0);
+}
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitIOPinService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    // Check for writes to the IO configuration characteristic
+    if (params->handle == ioPinServiceIOCharacteristicHandle && params->len >= sizeof(ioPinServiceIOCharacteristicBuffer))
+    {
+        uint32_t *value = (uint32_t *)params->data;
+
+        // Our IO configuration may be changing... read the new value, and push it back into the BLE stack.
+        ioPinServiceIOCharacteristicBuffer = *value;
+        ble.gattServer().write(ioPinServiceIOCharacteristicHandle, (const uint8_t *)&ioPinServiceIOCharacteristicBuffer, sizeof(ioPinServiceIOCharacteristicBuffer));
+
+        // Also, drop any selected pins into input mode, so we can pick up changes later
+        for (int i=0; i < MICROBIT_IO_PIN_SERVICE_PINCOUNT; i++)
+        {
+            if(isDigital(i) && isInput(i))
+               io.pin[i].getDigitalValue();
+               //MicroBitIOPins[i]->getDigitalValue();
+
+            if(isAnalog(i) && isInput(i))
+               io.pin[i].getAnalogValue();
+               //MicroBitIOPins[i]->getAnalogValue();
+        }
+    }
+
+    // Check for writes to the IO configuration characteristic
+    if (params->handle == ioPinServiceADCharacteristicHandle && params->len >= sizeof(ioPinServiceADCharacteristicBuffer))
+    {
+        uint32_t *value = (uint32_t *)params->data;
+
+        // Our IO configuration may be changing... read the new value, and push it back into the BLE stack.
+        ioPinServiceADCharacteristicBuffer = *value;
+        ble.gattServer().write(ioPinServiceADCharacteristicHandle, (const uint8_t *)&ioPinServiceADCharacteristicBuffer, sizeof(ioPinServiceADCharacteristicBuffer));
+
+        // Also, drop any selected pins into input mode, so we can pick up changes later
+        for (int i=0; i < MICROBIT_IO_PIN_SERVICE_PINCOUNT; i++)
+        {
+            if(isDigital(i) && isInput(i))
+               io.pin[i].getDigitalValue();
+               //MicroBitIOPins[i]->getDigitalValue();
+
+            if(isAnalog(i) && isInput(i))
+               io.pin[i].getAnalogValue();
+               //MicroBitIOPins[i]->getAnalogValue();
+        }
+    }
+
+    if (params->handle == ioPinServiceDataCharacteristic->getValueHandle())
+    {
+        // We have some pin data to change...
+        uint16_t len = params->len;
+        IOData *data = (IOData *)params->data;
+
+        // There may be multiple write operaitons... take each in turn and update the pin values
+        while (len >= sizeof(IOData))
+        {
+            if (isOutput(data->pin))
+            {
+                if (isDigital(data->pin))
+               		io.pin[data->pin].setDigitalValue(data->value);
+                    //MicroBitIOPins[data->pin]->setDigitalValue(data->value);
+                else
+               		io.pin[data->pin].setAnalogValue(data->value*4);
+                    //MicroBitIOPins[data->pin]->setAnalogValue(data->value*4);
+            }
+
+            data++;
+            len -= sizeof(IOData);
+        }
+    }
+}
+
+/**
+ * Callback. invoked when the BLE data characteristic is read.
+ *
+ * Reads all the pins marked as inputs, and updates the data stored in the characteristic.
+ */
+void MicroBitIOPinService::onDataRead(GattReadAuthCallbackParams *params)
+{
+    if (params->handle == ioPinServiceDataCharacteristic->getValueHandle())
+    {
+
+        // Scan through all pins that our BLE client may be listening for. If any have changed value, update the BLE characterisitc, and NOTIFY our client.
+        int pairs = 0;
+
+        for (int i=0; i < MICROBIT_IO_PIN_SERVICE_PINCOUNT; i++)
+        {
+            if (isInput(i))
+            {
+                uint8_t value;
+
+                if (isDigital(i))
+               		value = io.pin[i].getDigitalValue();
+                    //value = MicroBitIOPins[i]->getDigitalValue();
+                else
+               		value = io.pin[i].getAnalogValue();
+                    //value = MicroBitIOPins[i]->getAnalogValue();
+
+                ioPinServiceIOData[i] = value;
+                ioPinServiceDataCharacteristicBuffer[pairs].pin = i;
+                ioPinServiceDataCharacteristicBuffer[pairs].value = value;
+
+                pairs++;
+
+                if (pairs >= MICROBIT_IO_PIN_SERVICE_DATA_SIZE)
+                    break;
+            }
+        }
+
+        // If there's any data, issue a BLE notification.
+        if (pairs > 0)
+            ble.gattServer().notify(ioPinServiceDataCharacteristic->getValueHandle(), (uint8_t *)ioPinServiceDataCharacteristicBuffer, pairs * sizeof(IOData));
+    }
+}
+
+
+/**
+ * Periodic callback from MicroBit scheduler.
+ *
+ * Check if any of the pins we're watching need updating. Notify any connected
+ * device with any changes.
+ */
+void MicroBitIOPinService::idleTick()
+{
+    // If we're not we're connected, then there's nothing to do...
+    if (!ble.getGapState().connected)
+        return;
+
+    // Scan through all pins that our BLE client may be listening for. If any have changed value, update the BLE characterisitc, and NOTIFY our client.
+    int pairs = 0;
+
+    for (int i=0; i < MICROBIT_IO_PIN_SERVICE_PINCOUNT; i++)
+    {
+        if (isInput(i))
+        {
+            uint8_t value;
+
+            if (isDigital(i))
+               	value = io.pin[i].getDigitalValue();
+                //value = MicroBitIOPins[i]->getDigitalValue();
+            else
+               	value = io.pin[i].getAnalogValue();
+                //value = MicroBitIOPins[i]->getAnalogValue();
+
+            // If the data has changed, send an update.
+            if (value != ioPinServiceIOData[i])
+            {
+                ioPinServiceIOData[i] = value;
+
+                ioPinServiceDataCharacteristicBuffer[pairs].pin = i;
+                ioPinServiceDataCharacteristicBuffer[pairs].value = value;
+
+                pairs++;
+
+                if (pairs >= MICROBIT_IO_PIN_SERVICE_DATA_SIZE)
+                    break;
+            }
+        }
+    }
+
+    // If there were any changes, issue a BLE notification.
+    if (pairs > 0)
+        ble.gattServer().notify(ioPinServiceDataCharacteristic->getValueHandle(), (uint8_t *)ioPinServiceDataCharacteristicBuffer, pairs * sizeof(IOData));
+}
+
+const uint8_t  MicroBitIOPinServiceUUID[] = {
+    0xe9,0x5d,0x12,0x7b,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitIOPinServiceIOConfigurationUUID[] = {
+    0xe9,0x5d,0xb9,0xfe,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitIOPinServiceADConfigurationUUID[] = {
+    0xe9,0x5d,0x58,0x99,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t MicroBitIOPinServiceDataUUID[] = {
+    0xe9,0x5d,0x8d,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+/*
+MicroBitPin * const MicroBitIOPins[] = {
+    &uBit.io.P0,
+    &uBit.io.P1,
+    &uBit.io.P2,
+    &uBit.io.P3,
+    &uBit.io.P4,
+    &uBit.io.P5,
+    &uBit.io.P6,
+    &uBit.io.P7,
+    &uBit.io.P8,
+    &uBit.io.P9,
+    &uBit.io.P10,
+    &uBit.io.P11,
+    &uBit.io.P12,
+    &uBit.io.P13,
+    &uBit.io.P14,
+    &uBit.io.P15,
+    &uBit.io.P16,
+    &uBit.io.P19,
+    &uBit.io.P20
+};
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitLEDService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,150 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit LED Service.
+  * Provides a BLE service to remotely read and write the state of the LED display.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitLEDService.h"
+
+/**
+  * Constructor.
+  * Create a representation of the LEDService
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _display An instance of MicroBitDisplay to interface with.
+  */
+MicroBitLEDService::MicroBitLEDService(BLEDevice &_ble, MicroBitDisplay &_display) :
+        ble(_ble), display(_display),
+        matrixCharacteristic(MicroBitLEDServiceMatrixUUID, (uint8_t *)&matrixCharacteristicBuffer, 0, sizeof(matrixCharacteristicBuffer),
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)
+{
+    // Create the data structures that represent each of our characteristics in Soft Device.
+    GattCharacteristic  textCharacteristic(MicroBitLEDServiceTextUUID, (uint8_t *)textCharacteristicBuffer, 0, MICROBIT_BLE_MAXIMUM_SCROLLTEXT,
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    GattCharacteristic  scrollingSpeedCharacteristic(MicroBitLEDServiceScrollingSpeedUUID, (uint8_t *)&scrollingSpeedCharacteristicBuffer, 0,
+    sizeof(scrollingSpeedCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+
+    // Initialise our characteristic values.
+    memclr(matrixCharacteristicBuffer, sizeof(matrixCharacteristicBuffer));
+    textCharacteristicBuffer[0] = 0;
+    scrollingSpeedCharacteristicBuffer = MICROBIT_DEFAULT_SCROLL_SPEED;
+
+    matrixCharacteristic.setReadAuthorizationCallback(this, &MicroBitLEDService::onDataRead);
+
+    // Set default security requirements
+    matrixCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    textCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    scrollingSpeedCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&matrixCharacteristic, &textCharacteristic, &scrollingSpeedCharacteristic};
+    GattService         service(MicroBitLEDServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    matrixCharacteristicHandle = matrixCharacteristic.getValueHandle();
+    textCharacteristicHandle = textCharacteristic.getValueHandle();
+    scrollingSpeedCharacteristicHandle = scrollingSpeedCharacteristic.getValueHandle();
+
+    ble.gattServer().write(scrollingSpeedCharacteristicHandle, (const uint8_t *)&scrollingSpeedCharacteristicBuffer, sizeof(scrollingSpeedCharacteristicBuffer));
+    ble.gattServer().write(matrixCharacteristicHandle, (const uint8_t *)&matrixCharacteristicBuffer, sizeof(matrixCharacteristicBuffer));
+
+    ble.onDataWritten(this, &MicroBitLEDService::onDataWritten);
+}
+
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitLEDService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    uint8_t *data = (uint8_t *)params->data;
+
+    if (params->handle == matrixCharacteristicHandle && params->len > 0 && params->len < 6)
+    {
+        for (int y=0; y<params->len; y++)
+            for (int x=0; x<5; x++)
+                display.image.setPixelValue(x, y, (data[y] & (0x01 << (4-x))) ? 255 : 0);
+    }
+
+    else if (params->handle == textCharacteristicHandle)
+    {
+        // Create a ManagedString representation from the UTF8 data.
+        // We do this explicitly to control the length (in case the string is not NULL terminated!)
+        ManagedString s((char *)params->data, params->len);
+
+        // Start the string scrolling and we're done.
+        display.scrollAsync(s, (int) scrollingSpeedCharacteristicBuffer);
+    }
+
+    else if (params->handle == scrollingSpeedCharacteristicHandle && params->len >= sizeof(scrollingSpeedCharacteristicBuffer))
+    {
+        // Read the speed requested, and store it locally.
+        // We use this as the speed for all scroll operations subsquently initiated from BLE.
+        scrollingSpeedCharacteristicBuffer = *((uint16_t *)params->data);
+    }
+}
+
+/**
+  * Callback. Invoked when any of our attributes are read via BLE.
+  */
+void MicroBitLEDService::onDataRead(GattReadAuthCallbackParams *params)
+{
+    if (params->handle == matrixCharacteristicHandle)
+    {
+        for (int y=0; y<5; y++)
+        {
+            matrixCharacteristicBuffer[y] = 0;
+
+            for (int x=0; x<5; x++)
+            {
+                if (display.image.getPixelValue(x, y))
+                    matrixCharacteristicBuffer[y] |= 0x01 << (4-x);
+            }
+        }
+
+        ble.gattServer().write(matrixCharacteristicHandle, (const uint8_t *)&matrixCharacteristicBuffer, sizeof(matrixCharacteristicBuffer));
+    }
+}
+
+
+const uint8_t  MicroBitLEDServiceUUID[] = {
+    0xe9,0x5d,0xd9,0x1d,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitLEDServiceMatrixUUID[] = {
+    0xe9,0x5d,0x7b,0x77,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitLEDServiceTextUUID[] = {
+    0xe9,0x5d,0x93,0xee,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitLEDServiceScrollingSpeedUUID[] = {
+    0xe9,0x5d,0x0d,0x2d,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitMagnetometerService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,156 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the MicroBit BLE Magnetometer Service.
+  * Provides access to live magnetometer data via BLE, and provides basic configuration options.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitMagnetometerService.h"
+
+/**
+  * Constructor.
+  * Create a representation of the MagnetometerService.
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _compass An instance of MicroBitCompass to use as our Magnetometer source.
+  */
+MicroBitMagnetometerService::MicroBitMagnetometerService(BLEDevice &_ble, MicroBitCompass &_compass) :
+        ble(_ble), compass(_compass)
+{
+    // Create the data structures that represent each of our characteristics in Soft Device.
+    GattCharacteristic  magnetometerDataCharacteristic(MicroBitMagnetometerServiceDataUUID, (uint8_t *)magnetometerDataCharacteristicBuffer, 0,
+    sizeof(magnetometerDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  magnetometerBearingCharacteristic(MicroBitMagnetometerServiceBearingUUID, (uint8_t *)&magnetometerBearingCharacteristicBuffer, 0,
+    sizeof(magnetometerBearingCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  magnetometerPeriodCharacteristic(MicroBitMagnetometerServicePeriodUUID, (uint8_t *)&magnetometerPeriodCharacteristicBuffer, 0,
+    sizeof(magnetometerPeriodCharacteristicBuffer),
+    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    // Initialise our characteristic values.
+    magnetometerDataCharacteristicBuffer[0] = 0;
+    magnetometerDataCharacteristicBuffer[1] = 0;
+    magnetometerDataCharacteristicBuffer[2] = 0;
+    magnetometerBearingCharacteristicBuffer = 0;
+    magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
+
+    // Set default security requirements
+    magnetometerDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    magnetometerBearingCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    magnetometerPeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&magnetometerDataCharacteristic, &magnetometerBearingCharacteristic, &magnetometerPeriodCharacteristic};
+    GattService         service(MicroBitMagnetometerServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    magnetometerDataCharacteristicHandle = magnetometerDataCharacteristic.getValueHandle();
+    magnetometerBearingCharacteristicHandle = magnetometerBearingCharacteristic.getValueHandle();
+    magnetometerPeriodCharacteristicHandle = magnetometerPeriodCharacteristic.getValueHandle();
+
+    ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
+    ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer));
+    ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
+
+    ble.onDataWritten(this, &MicroBitMagnetometerService::onDataWritten);
+    if (EventModel::defaultEventBus)
+    {
+        EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_DATA_UPDATE, this, &MicroBitMagnetometerService::magnetometerUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
+        EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED, this, &MicroBitMagnetometerService::samplePeriodUpdateNeeded);
+    }
+}
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitMagnetometerService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    if (params->handle == magnetometerPeriodCharacteristicHandle && params->len >= sizeof(magnetometerPeriodCharacteristicBuffer))
+    {
+        magnetometerPeriodCharacteristicBuffer = *((uint16_t *)params->data);
+        MicroBitEvent evt(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED);
+    }
+}
+
+/**
+  * Magnetometer update callback
+  */
+void MicroBitMagnetometerService::magnetometerUpdate(MicroBitEvent)
+{
+    if (ble.getGapState().connected)
+    {
+        magnetometerDataCharacteristicBuffer[0] = compass.getX();
+        magnetometerDataCharacteristicBuffer[1] = compass.getY();
+        magnetometerDataCharacteristicBuffer[2] = compass.getZ();
+        magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
+
+        ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
+        ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
+
+        if (compass.isCalibrated())
+        {
+            magnetometerBearingCharacteristicBuffer = (uint16_t) compass.heading();
+            ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer));
+        }
+    }
+}
+
+/**
+ * Sample Period Change Needed callback.
+ * Reconfiguring the magnetometer can to a REALLY long time (sometimes even seconds to complete)
+ * So we do this in the background when necessary, through this event handler.
+ */
+void MicroBitMagnetometerService::samplePeriodUpdateNeeded(MicroBitEvent)
+{
+    // Reconfigure the compass. This might take a while...
+    compass.setPeriod(magnetometerPeriodCharacteristicBuffer);
+
+    // The compass will choose the nearest sample period to that we've specified.
+    // Read the ACTUAL sample period back.
+    magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
+
+    // Ensure this is reflected in our BLE connection.
+    ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
+
+}
+
+const uint8_t  MicroBitMagnetometerServiceUUID[] = {
+    0xe9,0x5d,0xf2,0xd8,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitMagnetometerServiceDataUUID[] = {
+    0xe9,0x5d,0xfb,0x11,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitMagnetometerServicePeriodUUID[] = {
+    0xe9,0x5d,0x38,0x6c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitMagnetometerServiceBearingUUID[] = {
+    0xe9,0x5d,0x97,0x15,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitTemperatureService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,115 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit Temperature Service.
+  * Provides a BLE service to remotely read the silicon temperature of the nRF51822.
+  */
+#include "MicroBitConfig.h"
+#include "ble/UUID.h"
+
+#include "MicroBitTemperatureService.h"
+
+/**
+  * Constructor.
+  * Create a representation of the TemperatureService
+  * @param _ble The instance of a BLE device that we're running on.
+  * @param _thermometer An instance of MicroBitThermometer to use as our temperature source.
+  */
+MicroBitTemperatureService::MicroBitTemperatureService(BLEDevice &_ble, MicroBitThermometer &_thermometer) :
+        ble(_ble), thermometer(_thermometer)
+{
+    // Create the data structures that represent each of our characteristics in Soft Device.
+    GattCharacteristic  temperatureDataCharacteristic(MicroBitTemperatureServiceDataUUID, (uint8_t *)&temperatureDataCharacteristicBuffer, 0,
+    sizeof(temperatureDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+
+    GattCharacteristic  temperaturePeriodCharacteristic(MicroBitTemperatureServicePeriodUUID, (uint8_t *)&temperaturePeriodCharacteristicBuffer, 0,
+    sizeof(temperaturePeriodCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+
+    // Initialise our characteristic values.
+    temperatureDataCharacteristicBuffer = 0;
+    temperaturePeriodCharacteristicBuffer = thermometer.getPeriod();
+
+    // Set default security requirements
+    temperatureDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+    temperaturePeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
+
+    GattCharacteristic *characteristics[] = {&temperatureDataCharacteristic, &temperaturePeriodCharacteristic};
+    GattService         service(MicroBitTemperatureServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+
+    ble.addService(service);
+
+    temperatureDataCharacteristicHandle = temperatureDataCharacteristic.getValueHandle();
+    temperaturePeriodCharacteristicHandle = temperaturePeriodCharacteristic.getValueHandle();
+
+    ble.gattServer().write(temperatureDataCharacteristicHandle,(uint8_t *)&temperatureDataCharacteristicBuffer, sizeof(temperatureDataCharacteristicBuffer));
+    ble.gattServer().write(temperaturePeriodCharacteristicHandle,(uint8_t *)&temperaturePeriodCharacteristicBuffer, sizeof(temperaturePeriodCharacteristicBuffer));
+
+    ble.onDataWritten(this, &MicroBitTemperatureService::onDataWritten);
+    if (EventModel::defaultEventBus)
+        EventModel::defaultEventBus->listen(MICROBIT_ID_THERMOMETER, MICROBIT_THERMOMETER_EVT_UPDATE, this, &MicroBitTemperatureService::temperatureUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
+}
+
+/**
+  * Temperature update callback
+  */
+void MicroBitTemperatureService::temperatureUpdate(MicroBitEvent)
+{
+    if (ble.getGapState().connected)
+    {
+        temperatureDataCharacteristicBuffer = thermometer.getTemperature();
+        ble.gattServer().notify(temperatureDataCharacteristicHandle,(uint8_t *)&temperatureDataCharacteristicBuffer, sizeof(temperatureDataCharacteristicBuffer));
+    }
+}
+
+/**
+  * Callback. Invoked when any of our attributes are written via BLE.
+  */
+void MicroBitTemperatureService::onDataWritten(const GattWriteCallbackParams *params)
+{
+    if (params->handle == temperaturePeriodCharacteristicHandle && params->len >= sizeof(temperaturePeriodCharacteristicBuffer))
+    {
+        temperaturePeriodCharacteristicBuffer = *((uint16_t *)params->data);
+        thermometer.setPeriod(temperaturePeriodCharacteristicBuffer);
+
+        // The accelerometer will choose the nearest period to that requested that it can support
+        // Read back the ACTUAL period it is using, and report this back.
+        temperaturePeriodCharacteristicBuffer = thermometer.getPeriod();
+        ble.gattServer().write(temperaturePeriodCharacteristicHandle, (const uint8_t *)&temperaturePeriodCharacteristicBuffer, sizeof(temperaturePeriodCharacteristicBuffer));
+    }
+}
+
+
+const uint8_t  MicroBitTemperatureServiceUUID[] = {
+    0xe9,0x5d,0x61,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitTemperatureServiceDataUUID[] = {
+    0xe9,0x5d,0x92,0x50,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
+
+const uint8_t  MicroBitTemperatureServicePeriodUUID[] = {
+    0xe9,0x5d,0x1b,0x25,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/bluetooth/MicroBitUARTService.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,582 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the custom MicroBit UART Service.
+  * Provides a BLE service that acts as a UART port, enabling the reception and transmission
+  * of an arbitrary number of bytes.
+  */
+
+#include "ble/UUID.h"
+
+#include "ExternalEvents.h"
+#include "MicroBitUARTService.h"
+#include "MicroBitFiber.h"
+#include "ErrorNo.h"
+#include "NotifyEvents.h"
+
+static uint8_t txBufferHead = 0;
+static uint8_t txBufferTail = 0;
+
+static GattCharacteristic* txCharacteristic = NULL;
+
+/**
+  * A callback function for whenever a Bluetooth device consumes our TX Buffer
+  */
+void on_confirmation(uint16_t handle)
+{
+    if(handle == txCharacteristic->getValueAttribute().getHandle())
+    {
+        txBufferTail = txBufferHead;
+        MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
+    }
+}
+
+/**
+ * Constructor for the UARTService.
+ * @param _ble an instance of BLEDevice
+ * @param rxBufferSize the size of the rxBuffer
+ * @param txBufferSize the size of the txBuffer
+ *
+ * @note defaults to 20
+ */
+MicroBitUARTService::MicroBitUARTService(BLEDevice &_ble, uint8_t rxBufferSize, uint8_t txBufferSize) : ble(_ble)
+{
+    rxBufferSize += 1;
+    txBufferSize += 1;
+
+    txBuffer = (uint8_t *)malloc(txBufferSize);
+    rxBuffer = (uint8_t *)malloc(rxBufferSize);
+
+    rxBufferHead = 0;
+    rxBufferTail = 0;
+    this->rxBufferSize = rxBufferSize;
+
+    txBufferHead = 0;
+    txBufferTail = 0;
+    this->txBufferSize = txBufferSize;
+
+    GattCharacteristic rxCharacteristic(UARTServiceRXCharacteristicUUID, rxBuffer, 1, rxBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
+
+    txCharacteristic = new GattCharacteristic(UARTServiceTXCharacteristicUUID, txBuffer, 1, txBufferSize, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
+
+    GattCharacteristic *charTable[] = {txCharacteristic, &rxCharacteristic};
+
+    GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+    _ble.addService(uartService);
+
+    this->rxCharacteristicHandle = rxCharacteristic.getValueAttribute().getHandle();
+
+    _ble.gattServer().onDataWritten(this, &MicroBitUARTService::onDataWritten);
+    _ble.gattServer().onConfirmationReceived(on_confirmation);
+}
+
+/**
+  * A callback function for whenever a Bluetooth device writes to our RX characteristic.
+  */
+void MicroBitUARTService::onDataWritten(const GattWriteCallbackParams *params) {
+    if (params->handle == this->rxCharacteristicHandle)
+    {
+        uint16_t bytesWritten = params->len;
+
+        for(int byteIterator = 0; byteIterator <  bytesWritten; byteIterator++)
+        {
+            int newHead = (rxBufferHead + 1) % rxBufferSize;
+
+            if(newHead != rxBufferTail)
+            {
+                char c = params->data[byteIterator];
+
+                int delimeterOffset = 0;
+                int delimLength = this->delimeters.length();
+
+                //iterate through our delimeters (if any) to see if there is a match
+                while(delimeterOffset < delimLength)
+                {
+                    //fire an event if there is to block any waiting fibers
+                    if(this->delimeters.charAt(delimeterOffset) == c)
+                        MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
+
+                    delimeterOffset++;
+                }
+
+                rxBuffer[rxBufferHead] = c;
+
+                rxBufferHead = newHead;
+
+                if(rxBufferHead == rxBuffHeadMatch)
+                {
+                    rxBuffHeadMatch = -1;
+                    MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
+                }
+            }
+            else
+                MicroBitEvent(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_RX_FULL);
+        }
+    }
+}
+
+/**
+  * An internal method that copies values from a circular buffer to a linear buffer.
+  *
+  * @param circularBuff a pointer to the source circular buffer
+  * @param circularBuffSize the size of the circular buffer
+  * @param linearBuff a pointer to the destination linear buffer
+  * @param tailPosition the tail position in the circular buffer you want to copy from
+  * @param headPosition the head position in the circular buffer you want to copy to
+  *
+  * @note this method assumes that the linear buffer has the appropriate amount of
+  *       memory to contain the copy operation
+  */
+void MicroBitUARTService::circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition)
+{
+    int toBuffIndex = 0;
+
+    while(tailPosition != headPosition)
+    {
+        linearBuff[toBuffIndex++] = circularBuff[tailPosition];
+
+        tailPosition = (tailPosition + 1) % circularBuffSize;
+    }
+}
+
+/**
+  * Retreives a single character from our RxBuffer.
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will attempt to read a single character, and return immediately
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+  *                         event is received.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, a character or MICROBIT_NO_DATA
+  */
+int MicroBitUARTService::getc(MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if(mode == ASYNC)
+    {
+        if(!isReadable())
+            return MICROBIT_NO_DATA;
+    }
+
+    if(mode == SYNC_SLEEP)
+    {
+        if(!isReadable())
+            eventAfter(1, mode);
+    }
+
+    char c = rxBuffer[rxBufferTail];
+
+    rxBufferTail = (rxBufferTail + 1) % rxBufferSize;
+
+    return c;
+}
+
+/**
+  * places a single character into our transmission buffer,
+  *
+  * @param c the character to transmit
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
+  */
+int MicroBitUARTService::putc(char c, MicroBitSerialMode mode)
+{
+    return (send((uint8_t *)&c, 1, mode) == 1) ? 1 : EOF;
+}
+
+/**
+  * Copies characters into the buffer used for Transmitting to the central device.
+  *
+  * @param buf a buffer containing length number of bytes.
+  * @param length the size of the buffer.
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
+  */
+int MicroBitUARTService::send(const uint8_t *buf, int length, MicroBitSerialMode mode)
+{
+    if(length < 1 || mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    bool updatesEnabled = false;
+
+    ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
+
+    if(!ble.getGapState().connected && !updatesEnabled)
+        return MICROBIT_NOT_SUPPORTED;
+
+    int bytesWritten = 0;
+
+    while(bytesWritten < length && ble.getGapState().connected && updatesEnabled)
+    {
+        for(int bufferIterator = bytesWritten; bufferIterator < length; bufferIterator++)
+        {
+            int nextHead = (txBufferHead + 1) % txBufferSize;
+
+            if(nextHead != txBufferTail)
+            {
+                txBuffer[txBufferHead] = buf[bufferIterator];
+
+                txBufferHead = nextHead;
+
+                bytesWritten++;
+            }
+        }
+
+        int size = txBufferedSize();
+
+        uint8_t temp[size];
+
+        memclr(&temp, size);
+
+        circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead);
+
+
+        if(mode == SYNC_SLEEP)
+            fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY);
+
+        ble.gattServer().write(txCharacteristic->getValueAttribute().getHandle(), temp, size);
+
+        if(mode == SYNC_SLEEP)
+            schedule();
+        else
+            break;
+
+        ble.gattServer().areUpdatesEnabled(*txCharacteristic, &updatesEnabled);
+    }
+
+    return bytesWritten;
+}
+
+/**
+  * Copies characters into the buffer used for Transmitting to the central device.
+  *
+  * @param s the string to transmit
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will copy as many characters as it can into the buffer for transmission,
+  *                    and return control to the user.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will perform a cooperative blocking wait until all
+  *                         given characters have been received by the connected
+  *                         device.
+  *
+  * @return the number of characters written, or MICROBIT_NOT_SUPPORTED if there is
+  *         no connected device, or the connected device has not enabled indications.
+  */
+int MicroBitUARTService::send(ManagedString s, MicroBitSerialMode mode)
+{
+    return send((uint8_t *)s.toCharArray(), s.length(), mode);
+}
+
+/**
+  * Reads a number of characters from the rxBuffer and fills user given buffer.
+  *
+  * @param buf a pointer to a buffer of len bytes.
+  * @param len the size of the user allocated buffer
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will attempt to read all available characters, and return immediately
+  *                    until the buffer limit is reached
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will first of all determine whether the given number of characters
+  *                         are available in our buffer, if not, it will set an event and sleep
+  *                         until the number of characters are avaialable.
+  *
+  * @return the number of characters digested
+  */
+int MicroBitUARTService::read(uint8_t *buf, int len, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    int i = 0;
+
+    if(mode == ASYNC)
+    {
+        int c;
+
+        while((c = getc(mode)) > 0 && i < len)
+        {
+            buf[i] = c;
+            i++;
+        }
+    }
+
+    if(mode == SYNC_SLEEP)
+    {
+        if(len > rxBufferedSize())
+            eventAfter(len - rxBufferedSize(), mode);
+
+        while(i < len)
+        {
+            buf[i] = (char)getc(mode);
+            i++;
+        }
+    }
+
+    return i;
+}
+
+/**
+  * Reads a number of characters from the rxBuffer and returns them as a ManagedString
+  *
+  * @param len the number of characters to read.
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will attempt to read all available characters, and return immediately
+  *                    until the buffer limit is reached
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will first of all determine whether the given number of characters
+  *                         are available in our buffer, if not, it will set an event and sleep
+  *                         until the number of characters are avaialable.
+  *
+  * @return an empty ManagedString on error, or a ManagedString containing characters
+  */
+ManagedString MicroBitUARTService::read(int len, MicroBitSerialMode mode)
+{
+    uint8_t buf[len + 1];
+
+    memclr(&buf, len + 1);
+
+    int ret = read(buf, len, mode);
+
+    if(ret < 1)
+        return ManagedString();
+
+    return ManagedString((const char *)buf);
+}
+
+/**
+  * Reads characters until a character matches one of the given delimeters
+  *
+  * @param delimeters the number of characters to match against
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will attempt read the immediate buffer, and look for a match.
+  *                    If there isn't, an empty ManagedString will be returned.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will first of all consider the characters in the immediate buffer,
+  *                         if a match is not found, it will block on an event, fired when a
+  *                         character is matched.
+  *
+  * @return an empty ManagedString on error, or a ManagedString containing characters
+  */
+ManagedString MicroBitUARTService::readUntil(ManagedString delimeters, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    int localTail = rxBufferTail;
+    int preservedTail = rxBufferTail;
+
+    int foundIndex = -1;
+
+    //ASYNC mode just iterates through our stored characters checking for any matches.
+    while(localTail != rxBufferHead && foundIndex  == -1)
+    {
+        //we use localTail to prevent modification of the actual tail.
+        char c = rxBuffer[localTail];
+
+        for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
+            if(delimeters.charAt(delimeterIterator) == c)
+                foundIndex = localTail;
+
+        localTail = (localTail + 1) % rxBufferSize;
+    }
+
+    //if our mode is SYNC_SLEEP, we set up an event to be fired when we see a
+    //matching character.
+    if(mode == SYNC_SLEEP && foundIndex == -1)
+    {
+        eventOn(delimeters, mode);
+
+        foundIndex = rxBufferHead - 1;
+
+        this->delimeters = ManagedString();
+    }
+
+    if(foundIndex >= 0)
+    {
+        //calculate our local buffer size
+        int localBuffSize = (preservedTail > foundIndex) ? (rxBufferSize - preservedTail) + foundIndex : foundIndex - preservedTail;
+
+        uint8_t localBuff[localBuffSize + 1];
+
+        memclr(&localBuff, localBuffSize + 1);
+
+        circularCopy(rxBuffer, rxBufferSize, localBuff, preservedTail, foundIndex);
+
+        //plus one for the character we listened for...
+        rxBufferTail = (rxBufferTail + localBuffSize + 1) % rxBufferSize;
+
+        return ManagedString((char *)localBuff, localBuffSize);
+    }
+
+    return ManagedString();
+}
+
+/**
+  * Configures an event to be fired on a match with one of the delimeters.
+  *
+  * @param delimeters the characters to match received characters against e.g. ManagedString("\r\n")
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will configure the event and return immediately.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+  *                         event is received.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+  *
+  * @note delimeters are matched on a per byte basis.
+  */
+int MicroBitUARTService::eventOn(ManagedString delimeters, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //configure our head match...
+    this->delimeters = delimeters;
+
+    //block!
+    if(mode == SYNC_SLEEP)
+        fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures an event to be fired after "len" characters.
+  *
+  * @param len the number of characters to wait before triggering the event
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will configure the event and return immediately.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+  *                         event is received.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+  */
+int MicroBitUARTService::eventAfter(int len, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //configure our head match...
+    this->rxBuffHeadMatch = (rxBufferHead + len) % rxBufferSize;
+
+    //block!
+    if(mode == SYNC_SLEEP)
+        fiber_wait_for_event(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_HEAD_MATCH);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Determines if we have space in our rxBuff.
+  *
+  * @return 1 if we have space, 0 if we do not.
+  *
+  * @note the reason we do not wrap the super's readable() method is so that we
+  *       don't interfere with communities that use manual calls to uBit.serial.readable()
+  */
+int MicroBitUARTService::isReadable()
+{
+    return (rxBufferTail != rxBufferHead) ? 1 : 0;
+}
+
+/**
+  * @return The currently buffered number of bytes in our rxBuff.
+  */
+int MicroBitUARTService::rxBufferedSize()
+{
+    if(rxBufferTail > rxBufferHead)
+        return (rxBufferSize - rxBufferTail) + rxBufferHead;
+
+    return rxBufferHead - rxBufferTail;
+}
+
+/**
+  * @return The currently buffered number of bytes in our txBuff.
+  */
+int MicroBitUARTService::txBufferedSize()
+{
+    if(txBufferTail > txBufferHead)
+        return (txBufferSize - txBufferTail) + txBufferHead;
+
+    return txBufferHead - txBufferTail;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MemberFunctionCallback.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,58 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a MemberFunctionCallback.
+  *
+  * C++ member functions (also known as methods) have a more complex
+  * representation than normal C functions. This class allows a reference to
+  * a C++ member function to be stored then called at a later date.
+  *
+  * This class is used extensively by the MicroBitMessageBus to deliver
+  * events to C++ methods.
+  */
+
+#include "MicroBitConfig.h"
+#include "MemberFunctionCallback.h"
+
+/**
+  * Calls the method reference held by this MemberFunctionCallback.
+  *
+  * @param e The event to deliver to the method
+  */
+void MemberFunctionCallback::fire(MicroBitEvent e)
+{
+    invoke(object, method, e);
+}
+
+/**
+  * A comparison of two MemberFunctionCallback objects.
+  *
+  * @return true if the given MemberFunctionCallback is equivalent to this one, false otherwise.
+  */
+bool MemberFunctionCallback::operator==(const MemberFunctionCallback &mfc)
+{
+    return (object == mfc.object && (memcmp(method,mfc.method,sizeof(method))==0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitCompat.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,101 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * This file contains functions used to maintain compatability and portability.
+  * It also contains constants that are used elsewhere in the DAL.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitCompat.h"
+#include "ErrorNo.h"
+
+
+/**
+  * Performs an in buffer reverse of a given char array.
+  *
+  * @param s the string to reverse.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int string_reverse(char *s)
+{
+    //sanity check...
+    if(s == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    char *j;
+    int c;
+
+    j = s + strlen(s) - 1;
+
+    while(s < j)
+    {
+        c = *s;
+        *s++ = *j;
+        *j-- = c;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Converts a given integer into a string representation.
+  *
+  * @param n The number to convert.
+  *
+  * @param s A pointer to the buffer where the resulting string will be stored.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int itoa(int n, char *s)
+{
+    int i = 0;
+    int positive = (n >= 0);
+
+    if (s == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Record the sign of the number,
+    // Ensure our working value is positive.
+    if (positive)
+        n = -n;
+
+    // Calculate each character, starting with the LSB.
+    do {
+         s[i++] = abs(n % 10) + '0';
+    } while (abs(n /= 10) > 0);
+
+    // Add a negative sign as needed
+    if (!positive)
+        s[i++] = '-';
+
+    // Terminate the string.
+    s[i] = '\0';
+
+    // Flip the order.
+    string_reverse(s);
+
+    return MICROBIT_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitDevice.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,381 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Compatibility / portability funcitons and constants for the MicroBit DAL.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitButton.h"
+#include "MicroBitDevice.h"
+#include "MicroBitFont.h"
+#include "mbed.h"
+#include "ErrorNo.h"
+
+/*
+ * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include "nrf_soc.h"
+#include "nrf_sdm.h"
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic pop
+#endif
+
+static char friendly_name[MICROBIT_NAME_LENGTH+1];
+static const uint8_t panicFace[5] = {0x1B, 0x1B,0x0,0x0E,0x11};
+static int panic_timeout = 0;
+static uint32_t random_value = 0;
+
+/**
+  * Determines if a BLE stack is currently running.
+  *
+  * @return true is a bluetooth stack is operational, false otherwise.
+  */
+bool ble_running()
+{
+    uint8_t t = 0;
+
+#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) || CONFIG_ENABLED(MICROBIT_BLE_PAIRING_MODE)
+    sd_softdevice_is_enabled(&t);
+#endif
+
+    return t==1;
+}
+
+/**
+ * Derived a unique, consistent serial number of this device from internal data.
+ *
+ * @return the serial number of this device.
+ */
+uint32_t microbit_serial_number()
+{
+    return NRF_FICR->DEVICEID[1];
+}
+
+/**
+ * Derive the friendly name for this device, based on its serial number.
+ *
+ * @return the serial number of this device.
+ */
+char* microbit_friendly_name()
+{
+    const uint8_t codebook[MICROBIT_NAME_LENGTH][MICROBIT_NAME_CODE_LETTERS] =
+    {
+        {'z', 'v', 'g', 'p', 't'},
+        {'u', 'o', 'i', 'e', 'a'},
+        {'z', 'v', 'g', 'p', 't'},
+        {'u', 'o', 'i', 'e', 'a'},
+        {'z', 'v', 'g', 'p', 't'}
+    };
+
+    // We count right to left, so create a pointer to the end of the buffer.
+	char *name = friendly_name;
+    name += MICROBIT_NAME_LENGTH;
+
+    // Terminate the string.
+    *name = 0;
+
+	// Derive our name from the nrf51822's unique ID.
+    uint32_t n = microbit_serial_number();
+    int ld = 1;
+    int d = MICROBIT_NAME_CODE_LETTERS;
+    int h;
+
+    for (int i=0; i<MICROBIT_NAME_LENGTH; i++)
+    {
+        h = (n % d) / ld;
+        n -= h;
+        d *= MICROBIT_NAME_CODE_LETTERS;
+        ld *= MICROBIT_NAME_CODE_LETTERS;
+        *--name = codebook[i][h];
+    }
+
+    return friendly_name;
+}
+
+/**
+  * Perform a hard reset of the micro:bit.
+  */
+void
+microbit_reset()
+{
+    NVIC_SystemReset();
+}
+
+/**
+  * Determine the version of microbit-dal currently running.
+  * @return a pointer to a character buffer containing a representation of the semantic version number.
+  */
+const char *
+microbit_dal_version()
+{
+    return MICROBIT_DAL_VERSION;
+}
+
+/**
+ * Defines the length of time that the device will remain in a error state before resetting.
+ *
+ * @param iteration The number of times the error code will be displayed before resetting. Set to zero to remain in error state forever.
+ *
+ * @code
+ * microbit_panic_timeout(4);
+ * @endcode
+ */
+void microbit_panic_timeout(int iterations)
+{
+    panic_timeout = iterations;
+}
+
+/**
+  * Disables all interrupts and user processing.
+  * Displays "=(" and an accompanying status code on the default display.
+  * @param statusCode the appropriate status code, must be in the range 0-999.
+  *
+  * @code
+  * microbit_panic(20);
+  * @endcode
+  */
+void microbit_panic(int statusCode)
+{
+    DigitalIn resetButton(MICROBIT_PIN_BUTTON_RESET);
+    resetButton.mode(PullUp);
+
+    uint32_t    row_mask = 0;
+    uint32_t    col_mask = 0;
+    uint32_t    row_reset = 0x01 << microbitMatrixMap.rowStart;
+    uint32_t    row_data = row_reset;
+    uint8_t     count = panic_timeout ? panic_timeout : 1;
+    uint8_t     strobeRow = 0;
+
+    row_mask = 0;
+    for (int i = microbitMatrixMap.rowStart; i < microbitMatrixMap.rowStart + microbitMatrixMap.rows; i++)
+        row_mask |= 0x01 << i;
+
+    for (int i = microbitMatrixMap.columnStart; i < microbitMatrixMap.columnStart + microbitMatrixMap.columns; i++)
+        col_mask |= 0x01 << i;
+
+    PortOut LEDMatrix(Port0, row_mask | col_mask);
+
+    if(statusCode < 0 || statusCode > 999)
+        statusCode = 0;
+
+    __disable_irq(); //stop ALL interrupts
+
+
+    //point to the font stored in Flash
+    const unsigned char* fontLocation = MicroBitFont::defaultFont;
+
+    //get individual digits of status code, and place it into a single array/
+    const uint8_t* chars[MICROBIT_PANIC_ERROR_CHARS] = { panicFace, fontLocation+((((statusCode/100 % 10)+48)-MICROBIT_FONT_ASCII_START) * 5), fontLocation+((((statusCode/10 % 10)+48)-MICROBIT_FONT_ASCII_START) * 5), fontLocation+((((statusCode % 10)+48)-MICROBIT_FONT_ASCII_START) * 5)};
+
+    while(count)
+    {
+        //iterate through our chars :)
+        for(int characterCount = 0; characterCount < MICROBIT_PANIC_ERROR_CHARS; characterCount++)
+        {
+            int outerCount = 0;
+
+            //display the current character
+            while(outerCount < 500)
+            {
+                uint32_t col_data = 0;
+
+                int i = 0;
+
+                //if we have hit the row limit - reset both the bit mask and the row variable
+                if(strobeRow == microbitMatrixMap.rows)
+                {
+                    strobeRow = 0;
+                    row_data = row_reset;
+                }
+
+                // Calculate the bitpattern to write.
+                for (i = 0; i < microbitMatrixMap.columns; i++)
+                {
+                    int index = (i * microbitMatrixMap.rows) + strobeRow;
+
+                    int bitMsk = 0x10 >> microbitMatrixMap.map[index].x; //chars are right aligned but read left to right
+                    int y = microbitMatrixMap.map[index].y;
+
+                    if(chars[characterCount][y] & bitMsk)
+                        col_data |= (1 << i);
+                }
+
+                col_data = ~col_data << microbitMatrixMap.columnStart & col_mask;
+
+                if(chars[characterCount] == chars[(characterCount - 1) % MICROBIT_PANIC_ERROR_CHARS] && outerCount < 50)
+                    LEDMatrix =  0;
+                else
+                    LEDMatrix = col_data | row_data;
+
+                //burn cycles
+                i = 2000;
+                while(i>0)
+                {
+                    // Check if the reset button has been pressed. Interrupts are disabled, so the normal method can't be relied upon...
+                    if (resetButton == 0)
+                        microbit_reset();
+
+                    i--;
+                }
+
+                //update the bit mask and row count
+                row_data <<= 1;
+                strobeRow++;
+                outerCount++;
+            }
+        }
+
+        if (panic_timeout)
+            count--;
+    }
+
+    microbit_reset();
+}
+
+/**
+  * Generate a random number in the given range.
+  * We use a simple Galois LFSR random number generator here,
+  * as a Galois LFSR is sufficient for our applications, and much more lightweight
+  * than the hardware random number generator built int the processor, which takes
+  * a long time and uses a lot of energy.
+  *
+  * KIDS: You shouldn't use this is the real world to generte cryptographic keys though...
+  * have a think why not. :-)
+  *
+  * @param max the upper range to generate a number for. This number cannot be negative.
+  *
+  * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0.
+  *
+  * @code
+  * microbit_random(200); //a number between 0 and 199
+  * @endcode
+  */
+int microbit_random(int max)
+{
+    uint32_t m, result;
+
+    if(max <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Our maximum return value is actually one less than passed
+    max--;
+
+    do {
+        m = (uint32_t)max;
+        result = 0;
+		do {
+            // Cycle the LFSR (Linear Feedback Shift Register).
+            // We use an optimal sequence with a period of 2^32-1, as defined by Bruce Schneier here (a true legend in the field!),
+            // For those interested, it's documented in his paper:
+            // "Pseudo-Random Sequence Generator for 32-Bit CPUs: A fast, machine-independent generator for 32-bit Microprocessors"
+            // https://www.schneier.com/paper-pseudorandom-sequence.html
+			uint32_t rnd = random_value;
+
+            rnd = ((((rnd >> 31)
+                          ^ (rnd >> 6)
+                          ^ (rnd >> 4)
+                          ^ (rnd >> 2)
+                          ^ (rnd >> 1)
+                          ^ rnd)
+                          & 0x0000001)
+                          << 31 )
+                          | (rnd >> 1);
+
+			random_value = rnd;
+
+            result = ((result << 1) | (rnd & 0x00000001));
+        } while(m >>= 1);
+    } while (result > (uint32_t)max);
+
+    return result;
+}
+
+/**
+  * Seed the random number generator (RNG).
+  *
+  * This function uses the NRF51822's in built cryptographic random number generator to seed a Galois LFSR.
+  * We do this as the hardware RNG is relatively high power, and is locked out by the BLE stack internally,
+  * with a less than optimal application interface. A Galois LFSR is sufficient for our
+  * applications, and much more lightweight.
+  */
+void microbit_seed_random()
+{
+    random_value = 0;
+
+    if(ble_running())
+    {
+        // If Bluetooth is enabled, we need to go through the Nordic software to safely do this.
+        uint32_t result = sd_rand_application_vector_get((uint8_t*)&random_value, sizeof(random_value));
+
+        // If we couldn't get the random bytes then at least make the seed non-zero.
+        if (result != NRF_SUCCESS)
+            random_value = 0xBBC5EED;
+    }
+    else
+    {
+        // Othwerwise we can access the hardware RNG directly.
+
+        // Start the Random number generator. No need to leave it running... I hope. :-)
+        NRF_RNG->TASKS_START = 1;
+
+        for(int i = 0; i < 4; i++)
+        {
+            // Clear the VALRDY EVENT
+            NRF_RNG->EVENTS_VALRDY = 0;
+
+            // Wait for a number ot be generated.
+            while(NRF_RNG->EVENTS_VALRDY == 0);
+
+            random_value = (random_value << 8) | ((int) NRF_RNG->VALUE);
+        }
+
+        // Disable the generator to save power.
+        NRF_RNG->TASKS_STOP = 1;
+    }
+}
+
+/**
+  * Seed the pseudo random number generator (RNG) using the given 32-bit value.
+  * This function does not use the NRF51822's in built cryptographic random number generator.
+  *
+  * @param seed The value to use as a seed.
+  */
+void microbit_seed_random(uint32_t seed)
+{
+    random_value = seed;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitFiber.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,944 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Functionality definitions for the MicroBit Fiber scheduler.
+  *
+  * This lightweight, non-preemptive scheduler provides a simple threading mechanism for two main purposes:
+  *
+  * 1) To provide a clean abstraction for application languages to use when building async behaviour (callbacks).
+  * 2) To provide ISR decoupling for EventModel events generated in an ISR context.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitFiber.h"
+#include "MicroBitSystemTimer.h"
+
+/*
+ * Statically allocated values used to create and destroy Fibers.
+ * required to be defined here to allow persistence during context switches.
+ */
+Fiber *currentFiber = NULL;                        // The context in which the current fiber is executing.
+static Fiber *forkedFiber = NULL;                  // The context in which a newly created child fiber is executing.
+static Fiber *idleFiber = NULL;                    // the idle task - performs a power efficient sleep, and system maintenance tasks.
+
+/*
+ * Scheduler state.
+ */
+static Fiber *runQueue = NULL;                     // The list of runnable fibers.
+static Fiber *sleepQueue = NULL;                   // The list of blocked fibers waiting on a fiber_sleep() operation.
+static Fiber *waitQueue = NULL;                    // The list of blocked fibers waiting on an event.
+static Fiber *fiberPool = NULL;                    // Pool of unused fibers, just waiting for a job to do.
+
+/*
+ * Scheduler wide flags
+ */
+static uint8_t fiber_flags = 0;
+
+
+/*
+ * Fibers may perform wait/notify semantics on events. If set, these operations will be permitted on this EventModel.
+ */
+static EventModel *messageBus = NULL;
+
+// Array of components which are iterated during idle thread execution.
+static MicroBitComponent* idleThreadComponents[MICROBIT_IDLE_COMPONENTS];
+
+/**
+  * Utility function to add the currenty running fiber to the given queue.
+  *
+  * Perform a simple add at the head, to avoid complexity,
+  *
+  * Queues are normally very short, so maintaining a doubly linked, sorted list typically outweighs the cost of
+  * brute force searching.
+  *
+  * @param f The fiber to add to the queue
+  *
+  * @param queue The run queue to add the fiber to.
+  */
+void queue_fiber(Fiber *f, Fiber **queue)
+{
+    __disable_irq();
+
+    // Record which queue this fiber is on.
+    f->queue = queue;
+
+    // Add the fiber to the tail of the queue. Although this involves scanning the
+    // list, it results in fairer scheduling.
+    if (*queue == NULL)
+    {
+        f->next = NULL;
+        f->prev = NULL;
+        *queue = f;
+    }
+    else
+    {
+        // Scan to the end of the queue.
+        // We don't maintain a tail pointer to save RAM (queues are nrmally very short).
+        Fiber *last = *queue;
+
+        while (last->next != NULL)
+            last = last->next;
+
+        last->next = f;
+        f->prev = last;
+        f->next = NULL;
+    }
+
+    __enable_irq();
+}
+
+/**
+  * Utility function to the given fiber from whichever queue it is currently stored on.
+  *
+  * @param f the fiber to remove.
+  */
+void dequeue_fiber(Fiber *f)
+{
+    // If this fiber is already dequeued, nothing the there's nothing to do.
+    if (f->queue == NULL)
+        return;
+
+    // Remove this fiber fromm whichever queue it is on.
+    __disable_irq();
+
+    if (f->prev != NULL)
+        f->prev->next = f->next;
+    else
+        *(f->queue) = f->next;
+
+    if(f->next)
+        f->next->prev = f->prev;
+
+    f->next = NULL;
+    f->prev = NULL;
+    f->queue = NULL;
+
+    __enable_irq();
+
+}
+
+/**
+  * Allocates a fiber from the fiber pool if availiable. Otherwise, allocates a new one from the heap.
+  */
+Fiber *getFiberContext()
+{
+    Fiber *f;
+
+    __disable_irq();
+
+    if (fiberPool != NULL)
+    {
+        f = fiberPool;
+        dequeue_fiber(f);
+        // dequeue_fiber() exits with irqs enabled, so no need to do this again!
+    }
+    else
+    {
+        __enable_irq();
+
+        f = new Fiber();
+
+        if (f == NULL)
+            return NULL;
+
+        f->stack_bottom = 0;
+        f->stack_top = 0;
+    }
+
+    // Ensure this fiber is in suitable state for reuse.
+    f->flags = 0;
+    f->tcb.stack_base = CORTEX_M0_STACK_BASE;
+
+    return f;
+}
+
+
+/**
+  * Initialises the Fiber scheduler.
+  * Creates a Fiber context around the calling thread, and adds it to the run queue as the current thread.
+  *
+  * This function must be called once only from the main thread, and before any other Fiber operation.
+  *
+  * @param _messageBus An event model, used to direct the priorities of the scheduler.
+  */
+void scheduler_init(EventModel &_messageBus)
+{
+    // If we're already initialised, then nothing to do.
+    if (fiber_scheduler_running())
+        return;
+
+	// Store a reference to the messageBus provided.
+	// This parameter will be NULL if we're being run without a message bus.
+	messageBus = &_messageBus;
+
+    // Create a new fiber context
+    currentFiber = getFiberContext();
+
+    // Add ourselves to the run queue.
+    queue_fiber(currentFiber, &runQueue);
+
+    // Create the IDLE fiber.
+    // Configure the fiber to directly enter the idle task.
+    idleFiber = getFiberContext();
+    idleFiber->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
+    idleFiber->tcb.LR = (uint32_t) &idle_task;
+
+	if (messageBus)
+	{
+		// Register to receive events in the NOTIFY channel - this is used to implement wait-notify semantics
+		messageBus->listen(MICROBIT_ID_NOTIFY, MICROBIT_EVT_ANY, scheduler_event, MESSAGE_BUS_LISTENER_IMMEDIATE);
+		messageBus->listen(MICROBIT_ID_NOTIFY_ONE, MICROBIT_EVT_ANY, scheduler_event, MESSAGE_BUS_LISTENER_IMMEDIATE);
+	}
+
+	// register a period callback to drive the scheduler and any other registered components.
+    new MicroBitSystemTimerCallback(scheduler_tick);
+
+	fiber_flags |= MICROBIT_SCHEDULER_RUNNING;
+}
+
+/**
+  * Determines if the fiber scheduler is operational.
+  *
+  * @return 1 if the fber scheduler is running, 0 otherwise.
+  */
+int fiber_scheduler_running()
+{
+	if (fiber_flags & MICROBIT_SCHEDULER_RUNNING)
+		return 1;
+
+	return 0;
+}
+
+/**
+  * The timer callback, called from interrupt context once every SYSTEM_TICK_PERIOD_MS milliseconds.
+  * This function checks to determine if any fibers blocked on the sleep queue need to be woken up
+  * and made runnable.
+  */
+void scheduler_tick()
+{
+    Fiber *f = sleepQueue;
+    Fiber *t;
+
+    // Check the sleep queue, and wake up any fibers as necessary.
+    while (f != NULL)
+    {
+        t = f->next;
+
+        if (system_timer_current_time() >= f->context)
+        {
+            // Wakey wakey!
+            dequeue_fiber(f);
+            queue_fiber(f,&runQueue);
+        }
+
+        f = t;
+    }
+}
+
+/**
+  * Event callback. Called from an instance of MicroBitMessageBus whenever an event is raised.
+  *
+  * This function checks to determine if any fibers blocked on the wait queue need to be woken up
+  * and made runnable due to the event.
+  *
+  * @param evt the event that has just been raised on an instance of MicroBitMessageBus.
+  */
+void scheduler_event(MicroBitEvent evt)
+{
+    Fiber *f = waitQueue;
+    Fiber *t;
+    int notifyOneComplete = 0;
+
+	// This should never happen.
+	// It is however, safe to simply ignore any events provided, as if no messageBus if recorded,
+	// no fibers are permitted to block on events.
+	if (messageBus == NULL)
+		return;
+
+    // Check the wait queue, and wake up any fibers as necessary.
+    while (f != NULL)
+    {
+        t = f->next;
+
+        // extract the event data this fiber is blocked on.
+        uint16_t id = f->context & 0xFFFF;
+        uint16_t value = (f->context & 0xFFFF0000) >> 16;
+
+        // Special case for the NOTIFY_ONE channel...
+        if ((evt.source == MICROBIT_ID_NOTIFY_ONE && id == MICROBIT_ID_NOTIFY) && (value == MICROBIT_EVT_ANY || value == evt.value))
+        {
+            if (!notifyOneComplete)
+            {
+                // Wakey wakey!
+                dequeue_fiber(f);
+                queue_fiber(f,&runQueue);
+                notifyOneComplete = 1;
+            }
+        }
+
+        // Normal case.
+        else if ((id == MICROBIT_ID_ANY || id == evt.source) && (value == MICROBIT_EVT_ANY || value == evt.value))
+        {
+            // Wakey wakey!
+            dequeue_fiber(f);
+            queue_fiber(f,&runQueue);
+        }
+
+        f = t;
+    }
+
+    // Unregister this event, as we've woken up all the fibers with this match.
+    if (evt.source != MICROBIT_ID_NOTIFY && evt.source != MICROBIT_ID_NOTIFY_ONE)
+        messageBus->ignore(evt.source, evt.value, scheduler_event);
+}
+
+
+/**
+  * Blocks the calling thread for the given period of time.
+  * The calling thread will be immediateley descheduled, and placed onto a
+  * wait queue until the requested amount of time has elapsed.
+  *
+  * @param t The period of time to sleep, in milliseconds.
+  *
+  * @note the fiber will not be be made runnable until after the elapsed time, but there
+  * are no guarantees precisely when the fiber will next be scheduled.
+  */
+void fiber_sleep(unsigned long t)
+{
+    Fiber *f = currentFiber;
+
+    // If the scheduler is not running, then simply perform a spin wait and exit.
+    if (!fiber_scheduler_running())
+    {
+        wait_ms(t);
+        return;
+    }
+
+    // Sleep is a blocking call, so if we're in a fork on block context,
+    // it's time to spawn a new fiber...
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB)
+    {
+        // Allocate a new fiber. This will come from the fiber pool if availiable,
+        // else a new one will be allocated on the heap.
+        forkedFiber = getFiberContext();
+
+        // If we're out of memory, there's nothing we can do.
+        // keep running in the context of the current thread as a best effort.
+        if (forkedFiber != NULL)
+                f = forkedFiber;
+    }
+
+    // Calculate and store the time we want to wake up.
+    f->context = system_timer_current_time() + t;
+
+    // Remove fiber from the run queue
+    dequeue_fiber(f);
+
+    // Add fiber to the sleep queue. We maintain strict ordering here to reduce lookup times.
+    queue_fiber(f, &sleepQueue);
+
+    // Finally, enter the scheduler.
+    schedule();
+}
+
+/**
+  * Blocks the calling thread until the specified event is raised.
+  * The calling thread will be immediateley descheduled, and placed onto a
+  * wait queue until the requested event is received.
+  *
+  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
+  *
+  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
+  *
+  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
+  *
+  * @code
+  * fiber_wait_for_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+  * @endcode
+  *
+  * @note the fiber will not be be made runnable until after the event is raised, but there
+  * are no guarantees precisely when the fiber will next be scheduled.
+  */
+int fiber_wait_for_event(uint16_t id, uint16_t value)
+{
+    int ret = fiber_wake_on_event(id, value);
+
+    if(ret == MICROBIT_OK)
+        schedule();
+
+	return ret;
+}
+
+/**
+  * Configures the fiber context for the current fiber to block on an event ID
+  * and value, but does not deschedule the fiber.
+  *
+  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
+  *
+  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
+  *
+  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
+  *
+  * @code
+  * fiber_wake_on_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+  *
+  * //perform some time critical operation.
+  *
+  * //deschedule the current fiber manually, waiting for the previously configured event.
+  * schedule();
+  * @endcode
+  */
+int fiber_wake_on_event(uint16_t id, uint16_t value)
+{
+    Fiber *f = currentFiber;
+
+	if (messageBus == NULL || !fiber_scheduler_running())
+		return MICROBIT_NOT_SUPPORTED;
+
+    // Sleep is a blocking call, so if we're in a fork on block context,
+    // it's time to spawn a new fiber...
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB)
+    {
+        // Allocate a TCB from the new fiber. This will come from the tread pool if availiable,
+        // else a new one will be allocated on the heap.
+        forkedFiber = getFiberContext();
+
+        // If we're out of memory, there's nothing we can do.
+        // keep running in the context of the current thread as a best effort.
+        if (forkedFiber != NULL)
+        {
+            f = forkedFiber;
+            dequeue_fiber(f);
+            queue_fiber(f, &runQueue);
+            schedule();
+        }
+    }
+
+    // Encode the event data in the context field. It's handy having a 32 bit core. :-)
+    f->context = value << 16 | id;
+
+    // Remove ourselves from the run queue
+    dequeue_fiber(f);
+
+    // Add ourselves to the sleep queue. We maintain strict ordering here to reduce lookup times.
+    queue_fiber(f, &waitQueue);
+
+    // Register to receive this event, so we can wake up the fiber when it happens.
+    // Special case for the notify channel, as we always stay registered for that.
+    if (id != MICROBIT_ID_NOTIFY && id != MICROBIT_ID_NOTIFY_ONE)
+        messageBus->listen(id, value, scheduler_event, MESSAGE_BUS_LISTENER_IMMEDIATE);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Executes the given function asynchronously if necessary.
+  *
+  * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
+  * that complete very quickly, bringing unecessary RAM overhead.
+  *
+  * This function takes a snapshot of the current processor context, then attempts to optimistically call the given function directly.
+  * We only create an additional fiber if that function performs a block operation.
+  *
+  * @param entry_fn The function to execute.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int invoke(void (*entry_fn)(void))
+{
+    // Validate our parameters.
+    if (entry_fn == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (!fiber_scheduler_running())
+		return MICROBIT_NOT_SUPPORTED;
+
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB)
+    {
+        // If we attempt a fork on block whilst already in  fork n block context,
+        // simply launch a fiber to deal with the request and we're done.
+        create_fiber(entry_fn);
+        return MICROBIT_OK;
+    }
+
+    // Snapshot current context, but also update the Link Register to
+    // refer to our calling function.
+    save_register_context(&currentFiber->tcb);
+
+    // If we're here, there are two possibilities:
+    // 1) We're about to attempt to execute the user code
+    // 2) We've already tried to execute the code, it blocked, and we've backtracked.
+
+    // If we're returning from the user function and we forked another fiber then cleanup and exit.
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_PARENT)
+    {
+        currentFiber->flags &= ~MICROBIT_FIBER_FLAG_FOB;
+        currentFiber->flags &= ~MICROBIT_FIBER_FLAG_PARENT;
+        return MICROBIT_OK;
+    }
+
+    // Otherwise, we're here for the first time. Enter FORK ON BLOCK mode, and
+    // execute the function directly. If the code tries to block, we detect this and
+    // spawn a thread to deal with it.
+    currentFiber->flags |= MICROBIT_FIBER_FLAG_FOB;
+    entry_fn();
+    currentFiber->flags &= ~MICROBIT_FIBER_FLAG_FOB;
+
+    // If this is is an exiting fiber that for spawned to handle a blocking call, recycle it.
+    // The fiber will then re-enter the scheduler, so no need for further cleanup.
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_CHILD)
+        release_fiber();
+
+     return MICROBIT_OK;
+}
+
+/**
+  * Executes the given function asynchronously if necessary, and offers the ability to provide a parameter.
+  *
+  * Fibers are often used to run event handlers, however many of these event handlers are very simple functions
+  * that complete very quickly, bringing unecessary RAM. overhead
+  *
+  * This function takes a snapshot of the current fiber context, then attempt to optimistically call the given function directly.
+  * We only create an additional fiber if that function performs a block operation.
+  *
+  * @param entry_fn The function to execute.
+  *
+  * @param param an untyped parameter passed into the entry_fn and completion_fn.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  */
+int invoke(void (*entry_fn)(void *), void *param)
+{
+    // Validate our parameters.
+    if (entry_fn == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (!fiber_scheduler_running())
+		return MICROBIT_NOT_SUPPORTED;
+
+    if (currentFiber->flags & (MICROBIT_FIBER_FLAG_FOB | MICROBIT_FIBER_FLAG_PARENT | MICROBIT_FIBER_FLAG_CHILD))
+    {
+        // If we attempt a fork on block whilst already in a fork on block context,
+        // simply launch a fiber to deal with the request and we're done.
+        create_fiber(entry_fn, param);
+        return MICROBIT_OK;
+    }
+
+    // Snapshot current context, but also update the Link Register to
+    // refer to our calling function.
+    save_register_context(&currentFiber->tcb);
+
+    // If we're here, there are two possibilities:
+    // 1) We're about to attempt to execute the user code
+    // 2) We've already tried to execute the code, it blocked, and we've backtracked.
+
+    // If we're returning from the user function and we forked another fiber then cleanup and exit.
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_PARENT)
+    {
+        currentFiber->flags &= ~MICROBIT_FIBER_FLAG_FOB;
+        currentFiber->flags &= ~MICROBIT_FIBER_FLAG_PARENT;
+        return MICROBIT_OK;
+    }
+
+    // Otherwise, we're here for the first time. Enter FORK ON BLOCK mode, and
+    // execute the function directly. If the code tries to block, we detect this and
+    // spawn a thread to deal with it.
+    currentFiber->flags |= MICROBIT_FIBER_FLAG_FOB;
+    entry_fn(param);
+    currentFiber->flags &= ~MICROBIT_FIBER_FLAG_FOB;
+
+    // If this is is an exiting fiber that for spawned to handle a blocking call, recycle it.
+    // The fiber will then re-enter the scheduler, so no need for further cleanup.
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_CHILD)
+        release_fiber(param);
+
+    return MICROBIT_OK;
+}
+
+/**
+ * Launches a fiber.
+ *
+ * @param ep the entry point for the fiber.
+ *
+ * @param cp the completion routine after ep has finished execution
+ */
+void launch_new_fiber(void (*ep)(void), void (*cp)(void))
+{
+    // Execute the thread's entrypoint
+    ep();
+
+    // Execute the thread's completion routine;
+    cp();
+
+    // If we get here, then the completion routine didn't recycle the fiber... so do it anyway. :-)
+    release_fiber();
+}
+
+/**
+ * Launches a fiber with a parameter
+ *
+ * @param ep the entry point for the fiber.
+ *
+ * @param cp the completion routine after ep has finished execution
+ *
+ * @param pm the parameter to provide to ep and cp.
+ */
+void launch_new_fiber_param(void (*ep)(void *), void (*cp)(void *), void *pm)
+{
+    // Execute the thread's entrypoint.
+    ep(pm);
+
+    // Execute the thread's completion routine.
+    cp(pm);
+
+    // If we get here, then the completion routine didn't recycle the fiber... so do it anyway. :-)
+    release_fiber(pm);
+}
+
+Fiber *__create_fiber(uint32_t ep, uint32_t cp, uint32_t pm, int parameterised)
+{
+    // Validate our parameters.
+    if (ep == 0 || cp == 0)
+        return NULL;
+
+    // Allocate a TCB from the new fiber. This will come from the fiber pool if availiable,
+    // else a new one will be allocated on the heap.
+    Fiber *newFiber = getFiberContext();
+
+    // If we're out of memory, there's nothing we can do.
+    if (newFiber == NULL)
+        return NULL;
+
+    newFiber->tcb.R0 = (uint32_t) ep;
+    newFiber->tcb.R1 = (uint32_t) cp;
+    newFiber->tcb.R2 = (uint32_t) pm;
+
+    // Set the stack and assign the link register to refer to the appropriate entry point wrapper.
+    newFiber->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
+    newFiber->tcb.LR = parameterised ? (uint32_t) &launch_new_fiber_param : (uint32_t) &launch_new_fiber;
+
+    // Add new fiber to the run queue.
+    queue_fiber(newFiber, &runQueue);
+
+    return newFiber;
+}
+
+/**
+  * Creates a new Fiber, and launches it.
+  *
+  * @param entry_fn The function the new Fiber will begin execution in.
+  *
+  * @param completion_fn The function called when the thread completes execution of entry_fn.
+  *                      Defaults to release_fiber.
+  *
+  * @return The new Fiber, or NULL if the operation could not be completed.
+  */
+Fiber *create_fiber(void (*entry_fn)(void), void (*completion_fn)(void))
+{
+    if (!fiber_scheduler_running())
+		return NULL;
+
+    return __create_fiber((uint32_t) entry_fn, (uint32_t)completion_fn, 0, 0);
+}
+
+
+/**
+  * Creates a new parameterised Fiber, and launches it.
+  *
+  * @param entry_fn The function the new Fiber will begin execution in.
+  *
+  * @param param an untyped parameter passed into the entry_fn and completion_fn.
+  *
+  * @param completion_fn The function called when the thread completes execution of entry_fn.
+  *                      Defaults to release_fiber.
+  *
+  * @return The new Fiber, or NULL if the operation could not be completed.
+  */
+Fiber *create_fiber(void (*entry_fn)(void *), void *param, void (*completion_fn)(void *))
+{
+    if (!fiber_scheduler_running())
+		return NULL;
+
+    return __create_fiber((uint32_t) entry_fn, (uint32_t)completion_fn, (uint32_t) param, 1);
+}
+
+/**
+  * Exit point for all fibers.
+  *
+  * Any fiber reaching the end of its entry function will return here  for recycling.
+  */
+void release_fiber(void *)
+{
+    if (!fiber_scheduler_running())
+		return;
+
+    release_fiber();
+}
+
+/**
+  * Exit point for all fibers.
+  *
+  * Any fiber reaching the end of its entry function will return here  for recycling.
+  */
+void release_fiber(void)
+{
+    if (!fiber_scheduler_running())
+		return;
+
+    // Remove ourselves form the runqueue.
+    dequeue_fiber(currentFiber);
+
+    // Add ourselves to the list of free fibers
+    queue_fiber(currentFiber, &fiberPool);
+
+    // Find something else to do!
+    schedule();
+}
+
+/**
+  * Resizes the stack allocation of the current fiber if necessary to hold the system stack.
+  *
+  * If the stack allocation is large enough to hold the current system stack, then this function does nothing.
+  * Otherwise, the the current allocation of the fiber is freed, and a larger block is allocated.
+  *
+  * @param f The fiber context to verify.
+  *
+  * @return The stack depth of the given fiber.
+  */
+void verify_stack_size(Fiber *f)
+{
+    // Ensure the stack buffer is large enough to hold the stack Reallocate if necessary.
+    uint32_t stackDepth;
+    uint32_t bufferSize;
+
+    // Calculate the stack depth.
+    stackDepth = f->tcb.stack_base - ((uint32_t) __get_MSP());
+
+    // Calculate the size of our allocated stack buffer
+    bufferSize = f->stack_top - f->stack_bottom;
+
+    // If we're too small, increase our buffer size.
+    if (bufferSize < stackDepth)
+    {
+        // To ease heap churn, we choose the next largest multple of 32 bytes.
+        bufferSize = (stackDepth + 32) & 0xffffffe0;
+
+        // Release the old memory
+        if (f->stack_bottom != 0)
+            free((void *)f->stack_bottom);
+
+        // Allocate a new one of the appropriate size.
+        f->stack_bottom = (uint32_t) malloc(bufferSize);
+
+        // Recalculate where the top of the stack is and we're done.
+        f->stack_top = f->stack_bottom + bufferSize;
+    }
+}
+
+/**
+  * Determines if any fibers are waiting to be scheduled.
+  *
+  * @return The number of fibers currently on the run queue
+  */
+int scheduler_runqueue_empty()
+{
+    return (runQueue == NULL);
+}
+
+/**
+  * Calls the Fiber scheduler.
+  * The calling Fiber will likely be blocked, and control given to another waiting fiber.
+  * Call this function to yield control of the processor when you have nothing more to do.
+  */
+void schedule()
+{
+    if (!fiber_scheduler_running())
+		return;
+
+    // First, take a reference to the currently running fiber;
+    Fiber *oldFiber = currentFiber;
+
+    // First, see if we're in Fork on Block context. If so, we simply want to store the full context
+    // of the currently running thread in a newly created fiber, and restore the context of the
+    // currently running fiber, back to the point where it entered FOB.
+
+    if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB)
+    {
+        // Record that the fibers have a parent/child relationship
+        currentFiber->flags |= MICROBIT_FIBER_FLAG_PARENT;
+        forkedFiber->flags |= MICROBIT_FIBER_FLAG_CHILD;
+
+        // Define the stack base of the forked fiber to be align with the entry point of the parent fiber
+        forkedFiber->tcb.stack_base = currentFiber->tcb.SP;
+
+        // Ensure the stack allocation of the new fiber is large enough
+        verify_stack_size(forkedFiber);
+
+        // Store the full context of this fiber.
+        save_context(&forkedFiber->tcb, forkedFiber->stack_top);
+
+        // We may now be either the newly created thread, or the one that created it.
+        // if the MICROBIT_FIBER_FLAG_PARENT flag is still set, we're the old thread, so
+        // restore the current fiber to its stored context and we're done.
+        if (currentFiber->flags & MICROBIT_FIBER_FLAG_PARENT)
+            restore_register_context(&currentFiber->tcb);
+
+        // If we're the new thread, we must have been unblocked by the scheduler, so simply return
+        // and continue processing.
+        return;
+    }
+
+    // We're in a normal scheduling context, so perform a round robin algorithm across runnable fibers.
+    // OK - if we've nothing to do, then run the IDLE task (power saving sleep)
+    if (runQueue == NULL)
+        currentFiber = idleFiber;
+
+    else if (currentFiber->queue == &runQueue)
+        // If the current fiber is on the run queue, round robin.
+        currentFiber = currentFiber->next == NULL ? runQueue : currentFiber->next;
+
+    else
+        // Otherwise, just pick the head of the run queue.
+        currentFiber = runQueue;
+
+    if (currentFiber == idleFiber && oldFiber->flags & MICROBIT_FIBER_FLAG_DO_NOT_PAGE)
+    {
+        // Run the idle task right here using the old fiber's stack.
+        // Keep idling while the runqueue is empty, or there is data to process.
+
+        // Run in the context of the original fiber, to preserve state of flags...
+        // as we are running on top of this fiber's stack.
+        currentFiber = oldFiber;
+
+        do
+        {
+            idle();
+        }
+        while (runQueue == NULL);
+
+        // Switch to a non-idle fiber.
+        // If this fiber is the same as the old one then there'll be no switching at all.
+        currentFiber = runQueue;
+    }
+
+    // Swap to the context of the chosen fiber, and we're done.
+    // Don't bother with the overhead of switching if there's only one fiber on the runqueue!
+    if (currentFiber != oldFiber)
+    {
+        // Special case for the idle task, as we don't maintain a stack context (just to save memory).
+        if (currentFiber == idleFiber)
+        {
+            idleFiber->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
+            idleFiber->tcb.LR = (uint32_t) &idle_task;
+        }
+
+        if (oldFiber == idleFiber)
+        {
+            // Just swap in the new fiber, and discard changes to stack and register context.
+            swap_context(NULL, &currentFiber->tcb, 0, currentFiber->stack_top);
+        }
+        else
+        {
+            // Ensure the stack allocation of the fiber being scheduled out is large enough
+            verify_stack_size(oldFiber);
+
+            // Schedule in the new fiber.
+            swap_context(&oldFiber->tcb, &currentFiber->tcb, oldFiber->stack_top, currentFiber->stack_top);
+        }
+    }
+}
+
+/**
+  * Adds a component to the array of idle thread components, which are processed
+  * when the run queue is empty.
+  *
+  * @param component The component to add to the array.
+  * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full.
+  */
+int fiber_add_idle_component(MicroBitComponent *component)
+{
+    int i = 0;
+
+    while(idleThreadComponents[i] != NULL && i < MICROBIT_IDLE_COMPONENTS)
+        i++;
+
+    if(i == MICROBIT_IDLE_COMPONENTS)
+        return MICROBIT_NO_RESOURCES;
+
+    idleThreadComponents[i] = component;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * remove a component from the array of idle thread components
+  *
+  * @param component the component to remove from the idle component array.
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  */
+int fiber_remove_idle_component(MicroBitComponent *component)
+{
+    int i = 0;
+
+    while(idleThreadComponents[i] != component && i < MICROBIT_IDLE_COMPONENTS)
+        i++;
+
+    if(i == MICROBIT_IDLE_COMPONENTS)
+        return MICROBIT_INVALID_PARAMETER;
+
+    idleThreadComponents[i] = NULL;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Set of tasks to perform when idle.
+  * Service any background tasks that are required, and attempt a power efficient sleep.
+  */
+void idle()
+{
+    // Service background tasks
+    for(int i = 0; i < MICROBIT_IDLE_COMPONENTS; i++)
+        if(idleThreadComponents[i] != NULL)
+            idleThreadComponents[i]->idleTick();
+
+    // If the above did create any useful work, enter power efficient sleep.
+    if(scheduler_runqueue_empty())
+    	__WFE();
+}
+
+/**
+  * The idle task, which is called when the runtime has no fibers that require execution.
+  *
+  * This function typically calls idle().
+  */
+void idle_task()
+{
+    while(1)
+    {
+        idle();
+        schedule();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitFont.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,99 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a MicrobitFont
+  * This class represents a font that can be used by the display to render text.
+  *
+  * A MicroBitFont is 5x5.
+  * Each Row is represented by a byte in the array.
+  *
+  * Row Format:
+  *            ================================================================
+  *            | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+  *            ================================================================
+  *            |  N/A  |  N/A  |  N/A  | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 |
+  *            |  0x80 |  0x40 |  0x20 | 0x10  | 0x08  | 0x04  | 0x02  | 0x01  |
+  *
+  * Example: { 0x08, 0x08, 0x08, 0x0, 0x08 }
+  *
+  * The above will produce an exclaimation mark on the second column in form the left.
+  *
+  * We could compress further, but the complexity of decode would likely outweigh the gains.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitFont.h"
+
+const unsigned char pendolino3[475] = {
+0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0x8, 0xa, 0x4a, 0x40, 0x0, 0x0, 0xa, 0x5f, 0xea, 0x5f, 0xea, 0xe, 0xd9, 0x2e, 0xd3, 0x6e, 0x19, 0x32, 0x44, 0x89, 0x33, 0xc, 0x92, 0x4c, 0x92, 0x4d, 0x8, 0x8, 0x0, 0x0, 0x0, 0x4, 0x88, 0x8, 0x8, 0x4, 0x8, 0x4, 0x84, 0x84, 0x88, 0x0, 0xa, 0x44, 0x8a, 0x40, 0x0, 0x4, 0x8e, 0xc4, 0x80, 0x0, 0x0, 0x0, 0x4, 0x88, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x1, 0x22, 0x44, 0x88, 0x10, 0xc, 0x92, 0x52, 0x52, 0x4c, 0x4, 0x8c, 0x84, 0x84, 0x8e, 0x1c, 0x82, 0x4c, 0x90, 0x1e, 0x1e, 0xc2, 0x44, 0x92, 0x4c, 0x6, 0xca, 0x52, 0x5f, 0xe2, 0x1f, 0xf0, 0x1e, 0xc1, 0x3e, 0x2, 0x44, 0x8e, 0xd1, 0x2e, 0x1f, 0xe2, 0x44, 0x88, 0x10, 0xe, 0xd1, 0x2e, 0xd1, 0x2e, 0xe, 0xd1, 0x2e, 0xc4, 0x88, 0x0, 0x8, 0x0, 0x8, 0x0, 0x0, 0x4, 0x80, 0x4, 0x88, 0x2, 0x44, 0x88, 0x4, 0x82, 0x0, 0xe, 0xc0, 0xe, 0xc0, 0x8, 0x4, 0x82, 0x44, 0x88, 0xe, 0xd1, 0x26, 0xc0, 0x4, 0xe, 0xd1, 0x35, 0xb3, 0x6c, 0xc, 0x92, 0x5e, 0xd2, 0x52, 0x1c, 0x92, 0x5c, 0x92, 0x5c, 0xe, 0xd0, 0x10, 0x10, 0xe, 0x1c, 0x92, 0x52, 0x52, 0x5c, 0x1e, 0xd0, 0x1c, 0x90, 0x1e, 0x1e, 0xd0, 0x1c, 0x90, 0x10, 0xe, 0xd0, 0x13, 0x71, 0x2e, 0x12, 0x52, 0x5e, 0xd2, 0x52, 0x1c, 0x88, 0x8, 0x8, 0x1c, 0x1f, 0xe2, 0x42, 0x52, 0x4c, 0x12, 0x54, 0x98, 0x14, 0x92, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x11, 0x3b, 0x75, 0xb1, 0x31, 0x11, 0x39, 0x35, 0xb3, 0x71, 0xc, 0x92, 0x52, 0x52, 0x4c, 0x1c, 0x92, 0x5c, 0x90, 0x10, 0xc, 0x92, 0x52, 0x4c, 0x86, 0x1c, 0x92, 0x5c, 0x92, 0x51, 0xe, 0xd0, 0xc, 0x82, 0x5c, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x12, 0x52, 0x52, 0x52, 0x4c, 0x11, 0x31, 0x31, 0x2a, 0x44, 0x11, 0x31, 0x35, 0xbb, 0x71, 0x12, 0x52, 0x4c, 0x92, 0x52, 0x11, 0x2a, 0x44, 0x84, 0x84, 0x1e, 0xc4, 0x88, 0x10, 0x1e, 0xe, 0xc8, 0x8, 0x8, 0xe, 0x10, 0x8, 0x4, 0x82, 0x41, 0xe, 0xc2, 0x42, 0x42, 0x4e, 0x4, 0x8a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x8, 0x4, 0x80, 0x0, 0x0, 0x0, 0xe, 0xd2, 0x52, 0x4f, 0x10, 0x10, 0x1c, 0x92, 0x5c, 0x0, 0xe, 0xd0, 0x10, 0xe, 0x2, 0x42, 0x4e, 0xd2, 0x4e, 0xc, 0x92, 0x5c, 0x90, 0xe, 0x6, 0xc8, 0x1c, 0x88, 0x8, 0xe, 0xd2, 0x4e, 0xc2, 0x4c, 0x10, 0x10, 0x1c, 0x92, 0x52, 0x8, 0x0, 0x8, 0x8, 0x8, 0x2, 0x40, 0x2, 0x42, 0x4c, 0x10, 0x14, 0x98, 0x14, 0x92, 0x8, 0x8, 0x8, 0x8, 0x6, 0x0, 0x1b, 0x75, 0xb1, 0x31, 0x0, 0x1c, 0x92, 0x52, 0x52, 0x0, 0xc, 0x92, 0x52, 0x4c, 0x0, 0x1c, 0x92, 0x5c, 0x90, 0x0, 0xe, 0xd2, 0x4e, 0xc2, 0x0, 0xe, 0xd0, 0x10, 0x10, 0x0, 0x6, 0xc8, 0x4, 0x98, 0x8, 0x8, 0xe, 0xc8, 0x7, 0x0, 0x12, 0x52, 0x52, 0x4f, 0x0, 0x11, 0x31, 0x2a, 0x44, 0x0, 0x11, 0x31, 0x35, 0xbb, 0x0, 0x12, 0x4c, 0x8c, 0x92, 0x0, 0x11, 0x2a, 0x44, 0x98, 0x0, 0x1e, 0xc4, 0x88, 0x1e, 0x6, 0xc4, 0x8c, 0x84, 0x86, 0x8, 0x8, 0x8, 0x8, 0x8, 0x18, 0x8, 0xc, 0x88, 0x18, 0x0, 0x0, 0xc, 0x83, 0x60};
+
+
+const unsigned char* MicroBitFont::defaultFont = pendolino3;
+MicroBitFont MicroBitFont::systemFont = MicroBitFont(defaultFont, MICROBIT_FONT_ASCII_END);
+
+/**
+  * Constructor.
+  *
+  * Sets the font represented by this font object.
+  *
+  * @param font A pointer to the beginning of the new font.
+  *
+  * @param asciiEnd the char value at which this font finishes.
+  */
+MicroBitFont::MicroBitFont(const unsigned char* characters, int asciiEnd)
+{
+    this->characters = characters;
+    this->asciiEnd = asciiEnd;
+}
+
+/**
+  * Default Constructor.
+  *
+  * Configures the default font for the display to use.
+  */
+MicroBitFont::MicroBitFont()
+{
+    this->characters = defaultFont;
+    this->asciiEnd = MICROBIT_FONT_ASCII_END;
+}
+
+/**
+  * Modifies the current system font to the given instance of MicroBitFont.
+  *
+  * @param font the new font that will be used to render characters on the display.
+  */
+void MicroBitFont::setSystemFont(MicroBitFont font)
+{
+	MicroBitFont::systemFont = font;
+}
+
+/**
+  * Retreives the font object used for rendering characters on the display.
+  */
+MicroBitFont MicroBitFont::getSystemFont()
+{
+    return MicroBitFont::systemFont;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitHeapAllocator.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,405 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * A simple 32 bit block based memory allocator. This allows one or more memory segments to
+  * be designated as heap storage, and is designed to run in a static memory area or inside the standard C
+  * heap for use by the micro:bit runtime. This is required for several reasons:
+  *
+  * 1) It reduces memory fragmentation due to the high churn sometime placed on the heap
+  * by ManagedTypes, fibers and user code. Underlying heap implentations are often have very simplistic
+  * allocation pilicies and suffer from fragmentation in prolonged use - which can cause programs to
+  * stop working after a period of time. The algorithm implemented here is simple, but highly tolerant to
+  * large amounts of churn.
+  *
+  * 2) It allows us to reuse the 8K of SRAM set aside for SoftDevice as additional heap storage
+  * when BLE is not in use.
+  *
+  * 3) It gives a simple example of how memory allocation works! :-)
+  *
+  * P.S. This is a very simple allocator, therefore not without its weaknesses. Why don't you consider
+  * what these are, and consider the tradeoffs against simplicity...
+  *
+  * @note The need for this should be reviewed in the future, if a different memory allocator is
+  * made availiable in the mbed platform.
+  *
+  * TODO: Consider caching recently freed blocks to improve allocation time.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitHeapAllocator.h"
+#include "MicroBitDevice.h"
+#include "ErrorNo.h"
+
+struct HeapDefinition
+{
+    uint32_t *heap_start;		// Physical address of the start of this heap.
+    uint32_t *heap_end;		    // Physical address of the end of this heap.
+};
+
+// A list of all active heap regions, and their dimensions in memory.
+HeapDefinition heap[MICROBIT_MAXIMUM_HEAPS] = { };
+uint8_t heap_count = 0;
+
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+// Diplays a usage summary about a given heap...
+void microbit_heap_print(HeapDefinition &heap)
+{
+	uint32_t	blockSize;
+	uint32_t	*block;
+    int         totalFreeBlock = 0;
+    int         totalUsedBlock = 0;
+    int         cols = 0;
+
+    if (heap.heap_start == NULL)
+    {
+        if(SERIAL_DEBUG) SERIAL_DEBUG->printf("--- HEAP NOT INITIALISED ---\n");
+        return;
+    }
+
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("heap_start : %p\n", heap.heap_start);
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("heap_end   : %p\n", heap.heap_end);
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("heap_size  : %d\n", (int)heap.heap_end - (int)heap.heap_start);
+
+	// Disable IRQ temporarily to ensure no race conditions!
+    __disable_irq();
+
+	block = heap.heap_start;
+	while (block < heap.heap_end)
+	{
+		blockSize = *block & ~MICROBIT_HEAP_BLOCK_FREE;
+        if(SERIAL_DEBUG) SERIAL_DEBUG->printf("[%c:%d] ", *block & MICROBIT_HEAP_BLOCK_FREE ? 'F' : 'U', blockSize*4);
+        if (cols++ == 20)
+        {
+            if(SERIAL_DEBUG) SERIAL_DEBUG->printf("\n");
+            cols = 0;
+        }
+
+        if (*block & MICROBIT_HEAP_BLOCK_FREE)
+            totalFreeBlock += blockSize;
+        else
+            totalUsedBlock += blockSize;
+
+		block += blockSize;
+    }
+
+	// Enable Interrupts
+    __enable_irq();
+
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("\n");
+
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("mb_total_free : %d\n", totalFreeBlock*4);
+    if(SERIAL_DEBUG) SERIAL_DEBUG->printf("mb_total_used : %d\n", totalUsedBlock*4);
+}
+
+
+// Diagnostics function. Displays a usage summary about all initialised heaps.
+void microbit_heap_print()
+{
+    for (int i=0; i < heap_count; i++)
+    {
+        if(SERIAL_DEBUG) SERIAL_DEBUG->printf("\nHEAP %d: \n", i);
+        microbit_heap_print(heap[i]);
+    }
+}
+#endif
+
+void microbit_initialise_heap(HeapDefinition &heap)
+{
+    // Simply mark the entire heap as free.
+    *heap.heap_start = ((uint32_t) heap.heap_end - (uint32_t) heap.heap_start) / MICROBIT_HEAP_BLOCK_SIZE;
+    *heap.heap_start |= MICROBIT_HEAP_BLOCK_FREE;
+}
+
+/**
+  * Create and initialise a given memory region as for heap storage.
+  * After this is called, any future calls to malloc, new, free or delete may use the new heap.
+  * The heap allocator will attempt to allocate memory from heaps in the order that they are created.
+  * i.e. memory will be allocated from first heap created until it is full, then the second heap, and so on.
+  *
+  * @param start The start address of memory to use as a heap region.
+  *
+  * @param end The end address of memory to use as a heap region.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
+  *
+  * @note Only code that #includes MicroBitHeapAllocator.h will use this heap. This includes all micro:bit runtime
+  * code, and user code targetting the runtime. External code can choose to include this file, or
+  * simply use the standard heap.
+  */
+int microbit_create_heap(uint32_t start, uint32_t end)
+{
+    // Ensure we don't exceed the maximum number of heap segments.
+    if (heap_count == MICROBIT_MAXIMUM_HEAPS)
+        return MICROBIT_NO_RESOURCES;
+
+    // Sanity check. Ensure range is valid, large enough and word aligned.
+    if (end <= start || end - start < MICROBIT_HEAP_BLOCK_SIZE*2 || end % 4 != 0 || start % 4 != 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+	// Disable IRQ temporarily to ensure no race conditions!
+    __disable_irq();
+
+    // Record the dimensions of this new heap
+    heap[heap_count].heap_start = (uint32_t *)start;
+    heap[heap_count].heap_end = (uint32_t *)end;
+
+    // Initialise the heap as being completely empty and available for use.
+    microbit_initialise_heap(heap[heap_count]);
+    heap_count++;
+
+	// Enable Interrupts
+    __enable_irq();
+
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+    microbit_heap_print();
+#endif
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Create and initialise a heap region within the current the heap region specified
+  * by the linker script.
+  *
+  * If the requested amount is not available, then the amount requested will be reduced
+  * automatically to fit the space available.
+  *
+  * @param ratio The proportion of the underlying heap to allocate.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if the heap could not be allocated.
+  */
+int microbit_create_nested_heap(float ratio)
+{
+    uint32_t length;
+    void *p;
+
+    if (ratio <= 0.0 || ratio > 1.0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Snapshot something at the top of the main heap.
+    p = native_malloc(sizeof(uint32_t));
+
+    // Estimate the size left in our heap, taking care to ensure it lands on a word boundary.
+    length = (uint32_t) (((float)(MICROBIT_HEAP_END - (uint32_t)p)) * ratio);
+    length &= 0xFFFFFFFC;
+
+    // Release our reference pointer.
+    native_free(p);
+    p = NULL;
+
+    // Allocate memory for our heap.
+    // We iteratively reduce the size of memory are allocate until it fits within available space.
+    while (p == NULL)
+    {
+        p = native_malloc(length);
+        if (p == NULL)
+        {
+            length -= 32;
+            if (length <= 0)
+                return MICROBIT_NO_RESOURCES;
+        }
+    }
+
+    uint32_t start = (uint32_t) p;
+    microbit_create_heap(start, start + length);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Attempt to allocate a given amount of memory from any of our configured heap areas.
+  *
+  * @param size The amount of memory, in bytes, to allocate.
+  *
+  * @return A pointer to the allocated memory, or NULL if insufficient memory is available.
+  */
+void *microbit_malloc(size_t size, HeapDefinition &heap)
+{
+	uint32_t	blockSize = 0;
+	uint32_t	blocksNeeded = size % MICROBIT_HEAP_BLOCK_SIZE == 0 ? size / MICROBIT_HEAP_BLOCK_SIZE : size / MICROBIT_HEAP_BLOCK_SIZE + 1;
+	uint32_t	*block;
+	uint32_t	*next;
+
+	if (size <= 0)
+		return NULL;
+
+	// Account for the index block;
+	blocksNeeded++;
+
+	// Disable IRQ temporarily to ensure no race conditions!
+    __disable_irq();
+
+	// We implement a first fit algorithm with cache to handle rapid churn...
+    // We also defragment free blocks as we search, to optimise this and future searches.
+	block = heap.heap_start;
+	while (block < heap.heap_end)
+	{
+		// If the block is used, then keep looking.
+		if(!(*block & MICROBIT_HEAP_BLOCK_FREE))
+		{
+			block += *block;
+			continue;
+		}
+
+		blockSize = *block & ~MICROBIT_HEAP_BLOCK_FREE;
+
+		// We have a free block. Let's see if the subsequent ones are too. If so, we can merge...
+		next = block + blockSize;
+
+		while (*next & MICROBIT_HEAP_BLOCK_FREE)
+		{
+			if (next >= heap.heap_end)
+				break;
+
+			// We can merge!
+			blockSize += (*next & ~MICROBIT_HEAP_BLOCK_FREE);
+			*block = blockSize | MICROBIT_HEAP_BLOCK_FREE;
+
+			next = block + blockSize;
+		}
+
+		// We have a free block. Let's see if it's big enough.
+        // If so, we have a winner.
+		if (blockSize >= blocksNeeded)
+			break;
+
+		// Otherwise, keep looking...
+		block += blockSize;
+	}
+
+	// We're full!
+	if (block >= heap.heap_end)
+    {
+        __enable_irq();
+        return NULL;
+    }
+
+	// If we're at the end of memory or have very near match then mark the whole segment as in use.
+	if (blockSize <= blocksNeeded+1 || block+blocksNeeded+1 >= heap.heap_end)
+	{
+		// Just mark the whole block as used.
+		*block &= ~MICROBIT_HEAP_BLOCK_FREE;
+	}
+	else
+	{
+		// We need to split the block.
+		uint32_t *splitBlock = block + blocksNeeded;
+		*splitBlock = blockSize - blocksNeeded;
+		*splitBlock |= MICROBIT_HEAP_BLOCK_FREE;
+
+		*block = blocksNeeded;
+	}
+
+	// Enable Interrupts
+    __enable_irq();
+
+	return block+1;
+}
+
+/**
+  * Release a given area of memory from the heap.
+  *
+  * @param mem The memory area to release.
+  */
+void *microbit_malloc(size_t size)
+{
+    void *p;
+
+    // Assign the memory from the first heap created that has space.
+    for (int i=0; i < heap_count; i++)
+    {
+        p = microbit_malloc(size, heap[i]);
+        if (p != NULL)
+        {
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+            if(SERIAL_DEBUG) SERIAL_DEBUG->printf("microbit_malloc: ALLOCATED: %d [%p]\n", size, p);
+#endif
+            return p;
+        }
+    }
+
+    // If we reach here, then either we have no memory available, or our heap spaces
+    // haven't been initialised. Either way, we try the native allocator.
+
+    p = native_malloc(size);
+    if (p != NULL)
+    {
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+        // Keep everything trasparent if we've not been initialised yet
+        if (heap_count > 0)
+            if(SERIAL_DEBUG) SERIAL_DEBUG->printf("microbit_malloc: NATIVE ALLOCATED: %d [%p]\n", size, p);
+#endif
+        return p;
+    }
+
+    // We're totally out of options (and memory!).
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+    // Keep everything transparent if we've not been initialised yet
+    if (heap_count > 0)
+        if(SERIAL_DEBUG) SERIAL_DEBUG->printf("microbit_malloc: OUT OF MEMORY [%d]\n", size);
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_PANIC_HEAP_FULL)
+	microbit_panic(MICROBIT_OOM);
+#endif
+
+    return NULL;
+}
+
+/**
+  * Release a given area of memory from the heap.
+  *
+  * @param mem The memory area to release.
+  */
+void microbit_free(void *mem)
+{
+	uint32_t	*memory = (uint32_t *)mem;
+	uint32_t	*cb = memory-1;
+
+#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
+    if (heap_count > 0)
+        if(SERIAL_DEBUG) SERIAL_DEBUG->printf("microbit_free:   %p\n", mem);
+#endif
+    // Sanity check.
+	if (memory == NULL)
+       return;
+
+    // If this memory was created from a heap registered with us, free it.
+    for (int i=0; i < heap_count; i++)
+    {
+        if(memory > heap[i].heap_start && memory < heap[i].heap_end)
+        {
+            // The memory block given is part of this heap, so we can simply
+	        // flag that this memory area is now free, and we're done.
+	        *cb |= MICROBIT_HEAP_BLOCK_FREE;
+            return;
+        }
+    }
+
+    // If we reach here, then the memory is not part of any registered heap.
+    // Forward it to the native heap allocator, and let nature take its course...
+    native_free(mem);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitListener.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,122 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  *	This structure defines a MicroBitListener used to invoke functions, or member
+  * functions if an instance of EventModel receives an event whose id and value
+  * match this MicroBitListener's id and value.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitListener.h"
+
+/**
+  * Constructor.
+  *
+  * Create a new Message Bus Listener.
+  *
+  * @param id The ID of the component you want to listen to.
+  *
+  * @param value The event value you would like to listen to from that component
+  *
+  * @param handler A function pointer to call when the event is detected.
+  *
+  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+  * to be tuned.
+  */
+MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent), uint16_t flags)
+{
+	this->id = id;
+	this->value = value;
+	this->cb = handler;
+	this->cb_arg = NULL;
+    this->flags = flags;
+	this->next = NULL;
+    this->evt_queue = NULL;
+}
+
+/**
+  * Constructor.
+  *
+  * Create a new Message Bus Listener, this constructor accepts an additional
+  * parameter "arg", which is passed to the handler.
+  *
+  * @param id The ID of the component you want to listen to.
+  *
+  * @param value The event value you would like to listen to from that component
+  *
+  * @param handler A function pointer to call when the event is detected.
+  *
+  * @param arg A pointer to some data that will be given to the handler.
+  *
+  * @param flags User specified, implementation specific flags, that allow behaviour of this events listener
+  * to be tuned.
+  */
+MicroBitListener::MicroBitListener(uint16_t id, uint16_t value, void (*handler)(MicroBitEvent, void *), void* arg, uint16_t flags)
+{
+	this->id = id;
+	this->value = value;
+	this->cb_param = handler;
+	this->cb_arg = arg;
+    this->flags = flags | MESSAGE_BUS_LISTENER_PARAMETERISED;
+	this->next = NULL;
+    this->evt_queue = NULL;
+}
+
+/**
+  * Destructor. Ensures all resources used by this listener are freed.
+  */
+MicroBitListener::~MicroBitListener()
+{
+    if(this->flags & MESSAGE_BUS_LISTENER_METHOD)
+        delete cb_method;
+}
+
+/**
+  * Queues and event up to be processed.
+  *
+  * @param e The event to queue
+  */
+void MicroBitListener::queue(MicroBitEvent e)
+{
+    int queueDepth;
+
+    MicroBitEventQueueItem *p = evt_queue;
+
+    if (evt_queue == NULL)
+        evt_queue = new MicroBitEventQueueItem(e);
+    else
+    {
+        queueDepth = 1;
+
+        while (p->next != NULL)
+        {
+            p = p->next;
+            queueDepth++;
+        }
+
+        if (queueDepth < MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH)
+            p->next = new MicroBitEventQueueItem(e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/core/MicroBitSystemTimer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,216 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Definitions for the MicroBit system timer.
+  *
+  * This module provides:
+  *
+  * 1) a concept of global system time since power up
+  * 2) a simple periodic multiplexing API for the underlying mbed implementation.
+  *
+  * The latter is useful to avoid costs associated with multiple mbed Ticker instances
+  * in microbit-dal components, as each incurs a significant additional RAM overhead (circa 80 bytes).
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitSystemTimer.h"
+#include "ErrorNo.h"
+
+/*
+ * Time since power on. Measured in milliseconds.
+ * When stored as an unsigned long, this gives us approx 50 days between rollover, which is ample. :-)
+ */
+static uint64_t time_us = 0;
+static unsigned int tick_period = 0;
+
+// Array of components which are iterated during a system tick
+static MicroBitComponent* systemTickComponents[MICROBIT_SYSTEM_COMPONENTS];
+
+// Periodic callback interrupt
+static Ticker *ticker = NULL;
+
+// System timer.
+static Timer *timer = NULL;
+
+
+/**
+  * Initialises a system wide timer, used to drive the various components used in the runtime.
+  *
+  * This must be called before any components register to receive periodic periodic callbacks.
+  *
+  * @param timer_period The initial period between interrupts, in millseconds.
+  *
+  * @return MICROBIT_OK on success.
+  */
+int system_timer_init(int period)
+{
+    if (ticker == NULL)
+        ticker = new Ticker();
+
+    if (timer == NULL)
+    {
+        timer = new Timer();
+        timer->start();
+    }
+
+    return system_timer_set_period(period);
+}
+
+/**
+  * Reconfigures the system wide timer to the given period in milliseconds.
+  *
+  * @param period the new period of the timer in milliseconds
+  *
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if period < 1
+  */
+int system_timer_set_period(int period)
+{
+    if (period < 1)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If a timer is already running, ensure it is disabled before reconfiguring.
+    if (tick_period)
+        ticker->detach();
+
+	// register a period callback to drive the scheduler and any other registered components.
+    tick_period = period;
+    ticker->attach_us(system_timer_tick, period * 1000);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Accessor to obtain the current tick period in milliseconds
+  *
+  * @return the current tick period in milliseconds
+  */
+int system_timer_get_period()
+{
+    return tick_period;
+}
+
+/**
+  * Updates the current time in microseconds, since power on.
+  *
+  * If the mbed Timer hasn't been initialised, it will be initialised
+  * on the first call to this function.
+  */
+void update_time()
+{
+    // If we haven't been initialized, bring up the timer with the default period.
+    if (timer == NULL || ticker == NULL)
+        system_timer_init(SYSTEM_TICK_PERIOD_MS);
+
+    time_us += timer->read_us();
+    timer->reset();
+}
+
+/**
+  * Determines the time since the device was powered on.
+  *
+  * @return the current time since power on in milliseconds
+  */
+uint64_t system_timer_current_time()
+{
+    return system_timer_current_time_us() / 1000;
+}
+
+/**
+  * Determines the time since the device was powered on.
+  *
+  * @return the current time since power on in microseconds
+  */
+uint64_t system_timer_current_time_us()
+{
+    update_time();
+    return time_us;
+}
+
+/**
+  * Timer callback. Called from interrupt context, once per period.
+  *
+  * Simply checks to determine if any fibers blocked on the sleep queue need to be woken up
+  * and made runnable.
+  */
+void system_timer_tick()
+{
+    update_time();
+
+    // Update any components registered for a callback
+    for(int i = 0; i < MICROBIT_SYSTEM_COMPONENTS; i++)
+        if(systemTickComponents[i] != NULL)
+            systemTickComponents[i]->systemTick();
+}
+
+/**
+  * Add a component to the array of system components. This component will then receive
+  * periodic callbacks, once every tick period.
+  *
+  * @param component The component to add.
+  *
+  * @return MICROBIT_OK on success. MICROBIT_NO_RESOURCES is returned if the component array is full.
+  *
+  * @note The callback will be in interrupt context.
+  */
+int system_timer_add_component(MicroBitComponent *component)
+{
+    int i = 0;
+
+    // If we haven't been initialized, bring up the timer with the default period.
+    if (timer == NULL || ticker == NULL)
+        system_timer_init(SYSTEM_TICK_PERIOD_MS);
+
+    while(systemTickComponents[i] != NULL && i < MICROBIT_SYSTEM_COMPONENTS)
+        i++;
+
+    if(i == MICROBIT_SYSTEM_COMPONENTS)
+        return MICROBIT_NO_RESOURCES;
+
+    systemTickComponents[i] = component;
+    return MICROBIT_OK;
+}
+
+/**
+  * Remove a component from the array of system components. This component will no longer receive
+  * periodic callbacks.
+  *
+  * @param component The component to remove.
+  *
+  * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
+  */
+int system_timer_remove_component(MicroBitComponent *component)
+{
+    int i = 0;
+
+    while(systemTickComponents[i] != component && i < MICROBIT_SYSTEM_COMPONENTS)
+        i++;
+
+    if(i == MICROBIT_SYSTEM_COMPONENTS)
+        return MICROBIT_INVALID_PARAMETER;
+
+    systemTickComponents[i] = NULL;
+
+    return MICROBIT_OK;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/DynamicPwm.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,331 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for DynamicPwm.
+  *
+  * This class addresses a few issues found in the underlying libraries.
+  * This provides the ability for a neat, clean swap between PWM channels.
+  */
+
+#include "MicroBitConfig.h"
+#include "DynamicPwm.h"
+#include "MicroBitPin.h"
+#include "ErrorNo.h"
+
+DynamicPwm* DynamicPwm::pwms[NO_PWMS] = { NULL, NULL, NULL };
+
+uint8_t DynamicPwm::lastUsed = NO_PWMS+1; //set it to out of range i.e. 4 so we know it hasn't been used yet.
+
+uint16_t DynamicPwm::sharedPeriod = 0; //set the shared period to an unknown state
+
+/**
+  * Reassigns an already operational PWM channel to the given pin.
+  *
+  * @param pin The desired pin to begin a PWM wave.
+  *
+  * @param oldPin The pin to stop running a PWM wave.
+  *
+  * @param channel_number The GPIOTE channel being used to drive this PWM channel
+  *
+  * TODO: Merge into mbed, at a later date.
+  */
+void gpiote_reinit(PinName pin, PinName oldPin, uint8_t channel_number)
+{
+    // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
+    NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                            | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                            | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                            | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
+                            | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+
+    NRF_GPIO->OUTCLR = (1 << oldPin);
+    NRF_GPIO->OUTCLR = (1 << pin);
+
+    /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
+       If it does not, the channel output inheritance sets the proper level. */
+
+    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
+                                         ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
+                                         ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
+                                         ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos); // ((uint32_t)GPIOTE_CONFIG_OUTINIT_High <<
+                                                                                                             // GPIOTE_CONFIG_OUTINIT_Pos);//
+
+    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
+    __NOP();
+    __NOP();
+    __NOP();
+
+    NRF_TIMER2->CC[channel_number] = 0;
+}
+
+/**
+  * An internal constructor used when allocating a new DynamicPwm instance.
+  *
+  * @param pin the name of the pin for the pwm to target
+  *
+  * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
+  *                    or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
+  */
+DynamicPwm::DynamicPwm(PinName pin, PwmPersistence persistence) : PwmOut(pin)
+{
+    this->flags = persistence;
+}
+
+/**
+  * Redirects the pwm channel to point at a different pin.
+  *
+  * @param pin the desired pin to output a PWM wave.
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  * pwm->redirect(p0); // pwm is now produced on p0
+  * @endcode
+  */
+void DynamicPwm::redirect(PinName pin)
+{
+    gpiote_reinit(pin, _pwm.pin, (uint8_t)_pwm.pwm);
+    this->_pwm.pin = pin;
+}
+
+/**
+  * Creates a new DynamicPwm instance, or reuses an existing instance that
+  * has a persistence level of PWM_PERSISTENCE_TRANSIENT.
+  *
+  * @param pin the name of the pin for the pwm to target
+  *
+  * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
+  *                    or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
+  *
+  * @return a pointer to the first available free pwm channel - or the first one that can be reallocated. If
+  *         no channels are available, NULL is returned.
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  * @endcode
+  */
+DynamicPwm* DynamicPwm::allocate(PinName pin, PwmPersistence persistence)
+{
+    //try to find a blank spot first
+    for(int i = 0; i < NO_PWMS; i++)
+    {
+        if(pwms[i] == NULL)
+        {
+            lastUsed = i;
+            pwms[i] = new DynamicPwm(pin, persistence);
+            return pwms[i];
+        }
+    }
+
+    //no blank spot.. try to find a transient PWM
+    int channelIterator = (lastUsed + 1 > NO_PWMS - 1) ? 0 : lastUsed + 1;
+
+    while(channelIterator != lastUsed)
+    {
+        if(pwms[channelIterator]->flags & PWM_PERSISTENCE_TRANSIENT)
+        {
+            lastUsed = channelIterator;
+            pwms[channelIterator]->flags = persistence;
+            pwms[channelIterator]->redirect(pin);
+            return pwms[channelIterator];
+        }
+
+        channelIterator = (channelIterator + 1 > NO_PWMS - 1) ? 0 : channelIterator + 1;
+    }
+
+    //if we haven't found a free one, we must try to allocate the last used...
+    if(pwms[lastUsed]->flags & PWM_PERSISTENCE_TRANSIENT)
+    {
+        pwms[lastUsed]->flags = persistence;
+        pwms[lastUsed]->redirect(pin);
+        return pwms[lastUsed];
+    }
+
+    //well if we have no transient channels - we can't give any away! :( return null
+    return (DynamicPwm*)NULL;
+}
+
+/**
+  * Frees this DynamicPwm instance for reuse.
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate();
+  * pwm->release();
+  * @endcode
+  */
+void DynamicPwm::release()
+{
+    //free the pwm instance.
+    NRF_GPIOTE->CONFIG[(uint8_t) _pwm.pwm] = 0;
+    pwmout_free(&_pwm);
+    this->flags = PWM_PERSISTENCE_TRANSIENT;
+
+    //set the pointer to this object to null...
+    for(int i =0; i < NO_PWMS; i++)
+        if(pwms[i] == this)
+        {
+            delete pwms[i];
+            pwms[i] = NULL;
+        }
+}
+
+/**
+  * A lightweight wrapper around the super class' write in order to capture the value
+  *
+  * @param value the duty cycle percentage in floating point format.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate();
+  * pwm->write(0.5);
+  * @endcode
+  */
+int DynamicPwm::write(float value){
+
+    if(value < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    PwmOut::write(value);
+    lastValue = value;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Retreives the PinName associated with this DynamicPwm instance.
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  *
+  * // returns the PinName n.
+  * pwm->getPinName();
+  * @endcode
+  *
+  * @note This should be used to check that the DynamicPwm instance has not
+  *       been reallocated for use in another part of a program.
+  */
+PinName DynamicPwm::getPinName()
+{
+    return _pwm.pin;
+}
+
+/**
+  * Retreives the last value that has been written to this DynamicPwm instance.
+  * in the range 0 - 1023 inclusive.
+  *
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  * pwm->write(0.5);
+  *
+  * // will return 512.
+  * pwm->getValue();
+  * @endcode
+  */
+int DynamicPwm::getValue()
+{
+    return (float)lastValue * float(MICROBIT_PIN_MAX_OUTPUT);
+}
+
+/**
+  * Retreives the current period in use by the entire PWM module in microseconds.
+  *
+  * Example:
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  * pwm->getPeriod();
+  * @endcode
+  */
+int DynamicPwm::getPeriodUs()
+{
+    return sharedPeriod;
+}
+
+/**
+  * Retreives the current period in use by the entire PWM module in milliseconds.
+  *
+  * Example:
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  * pwm->setPeriodUs(20000);
+  *
+  * // will return 20000
+  * pwm->getPeriod();
+  * @endcode
+  */
+int DynamicPwm::getPeriod()
+{
+    return getPeriodUs() / 1000;
+}
+
+/**
+  * Sets the period used by the WHOLE PWM module.
+  *
+  * @param period the desired period in microseconds.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
+  *
+  * Example:
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  *
+  * // period now is 20ms
+  * pwm->setPeriodUs(20000);
+  * @endcode
+  *
+  * @note Any changes to the period will AFFECT ALL CHANNELS.
+  */
+int DynamicPwm::setPeriodUs(int period)
+{
+    if(period < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //#HACK this forces mbed to update the pulse width calculation.
+    period_us(period);
+    write(lastValue);
+    sharedPeriod = period;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Sets the period used by the WHOLE PWM module. Any changes to the period will AFFECT ALL CHANNELS.
+  *
+  * @param period the desired period in milliseconds.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
+  *
+  * Example:
+  * @code
+  * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
+  *
+  * // period now is 20ms
+  * pwm->setPeriod(20);
+  * @endcode
+  */
+int DynamicPwm::setPeriod(int period)
+{
+    return setPeriodUs(period * 1000);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitAccelerometer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,756 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+ * Class definition for MicroBit Accelerometer.
+ *
+ * Represents an implementation of the Freescale MMA8653 3 axis accelerometer
+ * Also includes basic data caching and on demand activation.
+ */
+#include "MicroBitConfig.h"
+#include "MicroBitAccelerometer.h"
+#include "ErrorNo.h"
+#include "MicroBitConfig.h"
+#include "MicroBitEvent.h"
+#include "MicroBitCompat.h"
+#include "MicroBitFiber.h"
+
+/**
+  * Configures the accelerometer for G range and sample rate defined
+  * in this object. The nearest values are chosen to those defined
+  * that are supported by the hardware. The instance variables are then
+  * updated to reflect reality.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured.
+  */
+int MicroBitAccelerometer::configure()
+{
+    const MMA8653SampleRangeConfig  *actualSampleRange;
+    const MMA8653SampleRateConfig  *actualSampleRate;
+    int result;
+
+    // First find the nearest sample rate to that specified.
+    actualSampleRate = &MMA8653SampleRate[MMA8653_SAMPLE_RATES-1];
+    for (int i=MMA8653_SAMPLE_RATES-1; i>=0; i--)
+    {
+        if(MMA8653SampleRate[i].sample_period < this->samplePeriod * 1000)
+            break;
+
+        actualSampleRate = &MMA8653SampleRate[i];
+    }
+
+    // Now find the nearest sample range to that specified.
+    actualSampleRange = &MMA8653SampleRange[MMA8653_SAMPLE_RANGES-1];
+    for (int i=MMA8653_SAMPLE_RANGES-1; i>=0; i--)
+    {
+        if(MMA8653SampleRange[i].sample_range < this->sampleRange)
+            break;
+
+        actualSampleRange = &MMA8653SampleRange[i];
+    }
+
+    // OK, we have the correct data. Update our local state.
+    this->samplePeriod = actualSampleRate->sample_period / 1000;
+    this->sampleRange = actualSampleRange->sample_range;
+
+    // Now configure the accelerometer accordingly.
+    // First place the device into standby mode, so it can be configured.
+    result = writeCommand(MMA8653_CTRL_REG1, 0x00);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    // Enable high precisiosn mode. This consumes a bit more power, but still only 184 uA!
+    result = writeCommand(MMA8653_CTRL_REG2, 0x10);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    // Enable the INT1 interrupt pin.
+    result = writeCommand(MMA8653_CTRL_REG4, 0x01);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    // Select the DATA_READY event source to be routed to INT1
+    result = writeCommand(MMA8653_CTRL_REG5, 0x01);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    // Configure for the selected g range.
+    result = writeCommand(MMA8653_XYZ_DATA_CFG, actualSampleRange->xyz_data_cfg);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    // Bring the device back online, with 10bit wide samples at the requested frequency.
+    result = writeCommand(MMA8653_CTRL_REG1, actualSampleRate->ctrl_reg1 | 0x01);
+    if (result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Issues a standard, 2 byte I2C command write to the accelerometer.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the register to write to.
+  *
+  * @param value The value to write.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed.
+  */
+int MicroBitAccelerometer::writeCommand(uint8_t reg, uint8_t value)
+{
+    uint8_t command[2];
+    command[0] = reg;
+    command[1] = value;
+
+    return i2c.write(address, (const char *)command, 2);
+}
+
+/**
+  * Issues a read command, copying data into the specified buffer.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the register to access.
+  *
+  * @param buffer Memory area to read the data into.
+  *
+  * @param length The number of bytes to read.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed.
+  */
+int MicroBitAccelerometer::readCommand(uint8_t reg, uint8_t* buffer, int length)
+{
+    int result;
+
+    if (buffer == NULL || length <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    result = i2c.write(address, (const char *)&reg, 1, true);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    result = i2c.read(address, (char *)buffer, length);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Constructor.
+  * Create a software abstraction of an accelerometer.
+  *
+  * @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer.
+  *
+  * @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR.
+  *
+  * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER
+  *
+  * @code
+  * MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0);
+  *
+  * MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c);
+  * @endcode
+ */
+MicroBitAccelerometer::MicroBitAccelerometer(MicroBitI2C& _i2c, uint16_t address, uint16_t id) : sample(), int1(MICROBIT_PIN_ACCEL_DATA_READY), i2c(_i2c)
+{
+    // Store our identifiers.
+    this->id = id;
+    this->status = 0;
+    this->address = address;
+
+    // Update our internal state for 50Hz at +/- 2g (50Hz has a period af 20ms).
+    this->samplePeriod = 20;
+    this->sampleRange = 2;
+
+    // Initialise gesture history
+    this->sigma = 0;
+    this->impulseSigma = 0;
+    this->lastGesture = MICROBIT_ACCELEROMETER_EVT_NONE;
+    this->currentGesture = MICROBIT_ACCELEROMETER_EVT_NONE;
+    this->shake.x = 0;
+    this->shake.y = 0;
+    this->shake.z = 0;
+    this->shake.count = 0;
+    this->shake.timer = 0;
+    this->shake.impulse_3 = 1;
+    this->shake.impulse_6 = 1;
+    this->shake.impulse_8 = 1;
+
+    // Configure and enable the accelerometer.
+    if (this->configure() == MICROBIT_OK)
+        status |= MICROBIT_COMPONENT_RUNNING;
+}
+
+/**
+  * Attempts to read the 8 bit ID from the accelerometer, this can be used for
+  * validation purposes.
+  *
+  * @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails.
+  *
+  * @code
+  * accelerometer.whoAmI();
+  * @endcode
+  */
+int MicroBitAccelerometer::whoAmI()
+{
+    uint8_t data;
+    int result;
+
+    result = readCommand(MMA8653_WHOAMI, &data, 1);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    return (int)data;
+}
+
+/**
+  * Reads the acceleration data from the accelerometer, and stores it in our buffer.
+  * This only happens if the accelerometer indicates that it has new data via int1.
+  *
+  * On first use, this member function will attempt to add this component to the
+  * list of fiber components in order to constantly update the values stored
+  * by this object.
+  *
+  * This technique is called lazy instantiation, and it means that we do not
+  * obtain the overhead from non-chalantly adding this component to fiber components.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails.
+  */
+int MicroBitAccelerometer::updateSample()
+{
+    if(!(status & MICROBIT_ACCEL_ADDED_TO_IDLE))
+    {
+        fiber_add_idle_component(this);
+        status |= MICROBIT_ACCEL_ADDED_TO_IDLE;
+    }
+
+    // Poll interrupt line from accelerometer.
+    // n.b. Default is Active LO. Interrupt is cleared in data read.
+    if(!int1)
+    {
+        int8_t data[6];
+        int result;
+
+        result = readCommand(MMA8653_OUT_X_MSB, (uint8_t *)data, 6);
+        if (result !=0)
+            return MICROBIT_I2C_ERROR;
+
+        // read MSB values...
+        sample.x = data[0];
+        sample.y = data[2];
+        sample.z = data[4];
+
+        // Normalize the data in the 0..1024 range.
+        sample.x *= 8;
+        sample.y *= 8;
+        sample.z *= 8;
+
+#if CONFIG_ENABLED(USE_ACCEL_LSB)
+        // Add in LSB values.
+        sample.x += (data[1] / 64);
+        sample.y += (data[3] / 64);
+        sample.z += (data[5] / 64);
+#endif
+
+        // Scale into millig (approx!)
+        sample.x *= this->sampleRange;
+        sample.y *= this->sampleRange;
+        sample.z *= this->sampleRange;
+
+        // Indicate that pitch and roll data is now stale, and needs to be recalculated if needed.
+        status &= ~MICROBIT_ACCEL_PITCH_ROLL_VALID;
+
+        // Update gesture tracking
+        updateGesture();
+
+        // Indicate that a new sample is available
+        MicroBitEvent e(id, MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE);
+    }
+
+    return MICROBIT_OK;
+};
+
+/**
+  * A service function.
+  * It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2).
+  * It does not, however, square root the result, as this is a relatively high cost operation.
+  *
+  * This is left to application code should it be needed.
+  *
+  * @return the sum of the square of the acceleration of the device across all axes.
+  */
+int MicroBitAccelerometer::instantaneousAccelerationSquared()
+{
+    updateSample();
+
+    // Use pythagoras theorem to determine the combined force acting on the device.
+    return (int)sample.x*(int)sample.x + (int)sample.y*(int)sample.y + (int)sample.z*(int)sample.z;
+}
+
+/**
+ * Service function.
+ * Determines a 'best guess' posture of the device based on instantaneous data.
+ *
+ * This makes no use of historic data, and forms the input to the filter implemented in updateGesture().
+ *
+ * @return A 'best guess' of the current posture of the device, based on instanataneous data.
+ */
+uint16_t MicroBitAccelerometer::instantaneousPosture()
+{
+    bool shakeDetected = false;
+
+    // Test for shake events.
+    // We detect a shake by measuring zero crossings in each axis. In other words, if we see a strong acceleration to the left followed by
+    // a strong acceleration to the right, then we can infer a shake. Similarly, we can do this for each axis (left/right, up/down, in/out).
+    //
+    // If we see enough zero crossings in succession (MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD), then we decide that the device
+    // has been shaken.
+    if ((getX() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.x) || (getX() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.x))
+    {
+        shakeDetected = true;
+        shake.x = !shake.x;
+    }
+
+    if ((getY() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.y) || (getY() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.y))
+    {
+        shakeDetected = true;
+        shake.y = !shake.y;
+    }
+
+    if ((getZ() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.z) || (getZ() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.z))
+    {
+        shakeDetected = true;
+        shake.z = !shake.z;
+    }
+
+    // If we detected a zero crossing in this sample period, count this.
+    if (shakeDetected && shake.count < MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD)
+    {
+        shake.count++;
+  
+        if (shake.count == 1)
+            shake.timer = 0;
+
+        if (shake.count == MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD)
+        {
+            shake.shaken = 1;
+            shake.timer = 0;
+            return MICROBIT_ACCELEROMETER_EVT_SHAKE;
+        }
+    }
+
+    // measure how long we have been detecting a SHAKE event.
+    if (shake.count > 0)
+    {
+        shake.timer++;
+
+        // If we've issued a SHAKE event already, and sufficient time has assed, allow another SHAKE event to be issued.
+        if (shake.shaken && shake.timer >= MICROBIT_ACCELEROMETER_SHAKE_RTX)
+        {
+            shake.shaken = 0;
+            shake.timer = 0;
+            shake.count = 0;
+        }
+
+        // Decay our count of zero crossings over time. We don't want them to accumulate if the user performs slow moving motions.
+        else if (!shake.shaken && shake.timer >= MICROBIT_ACCELEROMETER_SHAKE_DAMPING)
+        {
+            shake.timer = 0;
+            if (shake.count > 0)
+                shake.count--;
+        }
+    }
+
+    if (instantaneousAccelerationSquared() < MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD)
+        return MICROBIT_ACCELEROMETER_EVT_FREEFALL;
+
+    // Determine our posture.
+    if (getX() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_TILT_LEFT;
+
+    if (getX() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT;
+
+    if (getY() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_TILT_DOWN;
+
+    if (getY() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_TILT_UP;
+
+    if (getZ() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_FACE_UP;
+
+    if (getZ() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE))
+        return MICROBIT_ACCELEROMETER_EVT_FACE_DOWN;
+
+    return MICROBIT_ACCELEROMETER_EVT_NONE;
+}
+
+/**
+  * Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote
+  * stability.
+  */
+void MicroBitAccelerometer::updateGesture()
+{
+    // Check for High/Low G force events - typically impulses, impacts etc.
+    // Again, during such spikes, these event take priority of the posture of the device.
+    // For these events, we don't perform any low pass filtering.
+    int force = instantaneousAccelerationSquared();
+
+    if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD)
+    {
+        if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD && !shake.impulse_3)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_3G);
+            shake.impulse_3 = 1;
+        }
+        if (force > MICROBIT_ACCELEROMETER_6G_THRESHOLD && !shake.impulse_6)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_6G);
+            shake.impulse_6 = 1;
+        }
+        if (force > MICROBIT_ACCELEROMETER_8G_THRESHOLD && !shake.impulse_8)
+        {
+            MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_8G);
+            shake.impulse_8 = 1;
+        }
+
+        impulseSigma = 0;
+    }
+
+    // Reset the impulse event onve the acceleration has subsided.
+    if (impulseSigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
+        impulseSigma++;
+    else
+        shake.impulse_3 = shake.impulse_6 = shake.impulse_8 = 0;
+
+
+    // Determine what it looks like we're doing based on the latest sample...
+    uint16_t g = instantaneousPosture();
+
+    if (g == MICROBIT_ACCELEROMETER_EVT_SHAKE)
+    {
+        MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE);
+        return;
+    }
+
+    // Perform some low pass filtering to reduce jitter from any detected effects
+    if (g == currentGesture)
+    {
+        if (sigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
+            sigma++;
+    }
+    else
+    {
+        currentGesture = g;
+        sigma = 0;
+    }
+
+    // If we've reached threshold, update our record and raise the relevant event...
+    if (currentGesture != lastGesture && sigma >= MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
+    {
+        lastGesture = currentGesture;
+        MicroBitEvent e(MICROBIT_ID_GESTURE, lastGesture);
+    }
+}
+
+/**
+  * Attempts to set the sample rate of the accelerometer to the specified value (in ms).
+  *
+  * @param period the requested time between samples, in milliseconds.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
+  *
+  * @code
+  * // sample rate is now 20 ms.
+  * accelerometer.setPeriod(20);
+  * @endcode
+  *
+  * @note The requested rate may not be possible on the hardware. In this case, the
+  * nearest lower rate is chosen.
+  */
+int MicroBitAccelerometer::setPeriod(int period)
+{
+    this->samplePeriod = period;
+    return this->configure();
+}
+
+/**
+  * Reads the currently configured sample rate of the accelerometer.
+  *
+  * @return The time between samples, in milliseconds.
+  */
+int MicroBitAccelerometer::getPeriod()
+{
+    return (int)samplePeriod;
+}
+
+/**
+  * Attempts to set the sample range of the accelerometer to the specified value (in g).
+  *
+  * @param range The requested sample range of samples, in g.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails.
+  *
+  * @code
+  * // the sample range of the accelerometer is now 8G.
+  * accelerometer.setRange(8);
+  * @endcode
+  *
+  * @note The requested range may not be possible on the hardware. In this case, the
+  * nearest lower range is chosen.
+  */
+int MicroBitAccelerometer::setRange(int range)
+{
+    this->sampleRange = range;
+    return this->configure();
+}
+
+/**
+  * Reads the currently configured sample range of the accelerometer.
+  *
+  * @return The sample range, in g.
+  */
+int MicroBitAccelerometer::getRange()
+{
+    return (int)sampleRange;
+}
+
+/**
+  * Reads the value of the X axis from the latest update retrieved from the accelerometer.
+  *
+  * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+  *
+  * @return The force measured in the X axis, in milli-g.
+  *
+  * @code
+  * accelerometer.getX();
+  * @endcode
+  */
+int MicroBitAccelerometer::getX(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case SIMPLE_CARTESIAN:
+            return -sample.x;
+
+        case NORTH_EAST_DOWN:
+            return sample.y;
+
+        case RAW:
+        default:
+            return sample.x;
+    }
+}
+
+/**
+  * Reads the value of the Y axis from the latest update retrieved from the accelerometer.
+  *
+  * @return The force measured in the Y axis, in milli-g.
+  *
+  * @code
+  * accelerometer.getY();
+  * @endcode
+  */
+int MicroBitAccelerometer::getY(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case SIMPLE_CARTESIAN:
+            return -sample.y;
+
+        case NORTH_EAST_DOWN:
+            return -sample.x;
+
+        case RAW:
+        default:
+            return sample.y;
+    }
+}
+
+/**
+  * Reads the value of the Z axis from the latest update retrieved from the accelerometer.
+  *
+  * @return The force measured in the Z axis, in milli-g.
+  *
+  * @code
+  * accelerometer.getZ();
+  * @endcode
+  */
+int MicroBitAccelerometer::getZ(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case NORTH_EAST_DOWN:
+            return -sample.z;
+
+        case SIMPLE_CARTESIAN:
+        case RAW:
+        default:
+            return sample.z;
+    }
+}
+
+/**
+  * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
+  *
+  * @return The pitch of the device, in degrees.
+  *
+  * @code
+  * accelerometer.getPitch();
+  * @endcode
+  */
+int MicroBitAccelerometer::getPitch()
+{
+    return (int) ((360*getPitchRadians()) / (2*PI));
+}
+
+/**
+  * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer.
+  *
+  * @return The pitch of the device, in radians.
+  *
+  * @code
+  * accelerometer.getPitchRadians();
+  * @endcode
+  */
+float MicroBitAccelerometer::getPitchRadians()
+{
+    if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID))
+        recalculatePitchRoll();
+
+    return pitch;
+}
+
+/**
+  * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
+  *
+  * @return The roll of the device, in degrees.
+  *
+  * @code
+  * accelerometer.getRoll();
+  * @endcode
+  */
+int MicroBitAccelerometer::getRoll()
+{
+    return (int) ((360*getRollRadians()) / (2*PI));
+}
+
+/**
+  * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer.
+  *
+  * @return The roll of the device, in radians.
+  *
+  * @code
+  * accelerometer.getRollRadians();
+  * @endcode
+  */
+float MicroBitAccelerometer::getRollRadians()
+{
+    if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID))
+        recalculatePitchRoll();
+
+    return roll;
+}
+
+/**
+  * Recalculate roll and pitch values for the current sample.
+  *
+  * @note We only do this at most once per sample, as the necessary trigonemteric functions are rather
+  *       heavyweight for a CPU without a floating point unit.
+  */
+void MicroBitAccelerometer::recalculatePitchRoll()
+{
+    double x = (double) getX(NORTH_EAST_DOWN);
+    double y = (double) getY(NORTH_EAST_DOWN);
+    double z = (double) getZ(NORTH_EAST_DOWN);
+
+    roll = atan2(y, z);
+    pitch = atan(-x / (y*sin(roll) + z*cos(roll)));
+
+    status |= MICROBIT_ACCEL_PITCH_ROLL_VALID;
+}
+
+/**
+  * Retrieves the last recorded gesture.
+  *
+  * @return The last gesture that was detected.
+  *
+  * Example:
+  * @code
+  * MicroBitDisplay display;
+  *
+  * if (accelerometer.getGesture() == SHAKE)
+  *     display.scroll("SHAKE!");
+  * @endcode
+  */
+uint16_t MicroBitAccelerometer::getGesture()
+{
+    return lastGesture;
+}
+
+/**
+  * A periodic callback invoked by the fiber scheduler idle thread.
+  *
+  * Internally calls updateSample().
+  */
+void MicroBitAccelerometer::idleTick()
+{
+    updateSample();
+}
+
+/**
+  * Destructor for MicroBitAccelerometer, where we deregister from the array of fiber components.
+  */
+MicroBitAccelerometer::~MicroBitAccelerometer()
+{
+    fiber_remove_idle_component(this);
+}
+
+const MMA8653SampleRangeConfig MMA8653SampleRange[MMA8653_SAMPLE_RANGES] = {
+    {2, 0},
+    {4, 1},
+    {8, 2}
+};
+
+const MMA8653SampleRateConfig MMA8653SampleRate[MMA8653_SAMPLE_RATES] = {
+    {1250,      0x00},
+    {2500,      0x08},
+    {5000,      0x10},
+    {10000,     0x18},
+    {20000,     0x20},
+    {80000,     0x28},
+    {160000,    0x30},
+    {640000,    0x38}
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitButton.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,162 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitButton.h"
+#include "MicroBitSystemTimer.h"
+
+/**
+  * Constructor.
+  *
+  * Create a software representation of a button.
+  *
+  * @param name the physical pin on the processor that should be used as input.
+  *
+  * @param id the ID of the new MicroBitButton object.
+  *
+  * @param eventConfiguration Configures the events that will be generated by this MicroBitButton instance.
+  *                           Defaults to MICROBIT_BUTTON_ALL_EVENTS.
+  *
+  * @param mode the configuration of internal pullups/pulldowns, as defined in the mbed PinMode class. PullNone by default.
+  *
+  * @code
+  * buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A);
+  * @endcode
+  */
+MicroBitButton::MicroBitButton(PinName name, uint16_t id, MicroBitButtonEventConfiguration eventConfiguration, PinMode mode) : pin(name, mode)
+{
+    this->id = id;
+    this->name = name;
+    this->eventConfiguration = eventConfiguration;
+    this->downStartTime = 0;
+    this->sigma = 0;
+    system_timer_add_component(this);
+}
+
+/**
+  * Changes the event configuration used by this button to the given MicroBitButtonEventConfiguration.
+  *
+  * All subsequent events generated by this button will then be informed by this configuraiton.
+  *
+  * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
+  *
+  * Example:
+  * @code
+  * // Configure a button to generate all possible events.
+  * buttonA.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
+  *
+  * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
+  * buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+  * @endcode
+  */
+void MicroBitButton::setEventConfiguration(MicroBitButtonEventConfiguration config)
+{
+    this->eventConfiguration = config;
+}
+
+/**
+  * periodic callback from MicroBit system timer.
+  *
+  * Check for state change for this button, and fires various events on a state change.
+  */
+void MicroBitButton::systemTick()
+{
+    //
+    // If the pin is pulled low (touched), increment our culumative counter.
+    // otherwise, decrement it. We're essentially building a lazy follower here.
+    // This makes the output debounced for buttons, and desensitizes touch sensors
+    // (particularly in environments where there is mains noise!)
+    //
+    if(!pin)
+    {
+        if (sigma < MICROBIT_BUTTON_SIGMA_MAX)
+            sigma++;
+    }
+    else
+    {
+        if (sigma > MICROBIT_BUTTON_SIGMA_MIN)
+            sigma--;
+    }
+
+    // Check to see if we have off->on state change.
+    if(sigma > MICROBIT_BUTTON_SIGMA_THRESH_HI && !(status & MICROBIT_BUTTON_STATE))
+    {
+        // Record we have a state change, and raise an event.
+        status |= MICROBIT_BUTTON_STATE;
+        MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_DOWN);
+
+        //Record the time the button was pressed.
+        downStartTime = system_timer_current_time();
+    }
+
+    // Check to see if we have on->off state change.
+    if(sigma < MICROBIT_BUTTON_SIGMA_THRESH_LO && (status & MICROBIT_BUTTON_STATE))
+    {
+        status = 0;
+        MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_UP);
+
+       if (eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS)
+       {
+           //determine if this is a long click or a normal click and send event
+           if((system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_LONG_CLICK_TIME)
+               MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_LONG_CLICK);
+           else
+               MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK);
+       }
+    }
+
+    //if button is pressed and the hold triggered event state is not triggered AND we are greater than the button debounce value
+    if((status & MICROBIT_BUTTON_STATE) && !(status & MICROBIT_BUTTON_STATE_HOLD_TRIGGERED) && (system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_HOLD_TIME)
+    {
+        //set the hold triggered event flag
+        status |= MICROBIT_BUTTON_STATE_HOLD_TRIGGERED;
+
+        //fire hold event
+        MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_HOLD);
+    }
+}
+
+/**
+  * Tests if this Button is currently pressed.
+  *
+  * @code
+  * if(buttonA.isPressed())
+  *     display.scroll("Pressed!");
+  * @endcode
+  *
+  * @return 1 if this button is pressed, 0 otherwise.
+  */
+int MicroBitButton::isPressed()
+{
+    return status & MICROBIT_BUTTON_STATE ? 1 : 0;
+}
+
+/**
+  * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components.
+  */
+MicroBitButton::~MicroBitButton()
+{
+    system_timer_remove_component(this);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitCompass.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,768 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBit Compass.
+  *
+  * Represents an implementation of the Freescale MAG3110 I2C Magnetmometer.
+  * Also includes basic caching, calibration and on demand activation.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitCompass.h"
+#include "MicroBitFiber.h"
+#include "ErrorNo.h"
+
+/**
+  * An initialisation member function used by the many constructors of MicroBitCompass.
+  *
+  * @param id the unique identifier for this compass instance.
+  *
+  * @param address the base address of the magnetometer on the i2c bus.
+  */
+void MicroBitCompass::init(uint16_t id, uint16_t address)
+{
+    this->id = id;
+    this->address = address;
+
+    // Select 10Hz update rate, with oversampling, and enable the device.
+    this->samplePeriod = 100;
+    this->configure();
+
+    // Assume that we have no calibration information.
+    status &= ~MICROBIT_COMPASS_STATUS_CALIBRATED;
+
+    if(this->storage != NULL)
+    {
+        KeyValuePair *calibrationData =  storage->get("compassCal");
+
+        if(calibrationData != NULL)
+        {
+            CompassSample storedSample = CompassSample();
+
+            memcpy(&storedSample, calibrationData->value, sizeof(CompassSample));
+
+            setCalibration(storedSample);
+
+            delete calibrationData;
+        }
+    }
+
+    // Indicate that we're up and running.
+    status |= MICROBIT_COMPONENT_RUNNING;
+}
+
+/**
+  * Constructor.
+  * Create a software representation of an e-compass.
+  *
+  * @param _i2c an instance of i2c, which the compass is accessible from.
+  *
+  * @param _accelerometer an instance of the accelerometer, used for tilt compensation.
+  *
+  * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets.
+  *
+  * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * MicroBitAccelerometer accelerometer(i2c);
+  *
+  * MicroBitStorage storage;
+  *
+  * MicroBitCompass compass(i2c, accelerometer, storage);
+  * @endcode
+  */
+MicroBitCompass::MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, MicroBitStorage& _storage, uint16_t address,  uint16_t id) :
+    average(),
+    sample(),
+    int1(MICROBIT_PIN_COMPASS_DATA_READY),
+    i2c(_i2c),
+    accelerometer(&_accelerometer),
+    storage(&_storage)
+{
+    init(id, address);
+}
+
+/**
+  * Constructor.
+  * Create a software representation of an e-compass.
+  *
+  * @param _i2c an instance of i2c, which the compass is accessible from.
+  *
+  * @param _accelerometer an instance of the accelerometer, used for tilt compensation.
+  *
+  * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * MicroBitAccelerometer accelerometer(i2c);
+  *
+  * MicroBitCompass compass(i2c, accelerometer, storage);
+  * @endcode
+  */
+MicroBitCompass::MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, uint16_t address, uint16_t id) :
+    average(),
+    sample(),
+    int1(MICROBIT_PIN_COMPASS_DATA_READY),
+    i2c(_i2c),
+    accelerometer(&_accelerometer),
+    storage(NULL)
+{
+    init(id, address);
+}
+
+/**
+  * Constructor.
+  * Create a software representation of an e-compass.
+  *
+  * @param _i2c an instance of i2c, which the compass is accessible from.
+  *
+  * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets.
+  *
+  * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * MicroBitStorage storage;
+  *
+  * MicroBitCompass compass(i2c, storage);
+  * @endcode
+  */
+MicroBitCompass::MicroBitCompass(MicroBitI2C& _i2c, MicroBitStorage& _storage, uint16_t address, uint16_t id) :
+    average(),
+    sample(),
+    int1(MICROBIT_PIN_COMPASS_DATA_READY),
+    i2c(_i2c),
+    accelerometer(NULL),
+    storage(&_storage)
+{
+    init(id, address);
+}
+
+/**
+  * Constructor.
+  * Create a software representation of an e-compass.
+  *
+  * @param _i2c an instance of i2c, which the compass is accessible from.
+  *
+  * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR.
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  *
+  * MicroBitCompass compass(i2c);
+  * @endcode
+  */
+MicroBitCompass::MicroBitCompass(MicroBitI2C& _i2c, uint16_t address, uint16_t id) :
+    average(),
+    sample(),
+    int1(MICROBIT_PIN_COMPASS_DATA_READY),
+    i2c(_i2c),
+    accelerometer(NULL),
+    storage(NULL)
+{
+    init(id, address);
+}
+
+/**
+  * Issues a standard, 2 byte I2C command write to the accelerometer.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the register to write to.
+  *
+  * @param value The value to write.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed.
+  */
+int MicroBitCompass::writeCommand(uint8_t reg, uint8_t value)
+{
+    uint8_t command[2];
+    command[0] = reg;
+    command[1] = value;
+
+    return i2c.write(address, (const char *)command, 2);
+}
+
+/**
+  * Issues a read command, copying data into the specified buffer.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the register to access.
+  *
+  * @param buffer Memory area to read the data into.
+  *
+  * @param length The number of bytes to read.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed.
+  */
+int MicroBitCompass::readCommand(uint8_t reg, uint8_t* buffer, int length)
+{
+    int result;
+
+    if (buffer == NULL || length <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    result = i2c.write(address, (const char *)&reg, 1, true);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    result = i2c.read(address, (char *)buffer, length);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Issues a read of a given address, and returns the value.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the 16 bit register to access.
+  *
+  * @return The register value, interpreted as a 16 but signed value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed.
+  */
+int MicroBitCompass::read16(uint8_t reg)
+{
+    uint8_t cmd[2];
+    int result;
+
+    cmd[0] = reg;
+    result = i2c.write(address, (const char *)cmd, 1);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    cmd[0] = 0x00;
+    cmd[1] = 0x00;
+
+    result = i2c.read(address, (char *)cmd, 2);
+    if (result !=0)
+        return MICROBIT_I2C_ERROR;
+
+    return (int16_t) ((cmd[1] | (cmd[0] << 8))); //concatenate the MSB and LSB
+}
+
+/**
+  * Issues a read of a given address, and returns the value.
+  *
+  * Blocks the calling thread until complete.
+  *
+  * @param reg The address of the 16 bit register to access.
+  *
+  * @return The register value, interpreted as a 8 bit unsigned value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed.
+  */
+int MicroBitCompass::read8(uint8_t reg)
+{
+    uint8_t data;
+    int result;
+
+    data = 0;
+    result = readCommand(reg, (uint8_t*) &data, 1);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+    return data;
+}
+
+/**
+  * Calculates a tilt compensated bearing of the device, using the accelerometer.
+  */
+int MicroBitCompass::tiltCompensatedBearing()
+{
+    // Precompute the tilt compensation parameters to improve readability.
+    float phi = accelerometer->getRollRadians();
+    float theta = accelerometer->getPitchRadians();
+
+    float x = (float) getX(NORTH_EAST_DOWN);
+    float y = (float) getY(NORTH_EAST_DOWN);
+    float z = (float) getZ(NORTH_EAST_DOWN);
+
+    // Precompute cos and sin of pitch and roll angles to make the calculation a little more efficient.
+    float sinPhi = sin(phi);
+    float cosPhi = cos(phi);
+    float sinTheta = sin(theta);
+    float cosTheta = cos(theta);
+
+    float bearing = (360*atan2(z*sinPhi - y*cosPhi, x*cosTheta + y*sinTheta*sinPhi + z*sinTheta*cosPhi)) / (2*PI);
+
+    if (bearing < 0)
+        bearing += 360.0;
+
+    return (int) bearing;
+}
+
+/**
+  * Calculates a non-tilt compensated bearing of the device.
+  */
+int MicroBitCompass::basicBearing()
+{
+    updateSample();
+
+    float bearing = (atan2((double)(sample.y - average.y),(double)(sample.x - average.x)))*180/PI;
+
+    if (bearing < 0)
+        bearing += 360.0;
+
+    return (int)(360.0 - bearing);
+}
+
+/**
+  * Gets the current heading of the device, relative to magnetic north.
+  *
+  * If the compass is not calibrated, it will raise the MICROBIT_COMPASS_EVT_CALIBRATE event.
+  *
+  * Users wishing to implement their own calibration algorithms should listen for this event,
+  * using MESSAGE_BUS_LISTENER_IMMEDIATE model. This ensures that calibration is complete before
+  * the user program continues.
+  *
+  * @return the current heading, in degrees. Or MICROBIT_CALIBRATION_IN_PROGRESS if the compass is calibrating.
+  *
+  * @code
+  * compass.heading();
+  * @endcode
+  */
+int MicroBitCompass::heading()
+{
+    if(status & MICROBIT_COMPASS_STATUS_CALIBRATING)
+        return MICROBIT_CALIBRATION_IN_PROGRESS;
+
+    if(!(status & MICROBIT_COMPASS_STATUS_CALIBRATED))
+        calibrate();
+
+    if(accelerometer != NULL)
+        return tiltCompensatedBearing();
+
+    return basicBearing();
+}
+
+/**
+  * Updates the local sample, only if the compass indicates that
+  * data is stale.
+  *
+  * @note Can be used to trigger manual updates, if the device is running without a scheduler.
+  *       Also called internally by all get[X,Y,Z]() member functions.
+  */
+int MicroBitCompass::updateSample()
+{
+    /**
+      * Adds the compass to idle, if it hasn't been added already.
+      * This is an optimisation so that the compass is only added on first 'use'.
+      */
+    if(!(status & MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE))
+    {
+        fiber_add_idle_component(this);
+        status |= MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE;
+    }
+
+    // Poll interrupt line from compass (Active HI).
+    // Interrupt is cleared on data read of MAG_OUT_X_MSB.
+    if(int1)
+    {
+        sample.x = MAG3110_NORMALIZE_SAMPLE((int) read16(MAG_OUT_X_MSB));
+        sample.y = MAG3110_NORMALIZE_SAMPLE((int) read16(MAG_OUT_Y_MSB));
+        sample.z = MAG3110_NORMALIZE_SAMPLE((int) read16(MAG_OUT_Z_MSB));
+
+        // Indicate that a new sample is available
+        MicroBitEvent e(id, MICROBIT_COMPASS_EVT_DATA_UPDATE);
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Periodic callback from MicroBit idle thread.
+  *
+  * Calls updateSample().
+  */
+void MicroBitCompass::idleTick()
+{
+    updateSample();
+}
+
+/**
+  * Reads the value of the X axis from the latest update retrieved from the magnetometer.
+  *
+  * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+  *
+  * @return The magnetic force measured in the X axis, in nano teslas.
+  *
+  * @code
+  * compass.getX();
+  * @endcode
+  */
+int MicroBitCompass::getX(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case SIMPLE_CARTESIAN:
+            return sample.x - average.x;
+
+        case NORTH_EAST_DOWN:
+            return -(sample.y - average.y);
+
+        case RAW:
+        default:
+            return sample.x;
+    }
+}
+
+/**
+  * Reads the value of the Y axis from the latest update retrieved from the magnetometer.
+  *
+  * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+  *
+  * @return The magnetic force measured in the Y axis, in nano teslas.
+  *
+  * @code
+  * compass.getY();
+  * @endcode
+  */
+int MicroBitCompass::getY(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case SIMPLE_CARTESIAN:
+            return -(sample.y - average.y);
+
+        case NORTH_EAST_DOWN:
+            return (sample.x - average.x);
+
+        case RAW:
+        default:
+            return sample.y;
+    }
+}
+
+/**
+  * Reads the value of the Z axis from the latest update retrieved from the magnetometer.
+  *
+  * @param system The coordinate system to use. By default, a simple cartesian system is provided.
+  *
+  * @return The magnetic force measured in the Z axis, in nano teslas.
+  *
+  * @code
+  * compass.getZ();
+  * @endcode
+  */
+int MicroBitCompass::getZ(MicroBitCoordinateSystem system)
+{
+    updateSample();
+
+    switch (system)
+    {
+        case SIMPLE_CARTESIAN:
+        case NORTH_EAST_DOWN:
+            return -(sample.z - average.z);
+
+        case RAW:
+        default:
+            return sample.z;
+    }
+}
+
+/**
+  * Determines the overall magnetic field strength based on the latest update from the magnetometer.
+  *
+  * @return The magnetic force measured across all axis, in nano teslas.
+  *
+  * @code
+  * compass.getFieldStrength();
+  * @endcode
+  */
+int MicroBitCompass::getFieldStrength()
+{
+    double x = getX();
+    double y = getY();
+    double z = getZ();
+
+    return (int) sqrt(x*x + y*y + z*z);
+}
+
+/**
+  * Configures the compass for the sample rate defined in this object.
+  * The nearest values are chosen to those defined that are supported by the hardware.
+  * The instance variables are then updated to reflect reality.
+  *
+  * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be configured.
+  */
+int MicroBitCompass::configure()
+{
+    const MAG3110SampleRateConfig  *actualSampleRate;
+    int result;
+
+    // First, take the device offline, so it can be configured.
+    result = writeCommand(MAG_CTRL_REG1, 0x00);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+    // Wait for the part to enter standby mode...
+    while(1)
+    {
+        // Read the status of the part...
+        // If we can't communicate with it over I2C, pass on the error.
+        result = this->read8(MAG_SYSMOD);
+        if (result == MICROBIT_I2C_ERROR)
+            return MICROBIT_I2C_ERROR;
+
+        // if the part in in standby, we're good to carry on.
+        if((result & 0x03) == 0)
+            break;
+
+        // Perform a power efficient sleep...
+		fiber_sleep(100);
+    }
+
+    // Find the nearest sample rate to that specified.
+    actualSampleRate = &MAG3110SampleRate[MAG3110_SAMPLE_RATES-1];
+    for (int i=MAG3110_SAMPLE_RATES-1; i>=0; i--)
+    {
+        if(MAG3110SampleRate[i].sample_period < this->samplePeriod * 1000)
+            break;
+
+        actualSampleRate = &MAG3110SampleRate[i];
+    }
+
+    // OK, we have the correct data. Update our local state.
+    this->samplePeriod = actualSampleRate->sample_period / 1000;
+
+    // Enable automatic reset after each sample;
+    result = writeCommand(MAG_CTRL_REG2, 0xA0);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+
+    // Bring the device online, with the requested sample frequency.
+    result = writeCommand(MAG_CTRL_REG1, actualSampleRate->ctrl_reg1 | 0x01);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Attempts to set the sample rate of the compass to the specified value (in ms).
+  *
+  * @param period the requested time between samples, in milliseconds.
+  *
+  * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be updated.
+  *
+  * @code
+  * // sample rate is now 20 ms.
+  * compass.setPeriod(20);
+  * @endcode
+  *
+  * @note The requested rate may not be possible on the hardware. In this case, the
+  * nearest lower rate is chosen.
+  */
+int MicroBitCompass::setPeriod(int period)
+{
+    this->samplePeriod = period;
+    return this->configure();
+}
+
+/**
+  * Reads the currently configured sample rate of the compass.
+  *
+  * @return The time between samples, in milliseconds.
+  */
+int MicroBitCompass::getPeriod()
+{
+    return (int)samplePeriod;
+}
+
+/**
+  * Attempts to read the 8 bit ID from the magnetometer, this can be used for
+  * validation purposes.
+  *
+  * @return the 8 bit ID returned by the magnetometer, or MICROBIT_I2C_ERROR if the request fails.
+  *
+  * @code
+  * compass.whoAmI();
+  * @endcode
+  */
+int MicroBitCompass::whoAmI()
+{
+    uint8_t data;
+    int result;
+
+    result = readCommand(MAG_WHOAMI, &data, 1);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+    return (int)data;
+}
+
+/**
+  * Reads the current die temperature of the compass.
+  *
+  * @return the temperature in degrees celsius, or MICROBIT_I2C_ERROR if the temperature reading could not be retreived
+  *         from the accelerometer.
+  */
+int MicroBitCompass::readTemperature()
+{
+    int8_t temperature;
+    int result;
+
+    result = readCommand(MAG_DIE_TEMP, (uint8_t *)&temperature, 1);
+    if (result != MICROBIT_OK)
+        return MICROBIT_I2C_ERROR;
+
+    return temperature;
+}
+
+/**
+  * Perform a calibration of the compass.
+  *
+  * This method will be called automatically if a user attempts to read a compass value when
+  * the compass is uncalibrated. It can also be called at any time by the user.
+  *
+  * The method will only return once the compass has been calibrated.
+  *
+  * @return MICROBIT_OK, MICROBIT_I2C_ERROR if the magnetometer could not be accessed,
+  * or MICROBIT_CALIBRATION_REQUIRED if the calibration algorithm failed to complete successfully.
+  *
+  * @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS
+  */
+int MicroBitCompass::calibrate()
+{
+    // Only perform one calibration process at a time.
+    if(isCalibrating())
+        return MICROBIT_CALIBRATION_IN_PROGRESS;
+
+    updateSample();
+
+    // Delete old calibration data
+    clearCalibration();
+
+    // Record that we've started calibrating.
+    status |= MICROBIT_COMPASS_STATUS_CALIBRATING;
+
+    // Launch any registred calibration alogrithm visialisation
+    MicroBitEvent(id, MICROBIT_COMPASS_EVT_CALIBRATE);
+
+    // Record that we've finished calibrating.
+    status &= ~MICROBIT_COMPASS_STATUS_CALIBRATING;
+
+    // If there are no changes to our sample data, we either have no calibration algorithm, or it couldn't complete succesfully.
+    if(!(status & MICROBIT_COMPASS_STATUS_CALIBRATED))
+        return MICROBIT_CALIBRATION_REQUIRED;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configure the compass to use the calibration data that is supplied to this call.
+  *
+  * Calibration data is comprised of the perceived zero offset of each axis of the compass.
+  *
+  * After calibration this should now take into account trimming errors in the magnetometer,
+  * and any "hard iron" offsets on the device.
+  *
+  * @param calibration A CompassSample containing the offsets for the x, y and z axis.
+  */
+void MicroBitCompass::setCalibration(CompassSample calibration)
+{
+    if(this->storage != NULL)
+        this->storage->put(ManagedString("compassCal"), (uint8_t *)&calibration, sizeof(CompassSample));
+
+    average = calibration;
+    status |= MICROBIT_COMPASS_STATUS_CALIBRATED;
+}
+
+/**
+  * Provides the calibration data currently in use by the compass.
+  *
+  * More specifically, the x, y and z zero offsets of the compass.
+  *
+  * @return calibration A CompassSample containing the offsets for the x, y and z axis.
+  */
+CompassSample MicroBitCompass::getCalibration()
+{
+    return average;
+}
+
+/**
+  * Returns 0 or 1. 1 indicates that the compass is calibrated, zero means the compass requires calibration.
+  */
+int MicroBitCompass::isCalibrated()
+{
+    return status & MICROBIT_COMPASS_STATUS_CALIBRATED;
+}
+
+/**
+  * Returns 0 or 1. 1 indicates that the compass is calibrating, zero means the compass is not currently calibrating.
+  */
+int MicroBitCompass::isCalibrating()
+{
+    return status & MICROBIT_COMPASS_STATUS_CALIBRATING;
+}
+
+/**
+  * Clears the calibration held in persistent storage, and sets the calibrated flag to zero.
+  */
+void MicroBitCompass::clearCalibration()
+{
+    status &= ~MICROBIT_COMPASS_STATUS_CALIBRATED;
+}
+
+/**
+  * Destructor for MicroBitCompass, where we deregister this instance from the array of fiber components.
+  */
+MicroBitCompass::~MicroBitCompass()
+{
+    fiber_remove_idle_component(this);
+}
+
+const MAG3110SampleRateConfig MAG3110SampleRate[MAG3110_SAMPLE_RATES] = {
+    {12500,      0x00},        // 80 Hz
+    {25000,      0x20},        // 40 Hz
+    {50000,      0x40},        // 20 Hz
+    {100000,     0x60},        // 10 hz
+    {200000,     0x80},        // 5 hz
+    {400000,     0x88},        // 2.5 hz
+    {800000,     0x90},        // 1.25 hz
+    {1600000,    0xb0},        // 0.63 hz
+    {3200000,    0xd0},        // 0.31 hz
+    {6400000,    0xf0},        // 0.16 hz
+    {12800000,   0xf8}         // 0.08 hz
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitCompassCalibrator.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,188 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitCompassCalibrator.h"
+#include "EventModel.h"
+#include "Matrix4.h"
+
+/**
+  * Constructor.
+  *
+  * Create an object capable of calibrating the compass.
+  *
+  * The algorithm uses an accelerometer to ensure that a broad range of sample data has been gathered
+  * from the compass module, then performs a least mean squares optimisation of the
+  * results to determine the calibration data for the compass.
+  *
+  * The LED matrix display is used to provide feedback to the user on the gestures required.
+  *
+  * @param compass The compass instance to calibrate.
+  *
+  * @param accelerometer The accelerometer to gather contextual data from.
+  *
+  * @param display The LED matrix to display user feedback on.
+  */
+MicroBitCompassCalibrator::MicroBitCompassCalibrator(MicroBitCompass& _compass, MicroBitAccelerometer& _accelerometer, MicroBitDisplay& _display) : compass(_compass), accelerometer(_accelerometer), display(_display)
+{
+    if (EventModel::defaultEventBus)
+        EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CALIBRATE, this, &MicroBitCompassCalibrator::calibrate, MESSAGE_BUS_LISTENER_IMMEDIATE);
+}
+
+/**
+  * Performs a simple game that in parallel, calibrates the compass.
+  *
+  * This function is executed automatically when the user requests a compass bearing, and compass calibration is required.
+  *
+  * This function is, by design, synchronous and only returns once calibration is complete.
+  */
+void MicroBitCompassCalibrator::calibrate(MicroBitEvent)
+{
+    struct Point
+    {
+        uint8_t x;
+        uint8_t y;
+        uint8_t on;
+    };
+
+    const int PERIMETER_POINTS = 12;
+    const int PIXEL1_THRESHOLD = 200;
+    const int PIXEL2_THRESHOLD = 800;
+
+    wait_ms(100);
+
+	Matrix4 X(PERIMETER_POINTS, 4);
+    Point perimeter[PERIMETER_POINTS] = {{1,0,0}, {2,0,0}, {3,0,0}, {4,1,0}, {4,2,0}, {4,3,0}, {3,4,0}, {2,4,0}, {1,4,0}, {0,3,0}, {0,2,0}, {0,1,0}};
+    Point cursor = {2,2,0};
+
+    MicroBitImage img(5,5);
+    MicroBitImage smiley("0,255,0,255,0\n0,255,0,255,0\n0,0,0,0,0\n255,0,0,0,255\n0,255,255,255,0\n");
+    int samples = 0;
+
+    // Firstly, we need to take over the display. Ensure all active animations are paused.
+    display.stopAnimation();
+    display.scrollAsync("DRAW A CIRCLE");
+
+    for (int i=0; i<110; i++)
+        wait_ms(100);
+
+    display.stopAnimation();
+    display.clear();
+
+    while(samples < PERIMETER_POINTS)
+    {
+        // update our model of the flash status of the user controlled pixel.
+        cursor.on = (cursor.on + 1) % 4;
+
+        // take a snapshot of the current accelerometer data.
+        int x = accelerometer.getX();
+        int y = accelerometer.getY();
+
+        // Wait a little whie for the button state to stabilise (one scheduler tick).
+        wait_ms(10);
+
+        // Deterine the position of the user controlled pixel on the screen.
+        if (x < -PIXEL2_THRESHOLD)
+            cursor.x = 0;
+        else if (x < -PIXEL1_THRESHOLD)
+            cursor.x = 1;
+        else if (x > PIXEL2_THRESHOLD)
+            cursor.x = 4;
+        else if (x > PIXEL1_THRESHOLD)
+            cursor.x = 3;
+        else
+            cursor.x = 2;
+
+        if (y < -PIXEL2_THRESHOLD)
+            cursor.y = 0;
+        else if (y < -PIXEL1_THRESHOLD)
+            cursor.y = 1;
+        else if (y > PIXEL2_THRESHOLD)
+            cursor.y = 4;
+        else if (y > PIXEL1_THRESHOLD)
+            cursor.y = 3;
+        else
+            cursor.y = 2;
+
+        img.clear();
+
+        // Turn on any pixels that have been visited.
+        for (int i=0; i<PERIMETER_POINTS; i++)
+            if (perimeter[i].on)
+                img.setPixelValue(perimeter[i].x, perimeter[i].y, 255);
+
+        // Update the pixel at the users position.
+        img.setPixelValue(cursor.x, cursor.y, 255);
+
+        // Update the buffer to the screen.
+        display.image.paste(img,0,0,0);
+
+        // test if we need to update the state at the users position.
+        for (int i=0; i<PERIMETER_POINTS; i++)
+        {
+            if (cursor.x == perimeter[i].x && cursor.y == perimeter[i].y && !perimeter[i].on)
+            {
+                // Record the sample data for later processing...
+                X.set(samples, 0, compass.getX(RAW));
+                X.set(samples, 1, compass.getY(RAW));
+                X.set(samples, 2, compass.getZ(RAW));
+                X.set(samples, 3, 1);
+
+                // Record that this pixel has been visited.
+                perimeter[i].on = 1;
+                samples++;
+            }
+        }
+
+        wait_ms(100);
+    }
+
+    // We have enough sample data to make a fairly accurate calibration.
+    // We use a Least Mean Squares approximation, as detailed in Freescale application note AN2426.
+
+    // Firstly, calculate the square of each sample.
+	Matrix4 Y(X.height(), 1);
+	for (int i = 0; i < X.height(); i++)
+	{
+		float v = X.get(i, 0)*X.get(i, 0) + X.get(i, 1)*X.get(i, 1) + X.get(i, 2)*X.get(i, 2);
+		Y.set(i, 0, v);
+	}
+
+    // Now perform a Least Squares Approximation.
+	Matrix4 Alpha = X.multiplyT(X).invert();
+	Matrix4 Gamma = X.multiplyT(Y);
+	Matrix4 Beta = Alpha.multiply(Gamma);
+
+    // The result contains the approximate zero point of each axis, but doubled.
+    // Halve each sample, and record this as the compass calibration data.
+    CompassSample cal ((int)(Beta.get(0,0) / 2), (int)(Beta.get(1,0) / 2), (int)(Beta.get(2,0) / 2));
+    compass.setCalibration(cal);
+
+    // Show a smiley to indicate that we're done, and continue on with the user program.
+    display.clear();
+    display.printAsync(smiley, 0, 0, 0, 1500);
+    wait_ms(1000);
+    display.clear();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitDisplay.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1225 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBitDisplay.
+  *
+  * A MicroBitDisplay represents the LED matrix array on the micro:bit.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitDisplay.h"
+#include "MicroBitSystemTimer.h"
+#include "MicroBitFiber.h"
+#include "ErrorNo.h"
+#include "NotifyEvents.h"
+
+const int greyScaleTimings[MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH] = {1, 23, 70, 163, 351, 726, 1476, 2976};
+
+/**
+  * Constructor.
+  *
+  * Create a software representation the micro:bit's 5x5 LED matrix.
+  * The display is initially blank.
+  *
+  * @param id The id the display should use when sending events on the MessageBus. Defaults to MICROBIT_ID_DISPLAY.
+  *
+  * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
+  *            Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * @endcode
+  */
+MicroBitDisplay::MicroBitDisplay(uint16_t id, const MatrixMap &map) :
+    matrixMap(map),
+    image(map.width*2,map.height)
+{
+    uint32_t row_mask;
+
+    this->id = id;
+    this->width = map.width;
+    this->height = map.height;
+    this->rotation = MICROBIT_DISPLAY_ROTATION_0;
+
+    row_mask = 0;
+    col_mask = 0;
+    strobeRow = 0;
+    row_mask = 0;
+
+    for (int i = matrixMap.rowStart; i < matrixMap.rowStart + matrixMap.rows; i++)
+        row_mask |= 0x01 << i;
+
+    for (int i = matrixMap.columnStart; i < matrixMap.columnStart + matrixMap.columns; i++)
+        col_mask |= 0x01 << i;
+
+    LEDMatrix = new PortOut(Port0, row_mask | col_mask);
+
+    this->greyscaleBitMsk = 0x01;
+    this->timingCount = 0;
+    this->setBrightness(MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS);
+    this->mode = DISPLAY_MODE_BLACK_AND_WHITE;
+    this->animationMode = ANIMATION_MODE_NONE;
+    this->lightSensor = NULL;
+
+	system_timer_add_component(this);
+
+    status |= MICROBIT_COMPONENT_RUNNING;
+}
+
+/**
+  * Internal frame update method, used to strobe the display.
+  *
+  * TODO: Write a more efficient, complementary variation of this method for the case where
+  * MICROBIT_DISPLAY_ROW_COUNT > MICROBIT_DISPLAY_COLUMN_COUNT.
+  */
+void MicroBitDisplay::systemTick()
+{
+    if(!(status & MICROBIT_COMPONENT_RUNNING))
+        return;
+
+    if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
+    {
+        renderWithLightSense();
+        return;
+    }
+
+    // Move on to the next row.
+    strobeRow++;
+
+    //reset the row counts and bit mask when we have hit the max.
+    if(strobeRow == matrixMap.rows)
+        strobeRow = 0;
+
+    if(mode == DISPLAY_MODE_BLACK_AND_WHITE)
+        render();
+
+    if(mode == DISPLAY_MODE_GREYSCALE)
+    {
+        greyscaleBitMsk = 0x01;
+        timingCount = 0;
+        renderGreyscale();
+    }
+
+    // Update text and image animations if we need to.
+    this->animationUpdate();
+}
+
+void MicroBitDisplay::renderFinish()
+{
+    *LEDMatrix = 0;
+}
+
+void MicroBitDisplay::render()
+{
+    // Simple optimisation.
+    // If display is at zero brightness, there's nothing to do.
+    if(brightness == 0)
+        return;
+
+    // Calculate the bitpattern to write.
+    uint32_t row_data = 0x01 << (matrixMap.rowStart + strobeRow);
+    uint32_t col_data = 0;
+
+    for (int i = 0; i < matrixMap.columns; i++)
+    {
+        int index = (i * matrixMap.rows) + strobeRow;
+
+        int x = matrixMap.map[index].x;
+        int y = matrixMap.map[index].y;
+        int t = x;
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_90)
+        {
+                x = width - 1 - y;
+                y = t;
+        }
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_180)
+        {
+                x = width - 1 - x;
+                y = height - 1 - y;
+        }
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_270)
+        {
+                x = y;
+                y = height - 1 - t;
+        }
+
+        if(image.getBitmap()[y*(width*2)+x])
+            col_data |= (1 << i);
+    }
+
+    // Invert column bits (as we're sinking not sourcing power), and mask off any unused bits.
+    col_data = ~col_data << matrixMap.columnStart & col_mask;
+
+    // Write the new bit pattern
+    *LEDMatrix = col_data | row_data;
+
+    //timer does not have enough resolution for brightness of 1. 23.53 us
+    if(brightness != MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
+        renderTimer.attach_us(this, &MicroBitDisplay::renderFinish, (((brightness * 950) / (MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS)) * system_timer_get_period()));
+
+    //this will take around 23us to execute
+    if(brightness <= MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
+        renderFinish();
+}
+
+void MicroBitDisplay::renderWithLightSense()
+{
+    //reset the row counts and bit mask when we have hit the max.
+    if(strobeRow == matrixMap.rows + 1)
+    {
+        MicroBitEvent(id, MICROBIT_DISPLAY_EVT_LIGHT_SENSE);
+        strobeRow = 0;
+    }
+    else
+    {
+        render();
+        this->animationUpdate();
+
+        // Move on to the next row.
+        strobeRow++;
+    }
+
+}
+
+void MicroBitDisplay::renderGreyscale()
+{
+    uint32_t row_data = 0x01 << (matrixMap.rowStart + strobeRow);
+    uint32_t col_data = 0;
+
+    // Calculate the bitpattern to write.
+    for (int i = 0; i < matrixMap.columns; i++)
+    {
+        int index = (i * matrixMap.rows) + strobeRow;
+
+        int x = matrixMap.map[index].x;
+        int y = matrixMap.map[index].y;
+        int t = x;
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_90)
+        {
+                x = width - 1 - y;
+                y = t;
+        }
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_180)
+        {
+                x = width - 1 - x;
+                y = height - 1 - y;
+        }
+
+        if(rotation == MICROBIT_DISPLAY_ROTATION_270)
+        {
+                x = y;
+                y = height - 1 - t;
+        }
+
+        if(min(image.getBitmap()[y * (width * 2) + x],brightness) & greyscaleBitMsk)
+            col_data |= (1 << i);
+    }
+
+    // Invert column bits (as we're sinking not sourcing power), and mask off any unused bits.
+    col_data = ~col_data << matrixMap.columnStart & col_mask;
+
+    // Write the new bit pattern
+    *LEDMatrix = col_data | row_data;
+
+    if(timingCount > MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH-1)
+        return;
+
+    greyscaleBitMsk <<= 1;
+
+    if(timingCount < 3)
+    {
+        wait_us(greyScaleTimings[timingCount++]);
+        renderGreyscale();
+        return;
+    }
+    renderTimer.attach_us(this,&MicroBitDisplay::renderGreyscale, greyScaleTimings[timingCount++]);
+}
+
+/**
+  * Periodic callback, that we use to perform any animations we have running.
+  */
+void
+MicroBitDisplay::animationUpdate()
+{
+    // If there's no ongoing animation, then nothing to do.
+    if (animationMode == ANIMATION_MODE_NONE)
+        return;
+
+    animationTick += system_timer_get_period();
+
+    if(animationTick >= animationDelay)
+    {
+        animationTick = 0;
+
+        if (animationMode == ANIMATION_MODE_SCROLL_TEXT)
+            this->updateScrollText();
+
+        if (animationMode == ANIMATION_MODE_PRINT_TEXT)
+            this->updatePrintText();
+
+        if (animationMode == ANIMATION_MODE_SCROLL_IMAGE)
+            this->updateScrollImage();
+
+        if (animationMode == ANIMATION_MODE_ANIMATE_IMAGE || animationMode == ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR)
+            this->updateAnimateImage();
+
+        if(animationMode == ANIMATION_MODE_PRINT_CHARACTER)
+        {
+            animationMode = ANIMATION_MODE_NONE;
+            this->sendAnimationCompleteEvent();
+        }
+    }
+}
+
+/**
+  * Broadcasts an event onto the defult EventModel indicating that the
+  * current animation has completed.
+  */
+void MicroBitDisplay::sendAnimationCompleteEvent()
+{
+    // Signal that we've completed an animation.
+    MicroBitEvent(id,MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE);
+
+    // Wake up a fiber that was blocked on the animation (if any).
+    MicroBitEvent(MICROBIT_ID_NOTIFY_ONE, MICROBIT_DISPLAY_EVT_FREE);
+}
+
+/**
+  * Internal scrollText update method.
+  * Shift the screen image by one pixel to the left. If necessary, paste in the next char.
+  */
+void MicroBitDisplay::updateScrollText()
+{
+    image.shiftLeft(1);
+    scrollingPosition++;
+
+    if (scrollingPosition == width + MICROBIT_DISPLAY_SPACING)
+    {
+        scrollingPosition = 0;
+
+        image.print(scrollingChar < scrollingText.length() ? scrollingText.charAt(scrollingChar) : ' ',width,0);
+
+        if (scrollingChar > scrollingText.length())
+        {
+            animationMode = ANIMATION_MODE_NONE;
+            this->sendAnimationCompleteEvent();
+            return;
+        }
+        scrollingChar++;
+   }
+}
+
+/**
+  * Internal printText update method.
+  * Paste the next character in the string.
+  */
+void MicroBitDisplay::updatePrintText()
+{
+    image.print(printingChar < printingText.length() ? printingText.charAt(printingChar) : ' ',0,0);
+
+    if (printingChar > printingText.length())
+    {
+        animationMode = ANIMATION_MODE_NONE;
+
+        this->sendAnimationCompleteEvent();
+        return;
+    }
+
+    printingChar++;
+}
+
+/**
+  * Internal scrollImage update method.
+  * Paste the stored bitmap at the appropriate point.
+  */
+void MicroBitDisplay::updateScrollImage()
+{
+    image.clear();
+
+    if (((image.paste(scrollingImage, scrollingImagePosition, 0, 0) == 0) && scrollingImageRendered) || scrollingImageStride == 0)
+    {
+        animationMode = ANIMATION_MODE_NONE;
+        this->sendAnimationCompleteEvent();
+
+        return;
+    }
+
+    scrollingImagePosition += scrollingImageStride;
+    scrollingImageRendered = true;
+}
+
+/**
+  * Internal animateImage update method.
+  * Paste the stored bitmap at the appropriate point and stop on the last frame.
+  */
+void MicroBitDisplay::updateAnimateImage()
+{
+    //wait until we have rendered the last position to give a continuous animation.
+    if (scrollingImagePosition <= -scrollingImage.getWidth() + (MICROBIT_DISPLAY_WIDTH + scrollingImageStride) && scrollingImageRendered)
+    {
+        if (animationMode == ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR)
+            this->clear();
+
+        animationMode = ANIMATION_MODE_NONE;
+
+        this->sendAnimationCompleteEvent();
+        return;
+    }
+
+    if(scrollingImagePosition > 0)
+        image.shiftLeft(-scrollingImageStride);
+
+    image.paste(scrollingImage, scrollingImagePosition, 0, 0);
+
+    if(scrollingImageStride == 0)
+    {
+        animationMode = ANIMATION_MODE_NONE;
+        this->sendAnimationCompleteEvent();
+    }
+
+    scrollingImageRendered = true;
+
+    scrollingImagePosition += scrollingImageStride;
+}
+
+/**
+  * Resets the current given animation.
+  */
+void MicroBitDisplay::stopAnimation()
+{
+    // Reset any ongoing animation.
+    if (animationMode != ANIMATION_MODE_NONE)
+    {
+        animationMode = ANIMATION_MODE_NONE;
+
+        // Indicate that we've completed an animation.
+        MicroBitEvent(id,MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE);
+
+        // Wake up aall fibers that may blocked on the animation (if any).
+        MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
+    }
+
+    // Clear the display and setup the animation timers.
+    this->image.clear();
+}
+
+/**
+  * Blocks the current fiber until the display is available (i.e. does not effect is being displayed).
+  * Animations are queued until their time to display.
+  */
+void MicroBitDisplay::waitForFreeDisplay()
+{
+    // If there's an ongoing animation, wait for our turn to display.
+    if (animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
+        fiber_wait_for_event(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
+}
+
+/**
+  * Blocks the current fiber until the current animation has finished.
+  * If the scheduler is not running, this call will essentially perform a spinning wait.
+  */
+void MicroBitDisplay::fiberWait()
+{
+    if (fiber_wait_for_event(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE) == MICROBIT_NOT_SUPPORTED)
+        while(animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
+            __WFE();
+}
+
+/**
+  * Prints the given character to the display, if it is not in use.
+  *
+  * @param c The character to display.
+  *
+  * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
+  *              or until the Displays next use.
+  *
+  * @return MICROBIT_OK, MICROBIT_BUSY is the screen is in use, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.printAsync('p');
+  * display.printAsync('p',100);
+  * @endcode
+  */
+int MicroBitDisplay::printCharAsync(char c, int delay)
+{
+    //sanitise this value
+    if(delay < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If the display is free, it's our turn to display.
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        image.print(c, 0, 0);
+
+        if (delay > 0)
+        {
+            animationDelay = delay;
+            animationTick = 0;
+            animationMode = ANIMATION_MODE_PRINT_CHARACTER;
+        }
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Prints the given ManagedString to the display, one character at a time.
+  * Returns immediately, and executes the animation asynchronously.
+  *
+  * @param s The string to display.
+  *
+  * @param delay The time to delay between characters, in milliseconds. Must be > 0.
+  *              Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.printAsync("abc123",400);
+  * @endcode
+  */
+int MicroBitDisplay::printAsync(ManagedString s, int delay)
+{
+    if (s.length() == 1)
+        return printCharAsync(s.charAt(0));
+
+    //sanitise this value
+    if (delay <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        printingChar = 0;
+        printingText = s;
+        animationDelay = delay;
+        animationTick = 0;
+
+        animationMode = ANIMATION_MODE_PRINT_TEXT;
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Prints the given image to the display, if the display is not in use.
+  * Returns immediately, and executes the animation asynchronously.
+  *
+  * @param i The image to display.
+  *
+  * @param x The horizontal position on the screen to display the image. Defaults to 0.
+  *
+  * @param y The vertical position on the screen to display the image. Defaults to 0.
+  *
+  * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
+  *
+  * @param delay The time to delay between characters, in milliseconds. Defaults to 0.
+  *
+  * @code
+  * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+  * display.print(i,400);
+  * @endcode
+  */
+int MicroBitDisplay::printAsync(MicroBitImage i, int x, int y, int alpha, int delay)
+{
+    if(delay < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        image.paste(i, x, y, alpha);
+
+        if(delay > 0)
+        {
+            animationDelay = delay;
+            animationTick = 0;
+            animationMode = ANIMATION_MODE_PRINT_CHARACTER;
+        }
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Prints the given character to the display.
+  *
+  * @param c The character to display.
+  *
+  * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
+  *              or until the Displays next use.
+  *
+  * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.printAsync('p');
+  * display.printAsync('p',100);
+  * @endcode
+  */
+int MicroBitDisplay::printChar(char c, int delay)
+{
+    if (delay < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        this->printCharAsync(c, delay);
+
+        if (delay > 0)
+            fiberWait();
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Prints the given string to the display, one character at a time.
+  *
+  * Blocks the calling thread until all the text has been displayed.
+  *
+  * @param s The string to display.
+  *
+  * @param delay The time to delay between characters, in milliseconds. Defaults
+  *              to: MICROBIT_DEFAULT_PRINT_SPEED.
+  *
+  * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.print("abc123",400);
+  * @endcode
+  */
+int MicroBitDisplay::print(ManagedString s, int delay)
+{
+    //sanitise this value
+    if(delay <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        if (s.length() == 1)
+        {
+            return printCharAsync(s.charAt(0));
+        }
+        else
+        {
+            this->printAsync(s, delay);
+            fiberWait();
+        }
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Prints the given image to the display.
+  * Blocks the calling thread until all the image has been displayed.
+  *
+  * @param i The image to display.
+  *
+  * @param x The horizontal position on the screen to display the image. Defaults to 0.
+  *
+  * @param y The vertical position on the screen to display the image. Defaults to 0.
+  *
+  * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
+  *
+  * @param delay The time to display the image for, or zero to show the image forever. Defaults to 0.
+  *
+  * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+  * display.print(i,400);
+  * @endcode
+  */
+int MicroBitDisplay::print(MicroBitImage i, int x, int y, int alpha, int delay)
+{
+    if(delay < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        this->printAsync(i, x, y, alpha, delay);
+
+        if (delay > 0)
+            fiberWait();
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Scrolls the given string to the display, from right to left.
+  * Returns immediately, and executes the animation asynchronously.
+  *
+  * @param s The string to display.
+  *
+  * @param delay The time to delay between characters, in milliseconds. Defaults
+  *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+  *
+  * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.scrollAsync("abc123",100);
+  * @endcode
+  */
+int MicroBitDisplay::scrollAsync(ManagedString s, int delay)
+{
+    //sanitise this value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If the display is free, it's our turn to display.
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        scrollingPosition = width-1;
+        scrollingChar = 0;
+        scrollingText = s;
+
+        animationDelay = delay;
+        animationTick = 0;
+        animationMode = ANIMATION_MODE_SCROLL_TEXT;
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Scrolls the given image across the display, from right to left.
+  * Returns immediately, and executes the animation asynchronously.
+  *
+  * @param image The image to display.
+  *
+  * @param delay The time between updates, in milliseconds. Defaults
+  *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+  *
+  * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
+  *
+  * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+  * display.scrollAsync(i,100,1);
+  * @endcode
+  */
+int MicroBitDisplay::scrollAsync(MicroBitImage image, int delay, int stride)
+{
+    //sanitise the delay value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If the display is free, it's our turn to display.
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        scrollingImagePosition = stride < 0 ? width : -image.getWidth();
+        scrollingImageStride = stride;
+        scrollingImage = image;
+        scrollingImageRendered = false;
+
+        animationDelay = stride == 0 ? 0 : delay;
+        animationTick = 0;
+        animationMode = ANIMATION_MODE_SCROLL_IMAGE;
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Scrolls the given string across the display, from right to left.
+  * Blocks the calling thread until all text has been displayed.
+  *
+  * @param s The string to display.
+  *
+  * @param delay The time to delay between characters, in milliseconds. Defaults
+  *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+  *
+  * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * display.scroll("abc123",100);
+  * @endcode
+  */
+int MicroBitDisplay::scroll(ManagedString s, int delay)
+{
+    //sanitise this value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        // Start the effect.
+        this->scrollAsync(s, delay);
+
+        // Wait for completion.
+        fiberWait();
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Scrolls the given image across the display, from right to left.
+  * Blocks the calling thread until all the text has been displayed.
+  *
+  * @param image The image to display.
+  *
+  * @param delay The time between updates, in milliseconds. Defaults
+  *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
+  *
+  * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
+  *
+  * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
+  * display.scroll(i,100,1);
+  * @endcode
+  */
+int MicroBitDisplay::scroll(MicroBitImage image, int delay, int stride)
+{
+    //sanitise the delay value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        // Start the effect.
+        this->scrollAsync(image, delay, stride);
+
+        // Wait for completion.
+        fiberWait();
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
+  * Returns immediately.
+  *
+  * @param image The image to display.
+  *
+  * @param delay The time to delay between each update of the display, in milliseconds.
+  *
+  * @param stride The number of pixels to shift by in each update.
+  *
+  * @param startingPosition the starting position on the display for the animation
+  *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
+  *
+  * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
+  *
+  * @return MICROBIT_OK, MICROBIT_BUSY if the screen is in use, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const int heart_w = 10;
+  * const int heart_h = 5;
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
+  *
+  * MicroBitImage i(heart_w,heart_h,heart);
+  * display.animateAsync(i,100,5);
+  * @endcode
+  */
+int MicroBitDisplay::animateAsync(MicroBitImage image, int delay, int stride, int startingPosition, int autoClear)
+{
+    //sanitise the delay value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If the display is free, we can display.
+    if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
+    {
+        // Assume right to left functionality, to align with scrollString()
+        stride = -stride;
+
+        //calculate starting position which is offset by the stride
+        scrollingImagePosition = (startingPosition == MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS) ? MICROBIT_DISPLAY_WIDTH + stride : startingPosition;
+        scrollingImageStride = stride;
+        scrollingImage = image;
+        scrollingImageRendered = false;
+
+        animationDelay = stride == 0 ? 0 : delay;
+        animationTick = delay-1;
+        animationMode = autoClear ? ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR : ANIMATION_MODE_ANIMATE_IMAGE;
+    }
+    else
+    {
+        return MICROBIT_BUSY;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
+  * Blocks the calling thread until the animation is complete.
+  *
+  *
+  * @param delay The time to delay between each update of the display, in milliseconds.
+  *
+  * @param stride The number of pixels to shift by in each update.
+  *
+  * @param startingPosition the starting position on the display for the animation
+  *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
+  *
+  * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
+  *
+  * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const int heart_w = 10;
+  * const int heart_h = 5;
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
+  *
+  * MicroBitImage i(heart_w,heart_h,heart);
+  * display.animate(i,100,5);
+  * @endcode
+  */
+int MicroBitDisplay::animate(MicroBitImage image, int delay, int stride, int startingPosition, int autoClear)
+{
+    //sanitise the delay value
+    if(delay <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // If there's an ongoing animation, wait for our turn to display.
+    this->waitForFreeDisplay();
+
+    // If the display is free, it's our turn to display.
+    // If someone called stopAnimation(), then we simply skip...
+    if (animationMode == ANIMATION_MODE_NONE)
+    {
+        // Start the effect.
+        this->animateAsync(image, delay, stride, startingPosition, autoClear);
+
+        // Wait for completion.
+        //TODO: Put this in when we merge tight-validation
+        //if (delay > 0)
+            fiberWait();
+    }
+    else
+    {
+        return MICROBIT_CANCELLED;
+    }
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Configures the brightness of the display.
+  *
+  * @param b The brightness to set the brightness to, in the range 0 - 255.
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER
+  *
+  * @code
+  * display.setBrightness(255); //max brightness
+  * @endcode
+  */
+int MicroBitDisplay::setBrightness(int b)
+{
+    //sanitise the brightness level
+    if(b < 0 || b > 255)
+        return MICROBIT_INVALID_PARAMETER;
+
+    this->brightness = b;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures the mode of the display.
+  *
+  * @param mode The mode to swap the display into. One of: DISPLAY_MODE_GREYSCALE,
+  *             DISPLAY_MODE_BLACK_AND_WHITE, DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
+  *
+  * @code
+  * display.setDisplayMode(DISPLAY_MODE_GREYSCALE); //per pixel brightness
+  * @endcode
+  */
+void MicroBitDisplay::setDisplayMode(DisplayMode mode)
+{
+    if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
+    {
+        //to reduce the artifacts on the display - increase the tick
+        if(system_timer_get_period() != MICROBIT_LIGHT_SENSOR_TICK_PERIOD)
+            system_timer_set_period(MICROBIT_LIGHT_SENSOR_TICK_PERIOD);
+    }
+
+    if(this->mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE && mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
+    {
+        delete this->lightSensor;
+
+        this->lightSensor = NULL;
+    }
+
+    this->mode = mode;
+}
+
+/**
+  * Retrieves the mode of the display.
+  *
+  * @return the current mode of the display
+  */
+int MicroBitDisplay::getDisplayMode()
+{
+    return this->mode;
+}
+
+/**
+  * Fetches the current brightness of this display.
+  *
+  * @return the brightness of this display, in the range 0..255.
+  *
+  * @code
+  * display.getBrightness(); //the current brightness
+  * @endcode
+  */
+int MicroBitDisplay::getBrightness()
+{
+    return this->brightness;
+}
+
+/**
+  * Rotates the display to the given position.
+  *
+  * Axis aligned values only.
+  *
+  * @code
+  * display.rotateTo(MICROBIT_DISPLAY_ROTATION_180); //rotates 180 degrees from original orientation
+  * @endcode
+  */
+void MicroBitDisplay::rotateTo(DisplayRotation rotation)
+{
+    this->rotation = rotation;
+}
+
+/**
+ * Enables or disables the display entirely, and releases the pins for other uses.
+ *
+ * @param enableDisplay true to enabled the display, or false to disable it.
+ */
+void MicroBitDisplay::setEnable(bool enableDisplay)
+{
+    // If we're already in the correct state, then there's nothing to do.
+    if(((status & MICROBIT_COMPONENT_RUNNING) && enableDisplay) || (!(status & MICROBIT_COMPONENT_RUNNING) && !enableDisplay))
+        return;
+
+    uint32_t rmask = 0;
+    uint32_t cmask = 0;
+
+    for (int i = matrixMap.rowStart; i < matrixMap.rowStart + matrixMap.rows; i++)
+        rmask |= 0x01 << i;
+
+    for (int i = matrixMap.columnStart; i < matrixMap.columnStart + matrixMap.columns; i++)
+        cmask |= 0x01 << i;
+
+    if (enableDisplay)
+    {
+        PortOut p(Port0, rmask | cmask);
+        status |= MICROBIT_COMPONENT_RUNNING;
+    }
+    else
+    {
+        PortIn p(Port0, rmask | cmask);
+        p.mode(PullNone);
+        status &= ~MICROBIT_COMPONENT_RUNNING;
+    }
+}
+
+/**
+  * Enables the display, should only be called if the display is disabled.
+  *
+  * @code
+  * display.enable(); //Enables the display mechanics
+  * @endcode
+  *
+  * @note Only enables the display if the display is currently disabled.
+  */
+void MicroBitDisplay::enable()
+{
+    setEnable(true);
+}
+
+/**
+  * Disables the display, which releases control of the GPIO pins used by the display,
+  * which are exposed on the edge connector.
+  *
+  * @code
+  * display.disable(); //disables the display
+  * @endcode
+  *
+  * @note Only disables the display if the display is currently enabled.
+  */
+void MicroBitDisplay::disable()
+{
+    setEnable(false);
+}
+
+/**
+  * Clears the display of any remaining pixels.
+  *
+  * `display.image.clear()` can also be used!
+  *
+  * @code
+  * display.clear(); //clears the display
+  * @endcode
+  */
+void MicroBitDisplay::clear()
+{
+    image.clear();
+}
+
+/**
+  * Updates the font that will be used for display operations.
+  *
+  * @param font the new font that will be used to render characters.
+  *
+  * @note DEPRECATED! Please use MicroBitFont::setSystemFont() instead.
+  */
+void MicroBitDisplay::setFont(MicroBitFont font)
+{
+	MicroBitFont::setSystemFont(font);
+}
+
+/**
+  * Retrieves the font object used for rendering characters on the display.
+  *
+  * @note DEPRECATED! Please use MicroBitFont::getSystemFont() instead.
+  */
+MicroBitFont MicroBitDisplay::getFont()
+{
+	return MicroBitFont::getSystemFont();
+}
+
+/**
+  * Captures the bitmap currently being rendered on the display.
+  *
+  * @return a MicroBitImage containing the captured data.
+  */
+MicroBitImage MicroBitDisplay::screenShot()
+{
+    return image.crop(0,0,MICROBIT_DISPLAY_WIDTH,MICROBIT_DISPLAY_HEIGHT);
+}
+
+/**
+  * Gives a representative figure of the light level in the current environment
+  * where are micro:bit is situated.
+  *
+  * Internally, it constructs an instance of a MicroBitLightSensor if not already configured
+  * and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
+  *
+  * This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
+  * that the display does not suffer from artifacts.
+  *
+  * @return an indicative light level in the range 0 - 255.
+  *
+  * @note this will return 0 on the first call to this method, a light reading
+  * will be available after the display has activated the light sensor for the
+  * first time.
+  */
+int MicroBitDisplay::readLightLevel()
+{
+    if(mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
+    {
+        setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE);
+        this->lightSensor = new MicroBitLightSensor(matrixMap);
+    }
+
+    return this->lightSensor->read();
+}
+
+/**
+  * Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
+  */
+MicroBitDisplay::~MicroBitDisplay()
+{
+    system_timer_remove_component(this);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitI2C.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,134 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitI2C.h"
+#include "ErrorNo.h"
+#include "twi_master.h"
+#include "nrf_delay.h"
+
+/**
+  * Constructor.
+  *
+  * Create an instance of MicroBitI2C for I2C communication.
+  *
+  * @param sda the Pin to be used for SDA
+  *
+  * @param scl the Pin to be used for SCL
+  *
+  * @code
+  * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
+  * @endcode
+  *
+  * @note This class presents a wrapped mbed call to capture failed I2C operations caused by a known silicon bug in the nrf51822.
+  * Attempts to automatically reset and restart the I2C hardware if this case is detected.
+  * \par
+  * For reference see PAN56 in:
+  * \par
+  * https://www.nordicsemi.com/eng/nordic/Products/nRF51822/PAN-nRF51822/24634
+  * \par
+  * v2.0 through to v2.4
+  */
+MicroBitI2C::MicroBitI2C(PinName sda, PinName scl) : I2C(sda,scl)
+{
+    this->retries = 0;
+}
+
+/**
+  * Performs a complete read transaction. The bottom bit of the address is forced to 1 to indicate a read.
+  *
+  * @param address 8-bit I2C slave address [ addr | 1 ]
+  *
+  * @param data A pointer to a byte buffer used for storing retrieved data.
+  *
+  * @param length Number of bytes to read.
+  *
+  * @param repeated if true, stop is not sent at the end. Defaults to false.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved read failure is detected.
+  */
+int MicroBitI2C::read(int address, char *data, int length, bool repeated)
+{
+    int result = I2C::read(address,data,length,repeated);
+
+    //0 indicates a success, presume failure
+    while(result != 0 && retries < MICROBIT_I2C_MAX_RETRIES)
+    {
+        _i2c.i2c->EVENTS_ERROR = 0;
+        _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+        _i2c.i2c->POWER        = 0;
+        nrf_delay_us(5);
+        _i2c.i2c->POWER        = 1;
+        _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
+        twi_master_init_and_clear();
+        result = I2C::read(address,data,length,repeated);
+        retries++;
+    }
+
+    if(result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    retries = 0;
+    return MICROBIT_OK;
+}
+
+/**
+  * Performs a complete write transaction. The bottom bit of the address is forced to 0 to indicate a write.
+  *
+  * @param address 8-bit I2C slave address [ addr | 0 ]
+  *
+  * @param data A pointer to a byte buffer containing the data to write.
+  *
+  * @param length Number of bytes to write
+  *
+  * @param repeated if true, stop is not sent at the end. Defaults to false.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if an unresolved write failure is detected.
+  */
+int MicroBitI2C::write(int address, const char *data, int length, bool repeated)
+{
+    int result = I2C::write(address,data,length,repeated);
+
+    //0 indicates a success, presume failure
+    while(result != 0 && retries < MICROBIT_I2C_MAX_RETRIES)
+    {
+        _i2c.i2c->EVENTS_ERROR = 0;
+        _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+        _i2c.i2c->POWER        = 0;
+        nrf_delay_us(5);
+        _i2c.i2c->POWER        = 1;
+        _i2c.i2c->ENABLE       = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
+
+        twi_master_init_and_clear();
+        result = I2C::write(address,data,length,repeated);
+        retries++;
+    }
+
+    if(result != 0)
+        return MICROBIT_I2C_ERROR;
+
+    retries = 0;
+    return MICROBIT_OK;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitIO.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,70 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBit IO.
+  *
+  * Represents a collection of all I/O pins on the edge connector.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitIO.h"
+
+/**
+  * Constructor.
+  *
+  * Create a representation of all given I/O pins on the edge connector
+  *
+  * Accepts a sequence of unique ID's used to distinguish events raised
+  * by MicroBitPin instances on the default EventModel.
+  */
+MicroBitIO::MicroBitIO(int ID_P0, int ID_P1, int ID_P2,
+                       int ID_P3, int ID_P4, int ID_P5,
+                       int ID_P6, int ID_P7, int ID_P8,
+                       int ID_P9, int ID_P10,int ID_P11,
+                       int ID_P12,int ID_P13,int ID_P14,
+                       int ID_P15,int ID_P16,int ID_P19,
+                       int ID_P20) :
+    P0 (ID_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL),            //P0 is the left most pad (ANALOG/DIGITAL/TOUCH)
+    P1 (ID_P1, MICROBIT_PIN_P1, PIN_CAPABILITY_ALL),            //P1 is the middle pad (ANALOG/DIGITAL/TOUCH)
+    P2 (ID_P2, MICROBIT_PIN_P2, PIN_CAPABILITY_ALL),            //P2 is the right most pad (ANALOG/DIGITAL/TOUCH)
+    P3 (ID_P3, MICROBIT_PIN_P3, PIN_CAPABILITY_AD),             //COL1 (ANALOG/DIGITAL)
+    P4 (ID_P4, MICROBIT_PIN_P4, PIN_CAPABILITY_AD),             //COL2 (ANALOG/DIGITAL)
+    P5 (ID_P5, MICROBIT_PIN_P5, PIN_CAPABILITY_DIGITAL),        //BTN_A
+    P6 (ID_P6, MICROBIT_PIN_P6, PIN_CAPABILITY_DIGITAL),        //ROW2
+    P7 (ID_P7, MICROBIT_PIN_P7, PIN_CAPABILITY_DIGITAL),        //ROW1
+    P8 (ID_P8, MICROBIT_PIN_P8, PIN_CAPABILITY_DIGITAL),        //PIN 18
+    P9 (ID_P9, MICROBIT_PIN_P9, PIN_CAPABILITY_DIGITAL),        //ROW3
+    P10(ID_P10,MICROBIT_PIN_P10,PIN_CAPABILITY_AD),             //COL3 (ANALOG/DIGITAL)
+    P11(ID_P11,MICROBIT_PIN_P11,PIN_CAPABILITY_DIGITAL),        //BTN_B
+    P12(ID_P12,MICROBIT_PIN_P12,PIN_CAPABILITY_DIGITAL),        //PIN 20
+    P13(ID_P13,MICROBIT_PIN_P13,PIN_CAPABILITY_DIGITAL),        //SCK
+    P14(ID_P14,MICROBIT_PIN_P14,PIN_CAPABILITY_DIGITAL),        //MISO
+    P15(ID_P15,MICROBIT_PIN_P15,PIN_CAPABILITY_DIGITAL),        //MOSI
+    P16(ID_P16,MICROBIT_PIN_P16,PIN_CAPABILITY_DIGITAL),        //PIN 16
+    P19(ID_P19,MICROBIT_PIN_P19,PIN_CAPABILITY_DIGITAL),        //SCL
+    P20(ID_P20,MICROBIT_PIN_P20,PIN_CAPABILITY_DIGITAL)         //SDA
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitLightSensor.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,180 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBitLightSensor.
+  *
+  * This is an object that interleaves light sensing with MicroBitDisplay.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitLightSensor.h"
+#include "MicroBitDisplay.h"
+
+/**
+  * After the startSensing method has been called, this method will be called
+  * MICROBIT_LIGHT_SENSOR_AN_SET_TIME after.
+  *
+  * It will then read from the currently selected channel using the AnalogIn
+  * that was configured in the startSensing method.
+  */
+void MicroBitLightSensor::analogReady()
+{
+    this->results[chan] = this->sensePin->read_u16();
+
+    analogDisable();
+
+    DigitalOut((PinName)(matrixMap.columnStart + chan)).write(1);
+
+    chan++;
+
+    chan = chan % MICROBIT_LIGHT_SENSOR_CHAN_NUM;
+}
+
+/**
+  * Forcibly disables the AnalogIn, otherwise it will remain in possession
+  * of the GPIO channel it is using, meaning that the display will not be
+  * able to use a channel (COL).
+  *
+  * This is required as per PAN 3, details of which can be found here:
+  *
+  * https://www.nordicsemi.com/eng/nordic/download_resource/24634/5/88440387
+  */
+void MicroBitLightSensor::analogDisable()
+{
+    NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;
+
+    NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) |
+                      (ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos) |
+                      (ADC_CONFIG_REFSEL_VBG                       << ADC_CONFIG_REFSEL_Pos) |
+                      (ADC_CONFIG_PSEL_Disabled                    << ADC_CONFIG_PSEL_Pos) |
+                      (ADC_CONFIG_EXTREFSEL_None                   << ADC_CONFIG_EXTREFSEL_Pos);
+}
+
+/**
+  * Constructor.
+  *
+  * Create a representation of the light sensor.
+  *
+  * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
+  *            Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
+  */
+MicroBitLightSensor::MicroBitLightSensor(const MatrixMap &map) :
+    analogTrigger(),
+    matrixMap(map)
+{
+    this->chan = 0;
+
+    for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
+        results[i] = 0;
+
+    if (EventModel::defaultEventBus)
+        EventModel::defaultEventBus->listen(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing, MESSAGE_BUS_LISTENER_IMMEDIATE);
+
+    this->sensePin = NULL;
+}
+
+/**
+  * This method returns a summed average of the three sections of the display.
+  *
+  * A section is defined as:
+  *  ___________________
+  * | 1 |   | 2 |   | 3 |
+  * |___|___|___|___|___|
+  * |   |   |   |   |   |
+  * |___|___|___|___|___|
+  * | 2 |   | 3 |   | 1 |
+  * |___|___|___|___|___|
+  * |   |   |   |   |   |
+  * |___|___|___|___|___|
+  * | 3 |   | 1 |   | 2 |
+  * |___|___|___|___|___|
+  *
+  * Where each number represents a different section on the 5 x 5 matrix display.
+  *
+  * @return returns a value in the range 0 - 255 where 0 is dark, and 255
+  * is very bright
+  */
+int MicroBitLightSensor::read()
+{
+    int sum = 0;
+
+    for(int i = 0; i < MICROBIT_LIGHT_SENSOR_CHAN_NUM; i++)
+        sum += results[i];
+
+    int average = sum / MICROBIT_LIGHT_SENSOR_CHAN_NUM;
+
+    average = min(average, MICROBIT_LIGHT_SENSOR_MAX_VALUE);
+
+    average = max(average, MICROBIT_LIGHT_SENSOR_MIN_VALUE);
+
+    int inverted = (MICROBIT_LIGHT_SENSOR_MAX_VALUE - average) + MICROBIT_LIGHT_SENSOR_MIN_VALUE;
+
+    int a = 0;
+
+    int b = 255;
+
+    int normalised = a + ((((inverted - MICROBIT_LIGHT_SENSOR_MIN_VALUE)) * (b - a))/ (MICROBIT_LIGHT_SENSOR_MAX_VALUE - MICROBIT_LIGHT_SENSOR_MIN_VALUE));
+
+    return normalised;
+}
+
+/**
+  * The method that is invoked by sending MICROBIT_DISPLAY_EVT_LIGHT_SENSE
+  * using the id MICROBIT_ID_DISPLAY.
+  *
+  * @note this can be manually driven by calling this member function, with
+  *       a MicroBitEvent using the CREATE_ONLY option of the MicroBitEvent
+  *       constructor.
+  */
+void MicroBitLightSensor::startSensing(MicroBitEvent)
+{
+    for(int rowCount = 0; rowCount < matrixMap.rows; rowCount++)
+        DigitalOut((PinName)(matrixMap.rowStart + rowCount)).write(0);
+
+    PinName currentPin = (PinName)(matrixMap.columnStart + chan);
+
+    DigitalOut(currentPin).write(1);
+
+    DigitalIn(currentPin, PullNone).~DigitalIn();
+
+    if(this->sensePin != NULL)
+        delete this->sensePin;
+
+    this->sensePin = new AnalogIn(currentPin);
+
+    analogTrigger.attach_us(this, &MicroBitLightSensor::analogReady, MICROBIT_LIGHT_SENSOR_AN_SET_TIME);
+}
+
+/**
+  * A destructor for MicroBitLightSensor.
+  *
+  * The destructor removes the listener, used by MicroBitLightSensor from the default EventModel.
+  */
+MicroBitLightSensor::~MicroBitLightSensor()
+{
+    if (EventModel::defaultEventBus)
+        EventModel::defaultEventBus->ignore(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_LIGHT_SENSE, this, &MicroBitLightSensor::startSensing);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitMessageBus.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,549 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the MicroBitMessageBus.
+  *
+  * The MicroBitMessageBus is the common mechanism to deliver asynchronous events on the
+  * MicroBit platform. It serves a number of purposes:
+  *
+  * 1) It provides an eventing abstraction that is independent of the underlying substrate.
+  *
+  * 2) It provides a mechanism to decouple user code from trusted system code
+  *    i.e. the basis of a message passing nano kernel.
+  *
+  * 3) It allows a common high level eventing abstraction across a range of hardware types.e.g. buttons, BLE...
+  *
+  * 4) It provides a mechanim for extensibility - new devices added via I/O pins can have OO based
+  *    drivers and communicate via the message bus with minima impact on user level languages.
+  *
+  * 5) It allows for the possiblility of event / data aggregation, which in turn can save energy.
+  *
+  * It has the following design principles:
+  *
+  * 1) Maintain a low RAM footprint where possible
+  *
+  * 2) Make few assumptions about the underlying platform, but allow optimizations where possible.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitMessageBus.h"
+#include "MicroBitFiber.h"
+#include "ErrorNo.h"
+
+/**
+  * Default constructor.
+  *
+  * Adds itself as a fiber component, and also configures itself to be the
+  * default EventModel if defaultEventBus is NULL.
+  */
+MicroBitMessageBus::MicroBitMessageBus()
+{
+	this->listeners = NULL;
+    this->evt_queue_head = NULL;
+    this->evt_queue_tail = NULL;
+    this->queueLength = 0;
+
+	fiber_add_idle_component(this);
+
+	if(EventModel::defaultEventBus == NULL)
+		EventModel::defaultEventBus = this;
+}
+
+/**
+  * Invokes a callback on a given MicroBitListener
+  *
+  * Internal wrapper function, used to enable
+  * parameterised callbacks through the fiber scheduler.
+  */
+void async_callback(void *param)
+{
+	MicroBitListener *listener = (MicroBitListener *)param;
+
+    // OK, now we need to decide how to behave depending on our configuration.
+    // If this a fiber f already active within this listener then check our
+    // configuration to determine the correct course of action.
+    //
+
+    if (listener->flags & MESSAGE_BUS_LISTENER_BUSY)
+    {
+        // Drop this event, if that's how we've been configured.
+        if (listener->flags & MESSAGE_BUS_LISTENER_DROP_IF_BUSY)
+            return;
+
+        // Queue this event up for later, if that's how we've been configured.
+        if (listener->flags & MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY)
+        {
+            listener->queue(listener->evt);
+            return;
+        }
+    }
+
+    // Determine the calling convention for the callback, and invoke...
+    // C++ is really bad at this! Especially as the ARM compiler is yet to support C++ 11 :-/
+
+    // Record that we have a fiber going into this listener...
+    listener->flags |= MESSAGE_BUS_LISTENER_BUSY;
+
+    while (1)
+    {
+        // Firstly, check for a method callback into an object.
+        if (listener->flags & MESSAGE_BUS_LISTENER_METHOD)
+            listener->cb_method->fire(listener->evt);
+
+        // Now a parameterised C function
+        else if (listener->flags & MESSAGE_BUS_LISTENER_PARAMETERISED)
+            listener->cb_param(listener->evt, listener->cb_arg);
+
+        // We must have a plain C function
+        else
+            listener->cb(listener->evt);
+
+        // If there are more events to process, dequeue the next one and process it.
+        if ((listener->flags & MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY) && listener->evt_queue)
+        {
+            MicroBitEventQueueItem *item = listener->evt_queue;
+
+            listener->evt = item->evt;
+            listener->evt_queue = listener->evt_queue->next;
+            delete item;
+
+            // We spin the scheduler here, to preven any particular event handler from continuously holding onto resources.
+            schedule();
+        }
+        else
+            break;
+    }
+
+    // The fiber of exiting... clear our state.
+    listener->flags &= ~MESSAGE_BUS_LISTENER_BUSY;
+}
+
+/**
+  * Queue the given event for processing at a later time.
+  * Add the given event at the tail of our queue.
+  *
+  * @param The event to queue.
+  */
+void MicroBitMessageBus::queueEvent(MicroBitEvent &evt)
+{
+    int processingComplete;
+
+    MicroBitEventQueueItem *prev = evt_queue_tail;
+
+    // Now process all handler regsitered as URGENT.
+    // These pre-empt the queue, and are useful for fast, high priority services.
+    processingComplete = this->process(evt, true);
+
+    // If we've already processed all event handlers, we're all done.
+    // No need to queue the event.
+    if (processingComplete)
+        return;
+
+    // If we need to queue, but there is no space, then there's nothg we can do.
+    if (queueLength >= MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH)
+        return;
+
+    // Otherwise, we need to queue this event for later processing...
+    // We queue this event at the tail of the queue at the point where we entered queueEvent()
+    // This is important as the processing above *may* have generated further events, and
+    // we want to maintain ordering of events.
+    MicroBitEventQueueItem *item = new MicroBitEventQueueItem(evt);
+
+    // The queue was empty when we entered this function, so queue our event at the start of the queue.
+    __disable_irq();
+
+    if (prev == NULL)
+    {
+        item->next = evt_queue_head;
+        evt_queue_head = item;
+    }
+    else
+    {
+        item->next = prev->next;
+        prev->next = item;
+    }
+
+    if (item->next == NULL)
+        evt_queue_tail = item;
+
+    queueLength++;
+
+    __enable_irq();
+}
+
+/**
+  * Extract the next event from the front of the event queue (if present).
+  *
+  * @return a pointer to the MicroBitEventQueueItem that is at the head of the list.
+  */
+MicroBitEventQueueItem* MicroBitMessageBus::dequeueEvent()
+{
+    MicroBitEventQueueItem *item = NULL;
+
+    __disable_irq();
+
+    if (evt_queue_head != NULL)
+    {
+        item = evt_queue_head;
+        evt_queue_head = item->next;
+
+        if (evt_queue_head == NULL)
+            evt_queue_tail = NULL;
+
+        queueLength--;
+    }
+
+    __enable_irq();
+
+
+    return item;
+}
+
+/**
+  * Cleanup any MicroBitListeners marked for deletion from the list.
+  *
+  * @return The number of listeners removed from the list.
+  */
+int MicroBitMessageBus::deleteMarkedListeners()
+{
+	MicroBitListener *l, *p;
+    int removed = 0;
+
+	l = listeners;
+	p = NULL;
+
+    // Walk this list of event handlers. Delete any that match the given listener.
+    while (l != NULL)
+    {
+        if ((l->flags & MESSAGE_BUS_LISTENER_DELETING) && !(l->flags & MESSAGE_BUS_LISTENER_BUSY))
+        {
+            if (p == NULL)
+                listeners = l->next;
+            else
+                p->next = l->next;
+
+            // delete the listener.
+            MicroBitListener *t = l;
+            l = l->next;
+
+            delete t;
+            removed++;
+
+            continue;
+        }
+
+        p = l;
+        l = l->next;
+    }
+
+    return removed;
+}
+
+/**
+  * Periodic callback from MicroBit.
+  *
+  * Process at least one event from the event queue, if it is not empty.
+  * We then continue processing events until something appears on the runqueue.
+  */
+void MicroBitMessageBus::idleTick()
+{
+    // Clear out any listeners marked for deletion
+    this->deleteMarkedListeners();
+
+    MicroBitEventQueueItem *item = this->dequeueEvent();
+
+    // Whilst there are events to process and we have no useful other work to do, pull them off the queue and process them.
+    while (item)
+    {
+        // send the event to all standard event listeners.
+        this->process(item->evt);
+
+        // Free the queue item.
+        delete item;
+
+        // If we have created some useful work to do, we stop processing.
+        // This helps to minimise the number of blocked fibers we create at any point in time, therefore
+        // also reducing the RAM footprint.
+        if(!scheduler_runqueue_empty())
+            break;
+
+        // Pull the next event to process, if there is one.
+        item = this->dequeueEvent();
+    }
+}
+
+/**
+  * Queues the given event to be sent to all registered recipients.
+  *
+  * @param evt The event to send.
+  *
+  * @code
+  * MicroBitMessageBus bus;
+  *
+  * // Creates and sends the MicroBitEvent using bus.
+  * MicrobitEvent evt(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
+  *
+  * // Creates the MicrobitEvent, but delays the sending of that event.
+  * MicrobitEvent evt1(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, CREATE_ONLY);
+  *
+  * bus.send(evt1);
+  *
+  * // This has the same effect!
+  * evt1.fire()
+  * @endcode
+  */
+int MicroBitMessageBus::send(MicroBitEvent evt)
+{
+    // We simply queue processing of the event until we're scheduled in normal thread context.
+    // We do this to avoid the possibility of executing event handler code in IRQ context, which may bring
+    // hidden race conditions to kids code. Queuing all events ensures causal ordering (total ordering in fact).
+    this->queueEvent(evt);
+    return MICROBIT_OK;
+}
+
+/**
+  * Internal function, used to deliver the given event to all relevant recipients.
+  * Normally, this is called once an event has been removed from the event queue.
+  *
+  * @param evt The event to send.
+  *
+  * @param urgent The type of listeners to process (optional). If set to true, only listeners defined as urgent and non-blocking will be processed
+  *               otherwise, all other (standard) listeners will be processed. Defaults to false.
+  *
+  * @return 1 if all matching listeners were processed, 0 if further processing is required.
+  *
+  * @note It is recommended that all external code uses the send() function instead of this function,
+  *       or the constructors provided by MicrobitEvent.
+  */
+int MicroBitMessageBus::process(MicroBitEvent &evt, bool urgent)
+{
+	MicroBitListener *l;
+    int complete = 1;
+    bool listenerUrgent;
+
+    l = listeners;
+    while (l != NULL)
+    {
+	    if((l->id == evt.source || l->id == MICROBIT_ID_ANY) && (l->value == evt.value || l->value == MICROBIT_EVT_ANY))
+        {
+            // If we're running under the fiber scheduler, then derive the THREADING_MODE for the callback based on the
+            // metadata in the listener itself.
+            if (fiber_scheduler_running())
+                listenerUrgent = (l->flags & MESSAGE_BUS_LISTENER_IMMEDIATE) == MESSAGE_BUS_LISTENER_IMMEDIATE;
+            else
+                listenerUrgent = true;
+
+            // If we should process this event hander in this pass, then activate the listener.
+            if(listenerUrgent == urgent && !(l->flags & MESSAGE_BUS_LISTENER_DELETING))
+            {
+                l->evt = evt;
+
+                // OK, if this handler has regisitered itself as non-blocking, we just execute it directly...
+                // This is normally only done for trusted system components.
+                // Otherwise, we invoke it in a 'fork on block' context, that will automatically create a fiber
+                // should the event handler attempt a blocking operation, but doesn't have the overhead
+                // of creating a fiber needlessly. (cool huh?)
+				if (l->flags & MESSAGE_BUS_LISTENER_NONBLOCKING || !fiber_scheduler_running())
+					async_callback(l);
+				else
+					invoke(async_callback, l);
+            }
+            else
+            {
+                complete = 0;
+            }
+		}
+
+		l = l->next;
+	}
+
+    return complete;
+}
+
+/**
+  * Add the given MicroBitListener to the list of event handlers, unconditionally.
+  *
+  * @param listener The MicroBitListener to add.
+  *
+  * @return MICROBIT_OK if the listener is valid, MICROBIT_INVALID_PARAMETER otherwise.
+  */
+int MicroBitMessageBus::add(MicroBitListener *newListener)
+{
+	MicroBitListener *l, *p;
+    int methodCallback;
+
+	//handler can't be NULL!
+	if (newListener == NULL)
+		return MICROBIT_INVALID_PARAMETER;
+
+	l = listeners;
+
+	// Firstly, we treat a listener as an idempotent operation. Ensure we don't already have this handler
+	// registered in a that will already capture these events. If we do, silently ignore.
+
+    // We always check the ID, VALUE and CB_METHOD fields.
+    // If we have a callback to a method, check the cb_method class. Otherwise, the cb function point is sufficient.
+    while (l != NULL)
+    {
+        methodCallback = (newListener->flags & MESSAGE_BUS_LISTENER_METHOD) && (l->flags & MESSAGE_BUS_LISTENER_METHOD);
+
+        if (l->id == newListener->id && l->value == newListener->value && (methodCallback ? *l->cb_method == *newListener->cb_method : l->cb == newListener->cb))
+        {
+            // We have a perfect match for this event listener already registered.
+            // If it's marked for deletion, we simply resurrect the listener, and we're done.
+            // Either way, we return an error code, as the *new* listener should be released...
+            if(l->flags & MESSAGE_BUS_LISTENER_DELETING)
+                l->flags &= ~MESSAGE_BUS_LISTENER_DELETING;
+
+            return MICROBIT_NOT_SUPPORTED;
+        }
+
+        l = l->next;
+    }
+
+    // We have a valid, new event handler. Add it to the list.
+	// if listeners is null - we can automatically add this listener to the list at the beginning...
+	if (listeners == NULL)
+	{
+		listeners = newListener;
+        MicroBitEvent(MICROBIT_ID_MESSAGE_BUS_LISTENER, newListener->id);
+
+		return MICROBIT_OK;
+	}
+
+	// We maintain an ordered list of listeners.
+	// The chain is held stictly in increasing order of ID (first level), then value code (second level).
+	// Find the correct point in the chain for this event.
+	// Adding a listener is a rare occurance, so we just walk the list...
+
+	p = listeners;
+	l = listeners;
+
+	while (l != NULL && l->id < newListener->id)
+	{
+		p = l;
+		l = l->next;
+	}
+
+	while (l != NULL && l->id == newListener->id && l->value < newListener->value)
+	{
+		p = l;
+		l = l->next;
+	}
+
+	//add at front of list
+	if (p == listeners && (newListener->id < p->id || (p->id == newListener->id && p->value > newListener->value)))
+	{
+		newListener->next = p;
+
+		//this new listener is now the front!
+		listeners = newListener;
+	}
+
+	//add after p
+	else
+	{
+		newListener->next = p->next;
+		p->next = newListener;
+	}
+
+    MicroBitEvent(MICROBIT_ID_MESSAGE_BUS_LISTENER, newListener->id);
+    return MICROBIT_OK;
+}
+
+/**
+  * Remove the given MicroBitListener from the list of event handlers.
+  *
+  * @param listener The MicroBitListener to remove.
+  *
+  * @return MICROBIT_OK if the listener is valid, MICROBIT_INVALID_PARAMETER otherwise.
+  */
+int MicroBitMessageBus::remove(MicroBitListener *listener)
+{
+	MicroBitListener *l;
+    int removed = 0;
+
+	//handler can't be NULL!
+	if (listener == NULL)
+		return MICROBIT_INVALID_PARAMETER;
+
+	l = listeners;
+
+    // Walk this list of event handlers. Delete any that match the given listener.
+    while (l != NULL)
+    {
+        if ((listener->flags & MESSAGE_BUS_LISTENER_METHOD) == (l->flags & MESSAGE_BUS_LISTENER_METHOD))
+        {
+            if(((listener->flags & MESSAGE_BUS_LISTENER_METHOD) && (*l->cb_method == *listener->cb_method)) ||
+              ((!(listener->flags & MESSAGE_BUS_LISTENER_METHOD) && l->cb == listener->cb)))
+            {
+                if ((listener->id == MICROBIT_ID_ANY || listener->id == l->id) && (listener->value == MICROBIT_EVT_ANY || listener->value == l->value))
+                {
+                    // Found a match. mark this to be removed from the list.
+                    l->flags |= MESSAGE_BUS_LISTENER_DELETING;
+                    removed++;
+                }
+            }
+        }
+
+        l = l->next;
+    }
+
+    if (removed > 0)
+        return MICROBIT_OK;
+    else
+        return MICROBIT_INVALID_PARAMETER;
+}
+
+/**
+  * Returns the microBitListener with the given position in our list.
+  *
+  * @param n The position in the list to return.
+  *
+  * @return the MicroBitListener at postion n in the list, or NULL if the position is invalid.
+  */
+MicroBitListener* MicroBitMessageBus::elementAt(int n)
+{
+    MicroBitListener *l = listeners;
+
+    while (n > 0)
+    {
+        if (l == NULL)
+            return NULL;
+
+        n--;
+        l = l->next;
+    }
+
+    return l;
+}
+
+/**
+  * Destructor for MicroBitMessageBus, where we deregister this instance from the array of fiber components.
+  */
+MicroBitMessageBus::~MicroBitMessageBus()
+{
+    fiber_remove_idle_component(this);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitMultiButton.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,298 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBitMultiButton.
+  *
+  * Represents a virtual button, capable of reacting to simultaneous presses of two
+  * other buttons.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitMultiButton.h"
+
+/**
+  * Constructor.
+  *
+  * Create a representation of a virtual button, that generates events based upon the combination
+  * of two given buttons.
+  *
+  * @param button1 the unique ID of the first button to watch.
+  *
+  * @param button2 the unique ID of the second button to watch.
+  *
+  * @param id the unique EventModel id of this MicroBitMultiButton instance.
+  *
+  * @code
+  * multiButton(MICROBIT_ID_BUTTON_A, MICROBIT_ID_BUTTON_B, MICROBIT_ID_BUTTON_AB);
+  * @endcode
+  */
+MicroBitMultiButton::MicroBitMultiButton(uint16_t button1, uint16_t button2, uint16_t id)
+{
+    this->id = id;
+    this->button1 = button1;
+    this->button2 = button2;
+    this->eventConfiguration = MICROBIT_BUTTON_SIMPLE_EVENTS;
+
+    if (EventModel::defaultEventBus)
+    {
+        EventModel::defaultEventBus->listen(button1, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent,  MESSAGE_BUS_LISTENER_IMMEDIATE);
+        EventModel::defaultEventBus->listen(button2, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent,  MESSAGE_BUS_LISTENER_IMMEDIATE);
+    }
+}
+
+/**
+  * Retrieves the button id for the alternate button id given.
+  *
+  * @param b the id of the button whose state we would like to retrieve.
+  *
+  * @return the other sub button id.
+  */
+uint16_t MicroBitMultiButton::otherSubButton(uint16_t b)
+{
+    return (b == button1 ? button2 : button1);
+}
+
+/**
+  * Determines if the given button id is marked as pressed.
+  *
+  * @param button the id of the button whose state we would like to retrieve.
+  *
+  * @return 1 if pressed, 0 if not.
+  */
+int MicroBitMultiButton::isSubButtonPressed(uint16_t button)
+{
+    if (button == button1)
+        return status & MICROBIT_MULTI_BUTTON_STATE_1;
+
+    if (button == button2)
+        return status & MICROBIT_MULTI_BUTTON_STATE_2;
+
+    return 0;
+}
+
+/**
+  * Determines if the given button id is marked as held.
+  *
+  * @param button the id of the button whose state we would like to retrieve.
+  *
+  * @return 1 if held, 0 if not.
+  */
+int MicroBitMultiButton::isSubButtonHeld(uint16_t button)
+{
+    if (button == button1)
+        return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
+
+    if (button == button2)
+        return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
+
+    return 0;
+}
+
+/**
+  * Determines if the given button id is marked as supressed.
+  *
+  * @param button the id of the button whose state we would like to retrieve.
+  *
+  * @return 1 if supressed, 0 if not.
+  */
+int MicroBitMultiButton::isSubButtonSupressed(uint16_t button)
+{
+    if (button == button1)
+        return status & MICROBIT_MULTI_BUTTON_SUPRESSED_1;
+
+    if (button == button2)
+        return status & MICROBIT_MULTI_BUTTON_SUPRESSED_2;
+
+    return 0;
+}
+
+/**
+  * Configures the button pressed state for the given button id.
+  *
+  * @param button the id of the button whose state requires updating.
+  *
+  * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+  */
+void MicroBitMultiButton::setButtonState(uint16_t button, int value)
+{
+    if (button == button1)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_STATE_1;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_STATE_1;
+    }
+
+    if (button == button2)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_STATE_2;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_STATE_2;
+    }
+}
+
+/**
+  * Configures the button held state for the given button id.
+  *
+  * @param button the id of the button whose state requires updating.
+  *
+  * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+  */
+void MicroBitMultiButton::setHoldState(uint16_t button, int value)
+{
+    if (button == button1)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
+    }
+
+    if (button == button2)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
+    }
+}
+
+/**
+  * Configures the button suppressed state for the given button id.
+  *
+  * @param button the id of the button whose state requires updating.
+  *
+  * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
+  */
+void MicroBitMultiButton::setSupressedState(uint16_t button, int value)
+{
+    if (button == button1)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_SUPRESSED_1;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_1;
+    }
+
+    if (button == button2)
+    {
+        if (value)
+            status |= MICROBIT_MULTI_BUTTON_SUPRESSED_2;
+        else
+            status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_2;
+    }
+}
+
+/**
+  * Changes the event configuration of this button to the given MicroBitButtonEventConfiguration.
+  * All subsequent events generated by this button will then be informed by this configuration.
+  *
+  * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
+  *
+  * @code
+  * // Configure a button to generate all possible events.
+  * buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
+  *
+  * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
+  * buttonAB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+  * @endcode
+  */
+void MicroBitMultiButton::setEventConfiguration(MicroBitButtonEventConfiguration config)
+{
+    this->eventConfiguration = config;
+}
+
+/**
+  * A member function that is invoked when any event is detected from the two
+  * button IDs this MicrobitMultiButton instance was constructed with.
+  *
+  * @param evt the event received from the default EventModel.
+  */
+void MicroBitMultiButton::onButtonEvent(MicroBitEvent evt)
+{
+    int button = evt.source;
+    int otherButton = otherSubButton(button);
+
+    switch(evt.value)
+    {
+        case MICROBIT_BUTTON_EVT_DOWN:
+            setButtonState(button, 1);
+            if(isSubButtonPressed(otherButton))
+                MicroBitEvent e(id, MICROBIT_BUTTON_EVT_DOWN);
+
+        break;
+
+        case MICROBIT_BUTTON_EVT_HOLD:
+            setHoldState(button, 1);
+            if(isSubButtonHeld(otherButton))
+                MicroBitEvent e(id, MICROBIT_BUTTON_EVT_HOLD);
+
+        break;
+
+        case MICROBIT_BUTTON_EVT_UP:
+            if(isSubButtonPressed(otherButton))
+            {
+                MicroBitEvent e(id, MICROBIT_BUTTON_EVT_UP);
+
+                if (isSubButtonHeld(button) && isSubButtonHeld(otherButton))
+                    MicroBitEvent e(id, MICROBIT_BUTTON_EVT_LONG_CLICK);
+                else
+                    MicroBitEvent e(id, MICROBIT_BUTTON_EVT_CLICK);
+
+                setSupressedState(otherButton, 1);
+            }
+            else if (!isSubButtonSupressed(button) && eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS)
+            {
+                if (isSubButtonHeld(button))
+                    MicroBitEvent e(button, MICROBIT_BUTTON_EVT_LONG_CLICK);
+                else
+                    MicroBitEvent e(button, MICROBIT_BUTTON_EVT_CLICK);
+            }
+
+            setButtonState(button, 0);
+            setHoldState(button, 0);
+            setSupressedState(button, 0);
+
+        break;
+
+    }
+}
+
+
+/**
+  * Tests if this MicroBitMultiButton instance is virtually pressed.
+  *
+  * @return 1 if both physical buttons are pressed simultaneously.
+  *
+  * @code
+  * if(buttonAB.isPressed())
+  *     display.scroll("Pressed!");
+  * @endcode
+  */
+int MicroBitMultiButton::isPressed()
+{
+    return ((status & MICROBIT_MULTI_BUTTON_STATE_1) && (status & MICROBIT_MULTI_BUTTON_STATE_2));
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitPin.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,634 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for MicroBitPin.
+  *
+  * Commonly represents an I/O pin on the edge connector.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitPin.h"
+#include "MicroBitButton.h"
+#include "MicroBitSystemTimer.h"
+#include "TimedInterruptIn.h"
+#include "DynamicPwm.h"
+#include "ErrorNo.h"
+
+/**
+  * Constructor.
+  * Create a MicroBitPin instance, generally used to represent a pin on the edge connector.
+  *
+  * @param id the unique EventModel id of this component.
+  *
+  * @param name the mbed PinName for this MicroBitPin instance.
+  *
+  * @param capability the capabilities this MicroBitPin instance should have.
+  *                   (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
+  *
+  * @code
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
+  * @endcode
+  */
+MicroBitPin::MicroBitPin(int id, PinName name, PinCapability capability)
+{
+    //set mandatory attributes
+    this->id = id;
+    this->name = name;
+    this->capability = capability;
+    this->pullMode = MICROBIT_DEFAULT_PULLMODE;
+
+    // Power up in a disconnected, low power state.
+    // If we're unused, this is how it will stay...
+    this->status = 0x00;
+    this->pin = NULL;
+
+}
+
+/**
+  * Disconnect any attached mBed IO from this pin.
+  *
+  * Used only when pin changes mode (i.e. Input/Output/Analog/Digital)
+  */
+void MicroBitPin::disconnect()
+{
+    // This is a bit ugly, but rarely used code.
+    // It would be much better to use some polymorphism here, but the mBed I/O classes aren't arranged in an inheritance hierarchy... yet. :-)
+    if (status & IO_STATUS_DIGITAL_IN)
+        delete ((DigitalIn *)pin);
+
+    if (status & IO_STATUS_DIGITAL_OUT)
+        delete ((DigitalOut *)pin);
+
+    if (status & IO_STATUS_ANALOG_IN){
+        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; // forcibly disable the ADC - BUG in mbed....
+        delete ((AnalogIn *)pin);
+    }
+
+    if (status & IO_STATUS_ANALOG_OUT)
+    {
+        if(((DynamicPwm *)pin)->getPinName() == name)
+            ((DynamicPwm *)pin)->release();
+    }
+
+    if (status & IO_STATUS_TOUCH_IN)
+        delete ((MicroBitButton *)pin);
+
+    if ((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
+        delete ((TimedInterruptIn *)pin);
+
+    this->pin = NULL;
+    this->status = 0;
+}
+
+/**
+  * Configures this IO pin as a digital output (if necessary) and sets the pin to 'value'.
+  *
+  * @param value 0 (LO) or 1 (HI)
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+  *         if the given pin does not have digital capability.
+  *
+  * @code
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+  * P0.setDigitalValue(1); // P0 is now HI
+  * @endcode
+  */
+int MicroBitPin::setDigitalValue(int value)
+{
+    // Check if this pin has a digital mode...
+    if(!(PIN_CAPABILITY_DIGITAL & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    // Ensure we have a valid value.
+    if (value < 0 || value > 1)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Move into a Digital input state if necessary.
+    if (!(status & IO_STATUS_DIGITAL_OUT)){
+        disconnect();
+        pin = new DigitalOut(name);
+        status |= IO_STATUS_DIGITAL_OUT;
+    }
+
+    // Write the value.
+    ((DigitalOut *)pin)->write(value);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures this IO pin as a digital input (if necessary) and tests its current value.
+  *
+  *
+  * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+  *         if the given pin does not have digital capability.
+  *
+  * @code
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+  * P0.getDigitalValue(); // P0 is either 0 or 1;
+  * @endcode
+  */
+int MicroBitPin::getDigitalValue()
+{
+    //check if this pin has a digital mode...
+    if(!(PIN_CAPABILITY_DIGITAL & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    // Move into a Digital input state if necessary.
+    if (!(status & (IO_STATUS_DIGITAL_IN | IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
+    {
+        disconnect();
+        pin = new DigitalIn(name, (PinMode)pullMode);
+        status |= IO_STATUS_DIGITAL_IN;
+    }
+
+    if(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE))
+        return ((TimedInterruptIn *)pin)->read();
+
+    return ((DigitalIn *)pin)->read();
+}
+
+/**
+ * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value.
+ *
+ * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+ *
+ * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
+ *         if the given pin does not have digital capability.
+ *
+ * @code
+ * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+ * P0.getDigitalValue(PullUp); // P0 is either 0 or 1;
+ * @endcode
+ */
+int MicroBitPin::getDigitalValue(PinMode pull)
+{
+    setPull(pull);
+    return getDigitalValue();
+}
+
+int MicroBitPin::obtainAnalogChannel()
+{
+    // Move into an analogue input state if necessary, if we are no longer the focus of a DynamicPWM instance, allocate ourselves again!
+    if (!(status & IO_STATUS_ANALOG_OUT) || !(((DynamicPwm *)pin)->getPinName() == name)){
+        disconnect();
+        pin = (void *)DynamicPwm::allocate(name);
+        status |= IO_STATUS_ANALOG_OUT;
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures this IO pin as an analog/pwm output, and change the output value to the given level.
+  *
+  * @param value the level to set on the output pin, in the range 0 - 1024
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+  *         if the given pin does not have analog capability.
+  */
+int MicroBitPin::setAnalogValue(int value)
+{
+    //check if this pin has an analogue mode...
+    if(!(PIN_CAPABILITY_ANALOG & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    //sanitise the level value
+    if(value < 0 || value > MICROBIT_PIN_MAX_OUTPUT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    float level = (float)value / float(MICROBIT_PIN_MAX_OUTPUT);
+
+    //obtain use of the DynamicPwm instance, if it has changed / configure if we do not have one
+    if(obtainAnalogChannel() == MICROBIT_OK)
+        return ((DynamicPwm *)pin)->write(level);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures this IO pin as an analog/pwm output (if necessary) and configures the period to be 20ms,
+  * with a duty cycle between 500 us and 2500 us.
+  *
+  * A value of 180 sets the duty cycle to be 2500us, and a value of 0 sets the duty cycle to be 500us by default.
+  *
+  * This range can be modified to fine tune, and also tolerate different servos.
+  *
+  * @param value the level to set on the output pin, in the range 0 - 180.
+  *
+  * @param range which gives the span of possible values the i.e. the lower and upper bounds (center +/- range/2). Defaults to MICROBIT_PIN_DEFAULT_SERVO_RANGE.
+  *
+  * @param center the center point from which to calculate the lower and upper bounds. Defaults to MICROBIT_PIN_DEFAULT_SERVO_CENTER
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+  *         if the given pin does not have analog capability.
+  */
+int MicroBitPin::setServoValue(int value, int range, int center)
+{
+    //check if this pin has an analogue mode...
+    if(!(PIN_CAPABILITY_ANALOG & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    //sanitise the servo level
+    if(value < 0 || range < 1 || center < 1)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //clip - just in case
+    if(value > MICROBIT_PIN_MAX_SERVO_RANGE)
+        value = MICROBIT_PIN_MAX_SERVO_RANGE;
+
+    //calculate the lower bound based on the midpoint
+    int lower = (center - (range / 2)) * 1000;
+
+    value = value * 1000;
+
+    //add the percentage of the range based on the value between 0 and 180
+    int scaled = lower + (range * (value / MICROBIT_PIN_MAX_SERVO_RANGE));
+
+    return setServoPulseUs(scaled / 1000);
+}
+
+/**
+  * Configures this IO pin as an analogue input (if necessary), and samples the Pin for its analog value.
+  *
+  * @return the current analogue level on the pin, in the range 0 - 1024, or
+  *         MICROBIT_NOT_SUPPORTED if the given pin does not have analog capability.
+  *
+  * @code
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+  * P0.getAnalogValue(); // P0 is a value in the range of 0 - 1024
+  * @endcode
+  */
+int MicroBitPin::getAnalogValue()
+{
+    //check if this pin has an analogue mode...
+    if(!(PIN_CAPABILITY_ANALOG & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    // Move into an analogue input state if necessary.
+    if (!(status & IO_STATUS_ANALOG_IN)){
+        disconnect();
+        pin = new AnalogIn(name);
+        status |= IO_STATUS_ANALOG_IN;
+    }
+
+    //perform a read!
+    return ((AnalogIn *)pin)->read_u16();
+}
+
+/**
+  * Determines if this IO pin is currently configured as an input.
+  *
+  * @return 1 if pin is an analog or digital input, 0 otherwise.
+  */
+int MicroBitPin::isInput()
+{
+    return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_ANALOG_IN)) == 0 ? 0 : 1;
+}
+
+/**
+  * Determines if this IO pin is currently configured as an output.
+  *
+  * @return 1 if pin is an analog or digital output, 0 otherwise.
+  */
+int MicroBitPin::isOutput()
+{
+    return (status & (IO_STATUS_DIGITAL_OUT | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1;
+}
+
+/**
+  * Determines if this IO pin is currently configured for digital use.
+  *
+  * @return 1 if pin is digital, 0 otherwise.
+  */
+int MicroBitPin::isDigital()
+{
+    return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_DIGITAL_OUT)) == 0 ? 0 : 1;
+}
+
+/**
+  * Determines if this IO pin is currently configured for analog use.
+  *
+  * @return 1 if pin is analog, 0 otherwise.
+  */
+int MicroBitPin::isAnalog()
+{
+    return (status & (IO_STATUS_ANALOG_IN | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1;
+}
+
+/**
+  * Configures this IO pin as a "makey makey" style touch sensor (if necessary)
+  * and tests its current debounced state.
+  *
+  * Users can also subscribe to MicroBitButton events generated from this pin.
+  *
+  * @return 1 if pin is touched, 0 if not, or MICROBIT_NOT_SUPPORTED if this pin does not support touch capability.
+  *
+  * @code
+  * MicroBitMessageBus bus;
+  *
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
+  * if(P0.isTouched())
+  * {
+  *     //do something!
+  * }
+  *
+  * // subscribe to events generated by this pin!
+  * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_BUTTON_EVT_CLICK, someFunction);
+  * @endcode
+  */
+int MicroBitPin::isTouched()
+{
+    //check if this pin has a touch mode...
+    if(!(PIN_CAPABILITY_DIGITAL & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    // Move into a touch input state if necessary.
+    if (!(status & IO_STATUS_TOUCH_IN)){
+        disconnect();
+        pin = new MicroBitButton(name, id);
+        status |= IO_STATUS_TOUCH_IN;
+    }
+
+    return ((MicroBitButton *)pin)->isPressed();
+}
+
+/**
+  * Configures this IO pin as an analog/pwm output if it isn't already, configures the period to be 20ms,
+  * and sets the pulse width, based on the value it is given.
+  *
+  * @param pulseWidth the desired pulse width in microseconds.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
+  *         if the given pin does not have analog capability.
+  */
+int MicroBitPin::setServoPulseUs(int pulseWidth)
+{
+    //check if this pin has an analogue mode...
+    if(!(PIN_CAPABILITY_ANALOG & capability))
+        return MICROBIT_NOT_SUPPORTED;
+
+    //sanitise the pulse width
+    if(pulseWidth < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //Check we still have the control over the DynamicPwm instance
+    if(obtainAnalogChannel() == MICROBIT_OK)
+    {
+        //check if the period is set to 20ms
+        if(((DynamicPwm *)pin)->getPeriodUs() != MICROBIT_DEFAULT_PWM_PERIOD)
+            ((DynamicPwm *)pin)->setPeriodUs(MICROBIT_DEFAULT_PWM_PERIOD);
+
+        ((DynamicPwm *)pin)->pulsewidth_us(pulseWidth);
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures the PWM period of the analog output to the given value.
+  *
+  * @param period The new period for the analog output in microseconds.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
+  *         given pin is not configured as an analog output.
+  */
+int MicroBitPin::setAnalogPeriodUs(int period)
+{
+    if (!(status & IO_STATUS_ANALOG_OUT))
+        return MICROBIT_NOT_SUPPORTED;
+
+    return ((DynamicPwm *)pin)->setPeriodUs(period);
+}
+
+/**
+  * Configures the PWM period of the analog output to the given value.
+  *
+  * @param period The new period for the analog output in milliseconds.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
+  *         given pin is not configured as an analog output.
+  */
+int MicroBitPin::setAnalogPeriod(int period)
+{
+    return setAnalogPeriodUs(period*1000);
+}
+
+/**
+  * Obtains the PWM period of the analog output in microseconds.
+  *
+  * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
+  *         given pin is not configured as an analog output.
+  */
+int MicroBitPin::getAnalogPeriodUs()
+{
+    if (!(status & IO_STATUS_ANALOG_OUT))
+        return MICROBIT_NOT_SUPPORTED;
+
+    return ((DynamicPwm *)pin)->getPeriodUs();
+}
+
+/**
+  * Obtains the PWM period of the analog output in milliseconds.
+  *
+  * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
+  *         given pin is not configured as an analog output.
+  */
+int MicroBitPin::getAnalogPeriod()
+{
+    return getAnalogPeriodUs()/1000;
+}
+
+/**
+  * Configures the pull of this pin.
+  *
+  * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
+  *
+  * @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other
+  *         than a digital input, otherwise MICROBIT_OK.
+  */
+int MicroBitPin::setPull(PinMode pull)
+{
+    pullMode = pull;
+
+    if ((status & IO_STATUS_DIGITAL_IN))
+    {
+        ((DigitalIn *)pin)->mode(pull);
+        return MICROBIT_OK;
+    }
+
+    if((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
+    {
+        ((TimedInterruptIn *)pin)->mode(pull);
+        return MICROBIT_OK;
+    }
+
+    return MICROBIT_NOT_SUPPORTED;
+}
+
+/**
+  * This member function manages the calculation of the timestamp of a pulse detected
+  * on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes.
+  *
+  * @param eventValue the event value to distribute onto the message bus.
+  */
+void MicroBitPin::pulseWidthEvent(int eventValue)
+{
+    MicroBitEvent evt(id, eventValue, CREATE_ONLY);
+    uint64_t now = evt.timestamp;
+    uint64_t previous = ((TimedInterruptIn *)pin)->getTimestamp();
+
+    if (previous != 0)
+    {
+        evt.timestamp -= previous;
+        evt.fire();
+    }
+
+    ((TimedInterruptIn *)pin)->setTimestamp(now);
+}
+
+/**
+  * Interrupt handler for when an rise interrupt is triggered.
+  */
+void MicroBitPin::onRise()
+{
+    if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
+        pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_LO);
+
+    if(status & IO_STATUS_EVENT_ON_EDGE)
+        MicroBitEvent(id, MICROBIT_PIN_EVT_RISE);
+}
+
+/**
+  * Interrupt handler for when an fall interrupt is triggered.
+  */
+void MicroBitPin::onFall()
+{
+    if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
+        pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_HI);
+
+    if(status & IO_STATUS_EVENT_ON_EDGE)
+        MicroBitEvent(id, MICROBIT_PIN_EVT_FALL);
+}
+
+/**
+  * This member function will construct an TimedInterruptIn instance, and configure
+  * interrupts for rise and fall.
+  *
+  * @param eventType the specific mode used in interrupt context to determine how an
+  *                  edge/rise is processed.
+  *
+  * @return MICROBIT_OK on success
+  */
+int MicroBitPin::enableRiseFallEvents(int eventType)
+{
+    // if we are in neither of the two modes, configure pin as a TimedInterruptIn.
+    if (!(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
+    {
+        disconnect();
+        pin = new TimedInterruptIn(name);
+
+        ((TimedInterruptIn *)pin)->mode((PinMode)pullMode);
+        ((TimedInterruptIn *)pin)->rise(this, &MicroBitPin::onRise);
+        ((TimedInterruptIn *)pin)->fall(this, &MicroBitPin::onFall);
+    }
+
+    status &= ~(IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE);
+
+    // set our status bits accordingly.
+    if(eventType == MICROBIT_PIN_EVENT_ON_EDGE)
+        status |= IO_STATUS_EVENT_ON_EDGE;
+    else if(eventType == MICROBIT_PIN_EVENT_ON_PULSE)
+        status |= IO_STATUS_EVENT_PULSE_ON_EDGE;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * If this pin is in a mode where the pin is generating events, it will destruct
+  * the current instance attached to this MicroBitPin instance.
+  *
+  * @return MICROBIT_OK on success.
+  */
+int MicroBitPin::disableEvents()
+{
+    if (status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE | IO_STATUS_TOUCH_IN))
+        disconnect();
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures the events generated by this MicroBitPin instance.
+  *
+  * MICROBIT_PIN_EVENT_ON_EDGE - Configures this pin to a digital input, and generates events whenever a rise/fall is detected on this pin. (MICROBIT_PIN_EVT_RISE, MICROBIT_PIN_EVT_FALL)
+  * MICROBIT_PIN_EVENT_ON_PULSE - Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either HI or LO. (MICROBIT_PIN_EVT_PULSE_HI, MICROBIT_PIN_EVT_PULSE_LO)
+  * MICROBIT_PIN_EVENT_ON_TOUCH - Configures this pin as a makey makey style touch sensor, in the form of a MicroBitButton. Normal button events will be generated using the ID of this pin.
+  * MICROBIT_PIN_EVENT_NONE - Disables events for this pin.
+  *
+  * @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE
+  *
+  * @code
+  * MicroBitMessageBus bus;
+  *
+  * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
+  * P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE);
+  *
+  * void onPulse(MicroBitEvent evt)
+  * {
+  *     int duration = evt.timestamp;
+  * }
+  *
+  * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE)
+  * @endcode
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match
+  *
+  * @note In the MICROBIT_PIN_EVENT_ON_PULSE mode, the smallest pulse that was reliably detected was 85us, around 5khz. If more precision is required,
+  *       please use the InterruptIn class supplied by ARM mbed.
+  */
+int MicroBitPin::eventOn(int eventType)
+{
+    switch(eventType)
+    {
+        case MICROBIT_PIN_EVENT_ON_EDGE:
+        case MICROBIT_PIN_EVENT_ON_PULSE:
+            enableRiseFallEvents(eventType);
+            break;
+
+        case MICROBIT_PIN_EVENT_ON_TOUCH:
+            isTouched();
+            break;
+
+        case MICROBIT_PIN_EVENT_NONE:
+            disableEvents();
+            break;
+
+        default:
+            return MICROBIT_INVALID_PARAMETER;
+    }
+
+    return MICROBIT_OK;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitRadio.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,529 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitRadio.h"
+#include "MicroBitComponent.h"
+#include "EventModel.h"
+#include "MicroBitDevice.h"
+#include "ErrorNo.h"
+#include "MicroBitFiber.h"
+#include "MicroBitBLEManager.h"
+
+/**
+  * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+  *
+  * The nrf51822 RADIO module supports a number of proprietary modes of operation oher than the typical BLE usage.
+  * This class uses one of these modes to enable simple, point to multipoint communication directly between micro:bits.
+  *
+  * TODO: The protocols implemented here do not currently perform any significant form of energy management,
+  * which means that they will consume far more energy than their BLE equivalent. Later versions of the protocol
+  * should look to address this through energy efficient broadcast techbiques / sleep scheduling. In particular, the GLOSSY
+  * approach to efficient rebroadcast and network synchronisation would likely provide an effective future step.
+  *
+  * TODO: Meshing should also be considered - again a GLOSSY approach may be effective here, and highly complementary to
+  * the master/slave arachitecture of BLE.
+  *
+  * TODO: This implementation may only operated whilst the BLE stack is disabled. The nrf51822 provides a timeslot API to allow
+  * BLE to cohabit with other protocols. Future work to allow this colocation would be benefical, and would also allow for the
+  * creation of wireless BLE bridges.
+  *
+  * NOTE: This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
+  * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+  * For serious applications, BLE should be considered a substantially more secure alternative.
+  */
+
+MicroBitRadio* MicroBitRadio::instance = NULL;
+
+extern "C" void RADIO_IRQHandler(void)
+{
+    if(NRF_RADIO->EVENTS_READY)
+    {
+        NRF_RADIO->EVENTS_READY = 0;
+
+        // Start listening and wait for the END event
+        NRF_RADIO->TASKS_START = 1;
+    }
+
+    if(NRF_RADIO->EVENTS_END)
+    {
+        NRF_RADIO->EVENTS_END = 0;
+        if(NRF_RADIO->CRCSTATUS == 1)
+        {
+            uint8_t sample = NRF_RADIO->RSSISAMPLE;
+
+            // Associate this packet's rssi value with the data just
+            // transferred by DMA receive
+            MicroBitRadio::instance->setRSSI(sample);
+
+            // Now move on to the next buffer, if possible.
+            // The queued packet will get the rssi value set above.
+            MicroBitRadio::instance->queueRxBuf();
+
+            // Set the new buffer for DMA
+            NRF_RADIO->PACKETPTR = (uint32_t) MicroBitRadio::instance->getRxBuf();
+        }
+        else
+        {
+            MicroBitRadio::instance->setRSSI(0);
+        }
+
+        // Start listening and wait for the END event
+        NRF_RADIO->TASKS_START = 1;
+    }
+}
+
+/**
+  * Constructor.
+  *
+  * Initialise the MicroBitRadio.
+  *
+  * @note This class is demand activated, as a result most resources are only
+  *       committed if send/recv or event registrations calls are made.
+  */
+MicroBitRadio::MicroBitRadio(uint16_t id) : datagram(*this), event (*this)
+{
+    this->id = id;
+    this->status = 0;
+	this->group = MICROBIT_RADIO_DEFAULT_GROUP;
+	this->queueDepth = 0;
+    this->rssi = 0;
+    this->rxQueue = NULL;
+    this->rxBuf = NULL;
+
+    instance = this;
+}
+
+/**
+  * Change the output power level of the transmitter to the given value.
+  *
+  * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range.
+  */
+int MicroBitRadio::setTransmitPower(int power)
+{
+    if (power < 0 || power >= MICROBIT_BLE_POWER_LEVELS)
+        return MICROBIT_INVALID_PARAMETER;
+
+    NRF_RADIO->TXPOWER = (uint32_t)MICROBIT_BLE_POWER_LEVEL[power];
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Change the transmission and reception band of the radio to the given channel
+  *
+  * @param band a frequency band in the range 0 - 100. Each step is 1MHz wide, based at 2400MHz.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the value is out of range,
+  *         or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::setFrequencyBand(int band)
+{
+    if (ble_running())
+        return MICROBIT_NOT_SUPPORTED;
+
+    if (band < 0 || band > 100)
+        return MICROBIT_INVALID_PARAMETER;
+
+    NRF_RADIO->FREQUENCY = (uint32_t)band;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Retrieve a pointer to the currently allocated receive buffer. This is the area of memory
+  * actively being used by the radio hardware to store incoming data.
+  *
+  * @return a pointer to the current receive buffer.
+  */
+FrameBuffer* MicroBitRadio::getRxBuf()
+{
+    return rxBuf;
+}
+
+/**
+  * Attempt to queue a buffer received by the radio hardware, if sufficient space is available.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if a replacement receiver buffer
+  *         could not be allocated (either by policy or memory exhaustion).
+  */
+int MicroBitRadio::queueRxBuf()
+{
+    if (rxBuf == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (queueDepth >= MICROBIT_RADIO_MAXIMUM_RX_BUFFERS)
+        return MICROBIT_NO_RESOURCES;
+
+    // Store the received RSSI value in the frame
+    rxBuf->rssi = getRSSI();
+
+    // Ensure that a replacement buffer is available before queuing.
+    FrameBuffer *newRxBuf = new FrameBuffer();
+
+    if (newRxBuf == NULL)
+        return MICROBIT_NO_RESOURCES;
+
+    // We add to the tail of the queue to preserve causal ordering.
+    rxBuf->next = NULL;
+
+    if (rxQueue == NULL)
+    {
+        rxQueue = rxBuf;
+    }
+    else
+    {
+        FrameBuffer *p = rxQueue;
+        while (p->next != NULL)
+            p = p->next;
+
+        p->next = rxBuf;
+    }
+
+    // Increase our received packet count
+    queueDepth++;
+
+    // Allocate a new buffer for the receiver hardware to use. the old on will be passed on to higher layer protocols/apps.
+    rxBuf = newRxBuf;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Sets the RSSI for the most recent packet.
+  *
+  * @param rssi the new rssi value.
+  *
+  * @note should only be called from RADIO_IRQHandler...
+  */
+int MicroBitRadio::setRSSI(uint8_t rssi)
+{
+    if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
+        return MICROBIT_NOT_SUPPORTED;
+
+    this->rssi = rssi;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Retrieves the current RSSI for the most recent packet.
+  *
+  * @return the most recent RSSI value or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::getRSSI()
+{
+    if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
+        return MICROBIT_NOT_SUPPORTED;
+
+    return this->rssi;
+}
+
+/**
+  * Initialises the radio for use as a multipoint sender/receiver
+  *
+  * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::enable()
+{
+    // If the device is already initialised, then there's nothing to do.
+    if (status & MICROBIT_RADIO_STATUS_INITIALISED)
+        return MICROBIT_OK;
+
+    // Only attempt to enable this radio mode if BLE is disabled.
+    if (ble_running())
+        return MICROBIT_NOT_SUPPORTED;
+
+    // If this is the first time we've been enable, allocate out receive buffers.
+    if (rxBuf == NULL)
+        rxBuf = new FrameBuffer();
+
+    if (rxBuf == NULL)
+        return MICROBIT_NO_RESOURCES;
+
+    // Enable the High Frequency clock on the processor. This is a pre-requisite for
+    // the RADIO module. Without this clock, no communication is possible.
+    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
+    NRF_CLOCK->TASKS_HFCLKSTART = 1;
+    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
+
+    // Bring up the nrf51822 RADIO module in Nordic's proprietary 1MBps packet radio mode.
+    setTransmitPower(MICROBIT_RADIO_DEFAULT_TX_POWER);
+    setFrequencyBand(MICROBIT_RADIO_DEFAULT_FREQUENCY);
+
+    // Configure for 1Mbps throughput.
+    // This may sound excessive, but running a high data rates reduces the chances of collisions...
+    NRF_RADIO->MODE = RADIO_MODE_MODE_Nrf_1Mbit;
+
+    // Configure the addresses we use for this protocol. We run ANONYMOUSLY at the core.
+    // A 40 bit addresses is used. The first 32 bits match the ASCII character code for "uBit".
+    // Statistically, this provides assurance to avoid other similar 2.4GHz protocols that may be in the vicinity.
+    // We also map the assigned 8-bit GROUP id into the PREFIX field. This allows the RADIO hardware to perform
+    // address matching for us, and only generate an interrupt when a packet matching our group is received.
+    NRF_RADIO->BASE0 = MICROBIT_RADIO_BASE_ADDRESS;
+
+    // Join the default group. This will configure the remaining byte in the RADIO hardware module.
+    setGroup(this->group);
+
+    // The RADIO hardware module supports the use of multiple addresses, but as we're running anonymously, we only need one.
+    // Configure the RADIO module to use the default address (address 0) for both send and receive operations.
+    NRF_RADIO->TXADDRESS = 0;
+    NRF_RADIO->RXADDRESSES = 1;
+
+    // Packet layout configuration. The nrf51822 has a highly capable and flexible RADIO module that, in addition to transmission
+    // and reception of data, also contains a LENGTH field, two optional additional 1 byte fields (S0 and S1) and a CRC calculation.
+    // Configure the packet format for a simple 8 bit length field and no additional fields.
+    NRF_RADIO->PCNF0 = 0x00000008;
+    NRF_RADIO->PCNF1 = 0x02040000 | MICROBIT_RADIO_MAX_PACKET_SIZE;
+
+    // Most communication channels contain some form of checksum - a mathematical calculation taken based on all the data
+    // in a packet, that is also sent as part of the packet. When received, this calculation can be repeated, and the results
+    // from the sender and receiver compared. If they are different, then some corruption of the data ahas happened in transit,
+    // and we know we can't trust it. The nrf51822 RADIO uses a CRC for this - a very effective checksum calculation.
+    //
+    // Enable automatic 16bit CRC generation and checking, and configure how the CRC is calculated.
+    NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Two;
+    NRF_RADIO->CRCINIT = 0xFFFF;
+    NRF_RADIO->CRCPOLY = 0x11021;
+
+    // Set the start random value of the data whitening algorithm. This can be any non zero number.
+    NRF_RADIO->DATAWHITEIV = 0x18;
+
+    // Set up the RADIO module to read and write from our internal buffer.
+    NRF_RADIO->PACKETPTR = (uint32_t)rxBuf;
+
+    // Configure the hardware to issue an interrupt whenever a task is complete (e.g. send/receive).
+    NRF_RADIO->INTENSET = 0x00000008;
+    NVIC_ClearPendingIRQ(RADIO_IRQn);
+    NVIC_EnableIRQ(RADIO_IRQn);
+
+    NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_RSSISTART_Msk;
+
+    // Start listening for the next packet
+    NRF_RADIO->EVENTS_READY = 0;
+    NRF_RADIO->TASKS_RXEN = 1;
+    while(NRF_RADIO->EVENTS_READY == 0);
+
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->TASKS_START = 1;
+
+    // register ourselves for a callback event, in order to empty the receive queue.
+    fiber_add_idle_component(this);
+
+    // Done. Record that our RADIO is configured.
+    status |= MICROBIT_RADIO_STATUS_INITIALISED;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Disables the radio for use as a multipoint sender/receiver.
+  *
+  * @return MICROBIT_OK on success, MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::disable()
+{
+    // Only attempt to enable.disable the radio if the protocol is alreayd running.
+    if (ble_running())
+        return MICROBIT_NOT_SUPPORTED;
+
+    if (!(status & MICROBIT_RADIO_STATUS_INITIALISED))
+        return MICROBIT_OK;
+
+    // Disable interrupts and STOP any ongoing packet reception.
+    NVIC_DisableIRQ(RADIO_IRQn);
+
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->TASKS_DISABLE = 1;
+    while(NRF_RADIO->EVENTS_DISABLED == 0);
+
+    // deregister ourselves from the callback event used to empty the receive queue.
+    fiber_remove_idle_component(this);
+
+    // record that the radio is now disabled
+    status &= ~MICROBIT_RADIO_STATUS_INITIALISED;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Sets the radio to listen to packets sent with the given group id.
+  *
+  * @param group The group to join. A micro:bit can only listen to one group ID at any time.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::setGroup(uint8_t group)
+{
+    if (ble_running())
+        return MICROBIT_NOT_SUPPORTED;
+
+    // Record our group id locally
+    this->group = group;
+
+    // Also append it to the address of this device, to allow the RADIO module to filter for us.
+    NRF_RADIO->PREFIX0 = (uint32_t)group;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * A background, low priority callback that is triggered whenever the processor is idle.
+  * Here, we empty our queue of received packets, and pass them onto higher level protocol handlers.
+  */
+void MicroBitRadio::idleTick()
+{
+    // Walk the list of packets and process each one.
+    while(rxQueue)
+    {
+        FrameBuffer *p = rxQueue;
+
+        switch (p->protocol)
+        {
+            case MICROBIT_RADIO_PROTOCOL_DATAGRAM:
+                datagram.packetReceived();
+                break;
+
+            case MICROBIT_RADIO_PROTOCOL_EVENTBUS:
+                event.packetReceived();
+                break;
+
+            default:
+                MicroBitEvent(MICROBIT_ID_RADIO_DATA_READY, p->protocol);
+        }
+
+        // If the packet was processed, it will have been recv'd, and taken from the queue.
+        // If this was a packet for an unknown protocol, it will still be there, so simply free it.
+        if (p == rxQueue)
+        {
+            recv();
+            delete p;
+        }
+    }
+}
+
+/**
+  * Determines the number of packets ready to be processed.
+  *
+  * @return The number of packets in the receive buffer.
+  */
+int MicroBitRadio::dataReady()
+{
+    return queueDepth;
+}
+
+/**
+  * Retrieves the next packet from the receive buffer.
+  * If a data packet is available, then it will be returned immediately to
+  * the caller. This call will also dequeue the buffer.
+  *
+  * @return The buffer containing the the packet. If no data is available, NULL is returned.
+  *
+  * @note Once recv() has been called, it is the callers responsibility to
+  *       delete the buffer when appropriate.
+  */
+FrameBuffer* MicroBitRadio::recv()
+{
+    FrameBuffer *p = rxQueue;
+
+    if (p)
+    {
+         // Protect shared resource from ISR activity
+        NVIC_DisableIRQ(RADIO_IRQn); 
+
+        rxQueue = rxQueue->next;
+        queueDepth--;
+
+        // Allow ISR access to shared resource
+        NVIC_EnableIRQ(RADIO_IRQn);
+    }
+
+    return p;
+}
+
+/**
+  * Transmits the given buffer onto the broadcast radio.
+  * The call will wait until the transmission of the packet has completed before returning.
+  *
+  * @param data The packet contents to transmit.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the BLE stack is running.
+  */
+int MicroBitRadio::send(FrameBuffer *buffer)
+{
+    if (ble_running())
+        return MICROBIT_NOT_SUPPORTED;
+
+    if (buffer == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if (buffer->length > MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE - 1)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Firstly, disable the Radio interrupt. We want to wait until the trasmission completes.
+    NVIC_DisableIRQ(RADIO_IRQn);
+
+    // Turn off the transceiver.
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->TASKS_DISABLE = 1;
+    while(NRF_RADIO->EVENTS_DISABLED == 0);
+
+    // Configure the radio to send the buffer provided.
+    NRF_RADIO->PACKETPTR = (uint32_t) buffer;
+
+    // Turn on the transmitter, and wait for it to signal that it's ready to use.
+    NRF_RADIO->EVENTS_READY = 0;
+    NRF_RADIO->TASKS_TXEN = 1;
+    while (NRF_RADIO->EVENTS_READY == 0);
+
+    // Start transmission and wait for end of packet.
+    NRF_RADIO->TASKS_START = 1;
+    NRF_RADIO->EVENTS_END = 0;
+    while(NRF_RADIO->EVENTS_END == 0);
+
+    // Return the radio to using the default receive buffer
+    NRF_RADIO->PACKETPTR = (uint32_t) rxBuf;
+
+    // Turn off the transmitter.
+    NRF_RADIO->EVENTS_DISABLED = 0;
+    NRF_RADIO->TASKS_DISABLE = 1;
+    while(NRF_RADIO->EVENTS_DISABLED == 0);
+
+    // Start listening for the next packet
+    NRF_RADIO->EVENTS_READY = 0;
+    NRF_RADIO->TASKS_RXEN = 1;
+    while(NRF_RADIO->EVENTS_READY == 0);
+
+    NRF_RADIO->EVENTS_END = 0;
+    NRF_RADIO->TASKS_START = 1;
+
+    // Re-enable the Radio interrupt.
+    NVIC_ClearPendingIRQ(RADIO_IRQn);
+    NVIC_EnableIRQ(RADIO_IRQn);
+
+    return MICROBIT_OK;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitRadioDatagram.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,203 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitRadio.h"
+
+/**
+  * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+  *
+  * This class provides the ability to broadcast simple text or binary messages to other micro:bits in the vicinity
+  * It is envisaged that this would provide the basis for children to experiment with building their own, simple,
+  * custom protocols.
+  *
+  * @note This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
+  * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+  * For serious applications, BLE should be considered a substantially more secure alternative.
+  */
+
+/**
+* Constructor.
+*
+* Creates an instance of a MicroBitRadioDatagram which offers the ability
+* to broadcast simple text or binary messages to other micro:bits in the vicinity
+*
+* @param r The underlying radio module used to send and receive data.
+*/
+MicroBitRadioDatagram::MicroBitRadioDatagram(MicroBitRadio &r) : radio(r)
+{
+    this->rxQueue = NULL;
+}
+
+/**
+  * Retrieves packet payload data into the given buffer.
+  *
+  * If a data packet is already available, then it will be returned immediately to the caller.
+  * If no data is available then MICROBIT_INVALID_PARAMETER is returned.
+  *
+  * @param buf A pointer to a valid memory location where the received data is to be stored
+  *
+  * @param len The maximum amount of data that can safely be stored in 'buf'
+  *
+  * @return The length of the data stored, or MICROBIT_INVALID_PARAMETER if no data is available, or the memory regions provided are invalid.
+  */
+int MicroBitRadioDatagram::recv(uint8_t *buf, int len)
+{
+    if (buf == NULL || rxQueue == NULL || len < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Take the first buffer from the queue.
+    FrameBuffer *p = rxQueue;
+    rxQueue = rxQueue->next;
+
+    int l = min(len, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1));
+
+    // Fill in the buffer provided, if possible.
+    memcpy(buf, p->payload, l);
+
+    delete p;
+    return l;
+}
+
+/**
+  * Retreives packet payload data into the given buffer.
+  *
+  * If a data packet is already available, then it will be returned immediately to the caller
+  * in the form of a PacketBuffer.
+  *
+  * @return the data received, or an empty PacketBuffer if no data is available.
+  */
+PacketBuffer MicroBitRadioDatagram::recv()
+{
+    if (rxQueue == NULL)
+        return PacketBuffer::EmptyPacket;
+
+    FrameBuffer *p = rxQueue;
+    rxQueue = rxQueue->next;
+
+    PacketBuffer packet(p->payload, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1), p->rssi);
+
+    delete p;
+    return packet;
+}
+
+/**
+  * Transmits the given buffer onto the broadcast radio.
+  *
+  * This is a synchronous call that will wait until the transmission of the packet
+  * has completed before returning.
+  *
+  * @param buffer The packet contents to transmit.
+  *
+  * @param len The number of bytes to transmit.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+  *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+  */
+int MicroBitRadioDatagram::send(uint8_t *buffer, int len)
+{
+    if (buffer == NULL || len < 0 || len > MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE - 1)
+        return MICROBIT_INVALID_PARAMETER;
+
+    FrameBuffer buf;
+
+    buf.length = len + MICROBIT_RADIO_HEADER_SIZE - 1;
+    buf.version = 1;
+    buf.group = 0;
+    buf.protocol = MICROBIT_RADIO_PROTOCOL_DATAGRAM;
+    memcpy(buf.payload, buffer, len);
+
+    return radio.send(&buf);
+}
+
+/**
+  * Transmits the given string onto the broadcast radio.
+  *
+  * This is a synchronous call that will wait until the transmission of the packet
+  * has completed before returning.
+  *
+  * @param data The packet contents to transmit.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+  *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+  */
+int MicroBitRadioDatagram::send(PacketBuffer data)
+{
+    return send((uint8_t *)data.getBytes(), data.length());
+}
+
+/**
+  * Transmits the given string onto the broadcast radio.
+  *
+  * This is a synchronous call that will wait until the transmission of the packet
+  * has completed before returning.
+  *
+  * @param data The packet contents to transmit.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
+  *         or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
+  */
+int MicroBitRadioDatagram::send(ManagedString data)
+{
+    return send((uint8_t *)data.toCharArray(), data.length());
+}
+
+/**
+  * Protocol handler callback. This is called when the radio receives a packet marked as a datagram.
+  *
+  * This function process this packet, and queues it for user reception.
+  */
+void MicroBitRadioDatagram::packetReceived()
+{
+    FrameBuffer *packet = radio.recv();
+    int queueDepth = 0;
+
+    // We add to the tail of the queue to preserve causal ordering.
+    packet->next = NULL;
+
+    if (rxQueue == NULL)
+    {
+        rxQueue = packet;
+    }
+    else
+    {
+        FrameBuffer *p = rxQueue;
+        while (p->next != NULL)
+        {
+            p = p->next;
+            queueDepth++;
+        }
+
+        if (queueDepth >= MICROBIT_RADIO_MAXIMUM_RX_BUFFERS)
+        {
+            delete packet;
+            return;
+        }
+
+        p->next = packet;
+    }
+
+    MicroBitEvent(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitRadioEvent.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,175 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitRadio.h"
+
+/**
+ * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
+ *
+ * This class provides the ability to extend the micro:bit's default EventModel to other micro:bits in the vicinity,
+ * in a very similar way to the MicroBitEventService for BLE interfaces.
+ *
+ * It is envisaged that this would provide the basis for children to experiment with building their own, simple,
+ * custom asynchronous events and actions.
+ *
+ * @note This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
+ * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
+ * For serious applications, BLE should be considered a substantially more secure alternative.
+ */
+
+/**
+  * Constructor.
+  *
+  * Creates an instance of MicroBitRadioEvent which offers the ability to extend
+  * the micro:bit's default EventModel to other micro:bits in the vicinity.
+  *
+  * @param r The underlying radio module used to send and receive data.
+  */
+MicroBitRadioEvent::MicroBitRadioEvent(MicroBitRadio &r) : radio(r)
+{
+    this->suppressForwarding = false;
+}
+
+/**
+  * Associates the given event with the radio channel.
+  *
+  * Once registered, all events matching the given registration sent to this micro:bit's
+  * default EventModel will be automatically retransmitted on the radio.
+  *
+  * @param id The id of the event to register.
+  *
+  * @param value the value of the event to register.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if no default EventModel is available.
+  *
+  * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
+  *       id and value fields.
+  */
+int MicroBitRadioEvent::listen(uint16_t id, uint16_t value)
+{
+    if (EventModel::defaultEventBus)
+        return listen(id, value, *EventModel::defaultEventBus);
+
+    return MICROBIT_NO_RESOURCES;
+}
+
+/**
+  * Associates the given event with the radio channel.
+  *
+  * Once registered, all events matching the given registration sent to the given
+  * EventModel will be automatically retransmitted on the radio.
+  *
+  * @param id The id of the events to register.
+  *
+  * @param value the value of the event to register.
+  *
+  * @param eventBus The EventModel to listen for events on.
+  *
+  * @return MICROBIT_OK on success.
+  *
+  * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
+  *       id and value fields.
+  */
+int MicroBitRadioEvent::listen(uint16_t id, uint16_t value, EventModel &eventBus)
+{
+    return eventBus.listen(id, value, this, &MicroBitRadioEvent::eventReceived, MESSAGE_BUS_LISTENER_IMMEDIATE);
+}
+
+/**
+  * Disassociates the given event with the radio channel.
+  *
+  * @param id The id of the events to deregister.
+  *
+  * @param value The value of the event to deregister.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the default message bus does not exist.
+  *
+  * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id.
+  */
+int MicroBitRadioEvent::ignore(uint16_t id, uint16_t value)
+{
+    if (EventModel::defaultEventBus)
+        return ignore(id, value, *EventModel::defaultEventBus);
+
+    return MICROBIT_INVALID_PARAMETER;
+}
+
+/**
+  * Disassociates the given events with the radio channel.
+  *
+  * @param id The id of the events to deregister.
+  *
+  * @param value The value of the event to deregister.
+  *
+  * @param eventBus The EventModel to deregister on.
+  *
+  * @return MICROBIT_OK on success.
+  *
+  * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id.
+  */
+int MicroBitRadioEvent::ignore(uint16_t id, uint16_t value, EventModel &eventBus)
+{
+    return eventBus.ignore(id, value, this, &MicroBitRadioEvent::eventReceived);
+}
+
+
+/**
+  * Protocol handler callback. This is called when the radio receives a packet marked as using the event protocol.
+  *
+  * This function process this packet, and fires the event contained inside onto the default EventModel.
+  */
+void MicroBitRadioEvent::packetReceived()
+{
+    FrameBuffer *p = radio.recv();
+    MicroBitEvent *e = (MicroBitEvent *) p->payload;
+
+    suppressForwarding = true;
+    e->fire();
+    suppressForwarding = false;
+
+    delete p;
+}
+
+/**
+  * Event handler callback. This is called whenever an event is received matching one of those registered through
+  * the registerEvent() method described above. Upon receiving such an event, it is wrapped into
+  * a radio packet and transmitted to any other micro:bits in the same group.
+  */
+void MicroBitRadioEvent::eventReceived(MicroBitEvent e)
+{
+    if(suppressForwarding)
+        return;
+
+    FrameBuffer buf;
+
+    buf.length = sizeof(MicroBitEvent) + MICROBIT_RADIO_HEADER_SIZE - 1;
+    buf.version = 1;
+    buf.group = 0;
+    buf.protocol = MICROBIT_RADIO_PROTOCOL_EVENTBUS;
+    memcpy(buf.payload, (const uint8_t *)&e, sizeof(MicroBitEvent));
+
+    radio.send(&buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitSerial.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,1127 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "mbed.h"
+#include "MicroBitSerial.h"
+#include "ErrorNo.h"
+#include "MicroBitComponent.h"
+#include "MicroBitFiber.h"
+#include "NotifyEvents.h"
+
+uint8_t MicroBitSerial::status = 0;
+
+int MicroBitSerial::baudrate = 0;
+
+/**
+  * Constructor.
+  * Create an instance of MicroBitSerial
+  *
+  * @param tx the Pin to be used for transmission
+  *
+  * @param rx the Pin to be used for receiving data
+  *
+  * @param rxBufferSize the size of the buffer to be used for receiving bytes
+  *
+  * @param txBufferSize the size of the buffer to be used for transmitting bytes
+  *
+  * @code
+  * MicroBitSerial serial(USBTX, USBRX);
+  * @endcode
+  * @note the default baud rate is 115200. More API details can be found:
+  *       -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/SerialBase.h
+  *       -https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/api/RawSerial.h
+  *
+  *       Buffers aren't allocated until the first send or receive respectively.
+  */
+MicroBitSerial::MicroBitSerial(PinName tx, PinName rx, uint8_t rxBufferSize, uint8_t txBufferSize) : RawSerial(tx,rx), delimeters()
+{
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->rxBuffSize = rxBufferSize + 1;
+    this->txBuffSize = txBufferSize + 1;
+
+    this->rxBuff = NULL;
+    this->txBuff = NULL;
+
+    this->rxBuffHead = 0;
+    this->rxBuffTail = 0;
+
+    this->txBuffHead = 0;
+    this->txBuffTail = 0;
+
+    this->rxBuffHeadMatch = -1;
+
+    this->baud(MICROBIT_SERIAL_DEFAULT_BAUD_RATE);
+
+#if CONFIG_ENABLED(MICROBIT_DBG)
+    SERIAL_DEBUG = this;
+#endif
+
+}
+
+/**
+  * An internal interrupt callback for MicroBitSerial configured for when a
+  * character is received.
+  *
+  * Each time a character is received fill our circular buffer!
+  */
+void MicroBitSerial::dataReceived()
+{
+    if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
+        return;
+
+    //get the received character
+    char c = getc();
+
+    int delimeterOffset = 0;
+    int delimLength = this->delimeters.length();
+
+    //iterate through our delimeters (if any) to see if there is a match
+    while(delimeterOffset < delimLength)
+    {
+        //fire an event if there is to block any waiting fibers
+        if(this->delimeters.charAt(delimeterOffset) == c)
+            MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH);
+
+        delimeterOffset++;
+    }
+
+    uint16_t newHead = (rxBuffHead + 1) % rxBuffSize;
+
+    //look ahead to our newHead value to see if we are about to collide with the tail
+    if(newHead != rxBuffTail)
+    {
+        //if we are not, store the character, and update our actual head.
+        this->rxBuff[rxBuffHead] = c;
+        rxBuffHead = newHead;
+
+        //if we have any fibers waiting for a specific number of characters, unblock them
+        if(rxBuffHeadMatch >= 0)
+            if(rxBuffHead == rxBuffHeadMatch)
+            {
+                rxBuffHeadMatch = -1;
+                MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_HEAD_MATCH);
+            }
+    }
+    else
+        //otherwise, our buffer is full, send an event to the user...
+        MicroBitEvent(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_RX_FULL);
+}
+
+/**
+  * An internal interrupt callback for MicroBitSerial.
+  *
+  * Each time the Serial module's buffer is empty, write a character if we have
+  * characters to write.
+  */
+void MicroBitSerial::dataWritten()
+{
+    if(txBuffTail == txBuffHead || !(status & MICROBIT_SERIAL_TX_BUFF_INIT))
+        return;
+
+    //send our current char
+    putc(txBuff[txBuffTail]);
+
+    uint16_t nextTail = (txBuffTail + 1) % txBuffSize;
+
+    //unblock any waiting fibers that are waiting for transmission to finish.
+    if(nextTail == txBuffHead)
+    {
+        MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_SERIAL_EVT_TX_EMPTY);
+        detach(Serial::TxIrq);
+    }
+
+    //update our tail!
+    txBuffTail = nextTail;
+}
+
+/**
+  * An internal method to configure an interrupt on tx buffer and also
+  * a best effort copy operation to move bytes from a user buffer to our txBuff
+  *
+  * @param string a pointer to the first character of the users' buffer.
+  *
+  * @param len the length of the string, and ultimately the maximum number of bytes
+  *        that will be copied dependent on the state of txBuff
+  *
+  * @param mode determines whether to configure the current fiber context or not. If
+  *             The mode is SYNC_SPINWAIT, the context will not be configured, otherwise
+  *             no context will be configured.
+  *
+  * @return the number of bytes copied into the buffer.
+  */
+int MicroBitSerial::setTxInterrupt(uint8_t *string, int len, MicroBitSerialMode mode)
+{
+    int copiedBytes = 0;
+
+    for(copiedBytes = 0; copiedBytes < len; copiedBytes++)
+    {
+        uint16_t nextHead = (txBuffHead + 1) % txBuffSize;
+        if(nextHead != txBuffTail)
+        {
+            this->txBuff[txBuffHead] = string[copiedBytes];
+            txBuffHead = nextHead;
+        }
+        else
+            break;
+    }
+
+    if(mode != SYNC_SPINWAIT)
+        fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_SERIAL_EVT_TX_EMPTY);
+
+    //set the TX interrupt
+    attach(this, &MicroBitSerial::dataWritten, Serial::TxIrq);
+
+    return copiedBytes;
+}
+
+/**
+  * Locks the mutex so that others can't use this serial instance for reception
+  */
+void MicroBitSerial::lockRx()
+{
+    status |= MICROBIT_SERIAL_RX_IN_USE;
+}
+
+/**
+  * Locks the mutex so that others can't use this serial instance for transmission
+  */
+void MicroBitSerial::lockTx()
+{
+    status |= MICROBIT_SERIAL_TX_IN_USE;
+}
+
+/**
+  * Unlocks the mutex so that others can use this serial instance for reception
+  */
+void MicroBitSerial::unlockRx()
+{
+    status &= ~MICROBIT_SERIAL_RX_IN_USE;
+}
+
+/**
+  * Unlocks the mutex so that others can use this serial instance for transmission
+  */
+void MicroBitSerial::unlockTx()
+{
+    status &= ~MICROBIT_SERIAL_TX_IN_USE;
+}
+
+/**
+  * We do not want to always have our buffers initialised, especially if users to not
+  * use them. We only bring them up on demand.
+  */
+int MicroBitSerial::initialiseRx()
+{
+    if((status & MICROBIT_SERIAL_RX_BUFF_INIT))
+    {
+        //ensure that we receive no interrupts after freeing our buffer
+        detach(Serial::RxIrq);
+        free(this->rxBuff);
+    }
+
+    status &= ~MICROBIT_SERIAL_RX_BUFF_INIT;
+
+    if((this->rxBuff = (uint8_t *)malloc(rxBuffSize)) == NULL)
+        return MICROBIT_NO_RESOURCES;
+
+    this->rxBuffHead = 0;
+    this->rxBuffTail = 0;
+
+    //set the receive interrupt
+    status |= MICROBIT_SERIAL_RX_BUFF_INIT;
+    attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * We do not want to always have our buffers initialised, especially if users to not
+  * use them. We only bring them up on demand.
+  */
+int MicroBitSerial::initialiseTx()
+{
+    if((status & MICROBIT_SERIAL_TX_BUFF_INIT))
+    {
+        //ensure that we receive no interrupts after freeing our buffer
+        detach(Serial::TxIrq);
+        free(this->txBuff);
+    }
+
+    status &= ~MICROBIT_SERIAL_TX_BUFF_INIT;
+
+    if((this->txBuff = (uint8_t *)malloc(txBuffSize)) == NULL)
+        return MICROBIT_NO_RESOURCES;
+
+    this->txBuffHead = 0;
+    this->txBuffTail = 0;
+
+    status |= MICROBIT_SERIAL_TX_BUFF_INIT;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * An internal method that either spin waits if mode is set to SYNC_SPINWAIT
+  * or puts the fiber to sleep if the mode is set to SYNC_SLEEP
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP
+  */
+void MicroBitSerial::send(MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        while(txBufferedSize() > 0);
+
+    if(mode == SYNC_SLEEP)
+        fiber_sleep(0);
+}
+
+/**
+  * Reads a single character from the rxBuff
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - A character is read from the rxBuff if available, if there
+  *                    are no characters to be read, a value of zero is returned immediately.
+  *
+  *            SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
+  *                            are no characters to be read, this method will spin
+  *                            (lock up the processor) until a character is available.
+  *
+  *            SYNC_SLEEP - A character is read from the rxBuff if available, if there
+  *                         are no characters to be read, the calling fiber sleeps
+  *                         until there is a character available.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return a character from the circular buffer, or MICROBIT_NO_DATA is there
+  *         are no characters in the buffer.
+  */
+int MicroBitSerial::getChar(MicroBitSerialMode mode)
+{
+    if(mode == ASYNC)
+    {
+        if(!isReadable())
+            return MICROBIT_NO_DATA;
+    }
+
+    if(mode == SYNC_SPINWAIT)
+        while(!isReadable());
+
+    if(mode == SYNC_SLEEP)
+    {
+        if(!isReadable())
+            eventAfter(1, mode);
+    }
+
+    char c = rxBuff[rxBuffTail];
+
+    rxBuffTail = (rxBuffTail + 1) % rxBuffSize;
+
+    return c;
+}
+
+/**
+  * An internal method that copies values from a circular buffer to a linear buffer.
+  *
+  * @param circularBuff a pointer to the source circular buffer
+  *
+  * @param circularBuffSize the size of the circular buffer
+  *
+  * @param linearBuff a pointer to the destination linear buffer
+  *
+  * @param tailPosition the tail position in the circular buffer you want to copy from
+  *
+  * @param headPosition the head position in the circular buffer you want to copy to
+  *
+  * @note this method assumes that the linear buffer has the appropriate amount of
+  *       memory to contain the copy operation
+  */
+void MicroBitSerial::circularCopy(uint8_t *circularBuff, uint8_t circularBuffSize, uint8_t *linearBuff, uint16_t tailPosition, uint16_t headPosition)
+{
+    int toBuffIndex = 0;
+
+    while(tailPosition != headPosition)
+    {
+        linearBuff[toBuffIndex++] = circularBuff[tailPosition];
+
+        tailPosition = (tailPosition + 1) % circularBuffSize;
+    }
+}
+
+/**
+  * Sends a single character over the serial line.
+  *
+  * @param c the character to send
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - the character is copied into the txBuff and returns immediately.
+  *
+  *            SYNC_SPINWAIT - the character is copied into the txBuff and this method
+  *                            will spin (lock up the processor) until the character has
+  *                            been sent.
+  *
+  *            SYNC_SLEEP - the character is copied into the txBuff and the fiber sleeps
+  *                         until the character has been sent. This allows other fibers
+  *                         to continue execution.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return the number of bytes written, or MICROBIT_SERIAL_IN_USE if another fiber
+  *         is using the serial instance for transmission.
+  */
+int MicroBitSerial::sendChar(char c, MicroBitSerialMode mode)
+{
+    if(txInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockTx();
+
+    //lazy initialisation of our tx buffer
+    if(!(status & MICROBIT_SERIAL_TX_BUFF_INIT))
+    {
+        int result = initialiseTx();
+
+        if(result != MICROBIT_OK)
+            return result;
+    }
+
+    uint8_t toTransmit[2] =  { c, '\0'};
+
+    int bytesWritten = setTxInterrupt(toTransmit, 1, mode);
+
+    send(mode);
+
+    unlockTx();
+
+    return bytesWritten;
+}
+
+/**
+  * Sends a ManagedString over the serial line.
+  *
+  * @param s the string to send
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - bytes are copied into the txBuff and returns immediately.
+  *
+  *            SYNC_SPINWAIT - bytes are copied into the txBuff and this method
+  *                            will spin (lock up the processor) until all bytes
+  *                            have been sent.
+  *
+  *            SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
+  *                         until all bytes have been sent. This allows other fibers
+  *                         to continue execution.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
+  *         is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
+  *         if buffer is invalid, or the given bufferLen is <= 0.
+  */
+int MicroBitSerial::send(ManagedString s, MicroBitSerialMode mode)
+{
+    return send((uint8_t *)s.toCharArray(), s.length(), mode);
+}
+
+/**
+  * Sends a buffer of known length over the serial line.
+  *
+  * @param buffer a pointer to the first character of the buffer
+  *
+  * @param len the number of bytes that are safely available to read.
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - bytes are copied into the txBuff and returns immediately.
+  *
+  *            SYNC_SPINWAIT - bytes are copied into the txBuff and this method
+  *                            will spin (lock up the processor) until all bytes
+  *                            have been sent.
+  *
+  *            SYNC_SLEEP - bytes are copied into the txBuff and the fiber sleeps
+  *                         until all bytes have been sent. This allows other fibers
+  *                         to continue execution.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return the number of bytes written, MICROBIT_SERIAL_IN_USE if another fiber
+  *         is using the serial instance for transmission, MICROBIT_INVALID_PARAMETER
+  *         if buffer is invalid, or the given bufferLen is <= 0.
+  */
+int MicroBitSerial::send(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode)
+{
+    if(txInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    if(bufferLen <= 0 || buffer == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    lockTx();
+
+    //lazy initialisation of our tx buffer
+    if(!(status & MICROBIT_SERIAL_TX_BUFF_INIT))
+    {
+        int result = initialiseTx();
+
+        if(result != MICROBIT_OK)
+            return result;
+    }
+
+    bool complete = false;
+    int bytesWritten = 0;
+
+    while(!complete)
+    {
+        bytesWritten += setTxInterrupt(buffer + bytesWritten, bufferLen - bytesWritten, mode);
+        send(mode);
+
+        if(mode == ASYNC || bytesWritten >= bufferLen)
+            complete = true;
+    }
+
+    unlockTx();
+
+    return bytesWritten;
+}
+
+/**
+  * Reads a single character from the rxBuff
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - A character is read from the rxBuff if available, if there
+  *                    are no characters to be read, a value of MICROBIT_NO_DATA is returned immediately.
+  *
+  *            SYNC_SPINWAIT - A character is read from the rxBuff if available, if there
+  *                            are no characters to be read, this method will spin
+  *                            (lock up the processor) until a character is available.
+  *
+  *            SYNC_SLEEP - A character is read from the rxBuff if available, if there
+  *                         are no characters to be read, the calling fiber sleeps
+  *                         until there is a character available.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return a character, MICROBIT_SERIAL_IN_USE if another fiber is using the serial instance for reception,
+  *         MICROBIT_NO_RESOURCES if buffer allocation did not complete successfully, or MICROBIT_NO_DATA if
+  *         the rx buffer is empty and the mode given is ASYNC.
+  */
+int MicroBitSerial::read(MicroBitSerialMode mode)
+{
+    if(rxInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockRx();
+
+    //lazy initialisation of our buffers
+    if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
+    {
+        int result = initialiseRx();
+
+        if(result != MICROBIT_OK)
+            return result;
+    }
+
+    int c = getChar(mode);
+
+    unlockRx();
+
+    return c;
+}
+
+/**
+  * Reads multiple characters from the rxBuff and returns them as a ManagedString
+  *
+  * @param size the number of characters to read.
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - If the desired number of characters are available, this will return
+  *                    a ManagedString with the expected size. Otherwise, it will read however
+  *                    many characters there are available.
+  *
+  *            SYNC_SPINWAIT - If the desired number of characters are available, this will return
+  *                            a ManagedString with the expected size. Otherwise, this method will spin
+  *                            (lock up the processor) until the desired number of characters have been read.
+  *
+  *            SYNC_SLEEP - If the desired number of characters are available, this will return
+  *                         a ManagedString with the expected size. Otherwise, the calling fiber sleeps
+  *                         until the desired number of characters have been read.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return A ManagedString, or an empty ManagedString if an error was encountered during the read.
+  */
+ManagedString MicroBitSerial::read(int size, MicroBitSerialMode mode)
+{
+    uint8_t buff[size + 1];
+
+    memclr(&buff, size + 1);
+
+    int returnedSize = read((uint8_t *)buff, size, mode);
+
+    if(returnedSize <= 0)
+        return ManagedString();
+
+    return ManagedString((char *)buff, returnedSize);
+}
+
+/**
+  * Reads multiple characters from the rxBuff and fills a user buffer.
+  *
+  * @param buffer a pointer to a user allocated buffer.
+  *
+  * @param bufferLen the amount of data that can be safely stored
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - If the desired number of characters are available, this will fill
+  *                    the given buffer. Otherwise, it will fill the buffer with however
+  *                    many characters there are available.
+  *
+  *            SYNC_SPINWAIT - If the desired number of characters are available, this will fill
+  *                            the given buffer. Otherwise, this method will spin (lock up the processor)
+  *                            and fill the buffer until the desired number of characters have been read.
+  *
+  *            SYNC_SLEEP - If the desired number of characters are available, this will fill
+  *                         the given buffer. Otherwise, the calling fiber sleeps
+  *                         until the desired number of characters have been read.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return the number of characters read, or MICROBIT_SERIAL_IN_USE if another fiber
+  *         is using the instance for receiving.
+  */
+int MicroBitSerial::read(uint8_t *buffer, int bufferLen, MicroBitSerialMode mode)
+{
+    if(rxInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockRx();
+
+    //lazy initialisation of our rx buffer
+    if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
+    {
+        int result = initialiseRx();
+
+        if(result != MICROBIT_OK)
+            return result;
+    }
+
+    int bufferIndex = 0;
+
+    int temp = 0;
+
+    if(mode == ASYNC)
+    {
+        while((temp = getChar(mode)) != MICROBIT_NO_DATA && bufferIndex < bufferLen)
+        {
+            buffer[bufferIndex] = (char)temp;
+            bufferIndex++;
+        }
+    }
+
+    if(mode == SYNC_SPINWAIT)
+    {
+        while(bufferIndex < bufferLen)
+        {
+            buffer[bufferIndex] = (char)getChar(mode);
+            bufferIndex++;
+        }
+    }
+
+    if(mode == SYNC_SLEEP)
+    {
+        if(bufferLen > rxBufferedSize())
+            eventAfter(bufferLen - rxBufferedSize(), mode);
+
+        while(bufferIndex < bufferLen)
+        {
+            buffer[bufferIndex] = (char)getChar(mode);
+            bufferIndex++;
+        }
+    }
+
+    unlockRx();
+
+    return bufferIndex;
+}
+
+
+/**
+  * Reads until one of the delimeters matches a character in the rxBuff
+  *
+  * @param delimeters a ManagedString containing a sequence of delimeter characters e.g. ManagedString("\r\n")
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - If one of the delimeters matches a character already in the rxBuff
+  *                    this method will return a ManagedString up to the delimeter.
+  *                    Otherwise, it will return an Empty ManagedString.
+  *
+  *            SYNC_SPINWAIT - If one of the delimeters matches a character already in the rxBuff
+  *                            this method will return a ManagedString up to the delimeter.
+  *                            Otherwise, this method will spin (lock up the processor) until a
+  *                            received character matches one of the delimeters.
+  *
+  *            SYNC_SLEEP - If one of the delimeters matches a character already in the rxBuff
+  *                         this method will return a ManagedString up to the delimeter.
+  *                         Otherwise, the calling fiber sleeps until a character matching one
+  *                         of the delimeters is seen.
+  *
+  *         Defaults to SYNC_SLEEP.
+  *
+  * @return A ManagedString containing the characters up to a delimeter, or an Empty ManagedString,
+  *         if another fiber is currently using this instance for reception.
+  *
+  * @note delimeters are matched on a per byte basis.
+  */
+ManagedString MicroBitSerial::readUntil(ManagedString delimeters, MicroBitSerialMode mode)
+{
+
+    if(rxInUse())
+        return ManagedString();
+
+    //lazy initialisation of our rx buffer
+    if(!(status & MICROBIT_SERIAL_RX_BUFF_INIT))
+    {
+        int result = initialiseRx();
+
+        if(result != MICROBIT_OK)
+            return result;
+    }
+
+    lockRx();
+
+    int localTail = rxBuffTail;
+    int preservedTail = rxBuffTail;
+
+    int foundIndex = -1;
+
+    //ASYNC mode just iterates through our stored characters checking for any matches.
+    while(localTail != rxBuffHead && foundIndex  == -1)
+    {
+        //we use localTail to prevent modification of the actual tail.
+        char c = rxBuff[localTail];
+
+        for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
+            if(delimeters.charAt(delimeterIterator) == c)
+                foundIndex = localTail;
+
+        localTail = (localTail + 1) % rxBuffSize;
+    }
+
+    //if our mode is SYNC_SPINWAIT and we didn't see any matching characters in our buffer
+    //spin until we find a match!
+    if(mode == SYNC_SPINWAIT)
+    {
+        while(foundIndex == -1)
+        {
+            while(localTail == rxBuffHead);
+
+            char c = rxBuff[localTail];
+
+            for(int delimeterIterator = 0; delimeterIterator < delimeters.length(); delimeterIterator++)
+                if(delimeters.charAt(delimeterIterator) == c)
+                    foundIndex = localTail;
+
+            localTail = (localTail + 1) % rxBuffSize;
+        }
+    }
+
+    //if our mode is SYNC_SLEEP, we set up an event to be fired when we see a
+    //matching character.
+    if(mode == SYNC_SLEEP && foundIndex == -1)
+    {
+        eventOn(delimeters, mode);
+
+        foundIndex = rxBuffHead - 1;
+
+        this->delimeters = ManagedString();
+    }
+
+    if(foundIndex >= 0)
+    {
+        //calculate our local buffer size
+        int localBuffSize = (preservedTail > foundIndex) ? (rxBuffSize - preservedTail) + foundIndex : foundIndex - preservedTail;
+
+        uint8_t localBuff[localBuffSize + 1];
+
+        memclr(&localBuff, localBuffSize + 1);
+
+        circularCopy(rxBuff, rxBuffSize, localBuff, preservedTail, foundIndex);
+
+        //plus one for the character we listened for...
+        rxBuffTail = (rxBuffTail + localBuffSize + 1) % rxBuffSize;
+
+        unlockRx();
+
+        return ManagedString((char *)localBuff, localBuffSize);
+    }
+
+    unlockRx();
+
+    return ManagedString();
+}
+
+/**
+  * A wrapper around the inherited method "baud" so we can trap the baud rate
+  * as it changes and restore it if redirect() is called.
+  *
+  * @param baudrate the new baudrate. See:
+  *         - https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c
+  *        for permitted baud rates.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if baud rate is less than 0, otherwise MICROBIT_OK.
+  *
+  * @note the underlying implementation chooses the first allowable rate at or above that requested.
+  */
+void MicroBitSerial::baud(int baudrate)
+{
+    if(baudrate < 0)
+        return;
+
+    this->baudrate = baudrate;
+
+    RawSerial::baud(baudrate);
+}
+
+/**
+  * A way of dynamically configuring the serial instance to use pins other than USBTX and USBRX.
+  *
+  * @param tx the new transmission pin.
+  *
+  * @param rx the new reception pin.
+  *
+  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently transmitting or receiving, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::redirect(PinName tx, PinName rx)
+{
+    if(txInUse() || rxInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockTx();
+    lockRx();
+
+    if(txBufferedSize() > 0)
+        detach(Serial::TxIrq);
+
+    detach(Serial::RxIrq);
+
+    serial_init(&_serial, tx, rx);
+
+    attach(this, &MicroBitSerial::dataReceived, Serial::RxIrq);
+
+    if(txBufferedSize() > 0)
+        attach(this, &MicroBitSerial::dataWritten, Serial::TxIrq);
+
+    this->baud(this->baudrate);
+
+    unlockRx();
+    unlockTx();
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures an event to be fired after "len" characters.
+  *
+  * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_HEAD_MATCH.
+  *
+  * @param len the number of characters to wait before triggering the event.
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will configure the event and return immediately.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+  *                         event is received.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::eventAfter(int len, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //configure our head match...
+    this->rxBuffHeadMatch = (rxBuffHead + len) % rxBuffSize;
+
+    //block!
+    if(mode == SYNC_SLEEP)
+        fiber_wait_for_event(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_HEAD_MATCH);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Configures an event to be fired on a match with one of the delimeters.
+  *
+  * Will generate an event with the ID: MICROBIT_ID_SERIAL and the value MICROBIT_SERIAL_EVT_DELIM_MATCH.
+  *
+  * @param delimeters the characters to match received characters against e.g. ManagedString("\n")
+  *
+  * @param mode the selected mode, one of: ASYNC, SYNC_SPINWAIT, SYNC_SLEEP. Each mode
+  *        gives a different behaviour:
+  *
+  *            ASYNC - Will configure the event and return immediately.
+  *
+  *            SYNC_SPINWAIT - will return MICROBIT_INVALID_PARAMETER
+  *
+  *            SYNC_SLEEP - Will configure the event and block the current fiber until the
+  *                         event is received.
+  *
+  * @return MICROBIT_INVALID_PARAMETER if the mode given is SYNC_SPINWAIT, otherwise MICROBIT_OK.
+  *
+  * @note delimeters are matched on a per byte basis.
+  */
+int MicroBitSerial::eventOn(ManagedString delimeters, MicroBitSerialMode mode)
+{
+    if(mode == SYNC_SPINWAIT)
+        return MICROBIT_INVALID_PARAMETER;
+
+    //configure our head match...
+    this->delimeters = delimeters;
+
+    //block!
+    if(mode == SYNC_SLEEP)
+        fiber_wait_for_event(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH);
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Determines whether there is any data waiting in our Rx buffer.
+  *
+  * @return 1 if we have space, 0 if we do not.
+  *
+  * @note We do not wrap the super's readable() method as we don't want to
+  *       interfere with communities that use manual calls to serial.readable().
+  */
+int MicroBitSerial::isReadable()
+{
+    return (rxBuffTail != rxBuffHead) ? 1 : 0;
+}
+
+/**
+  * Determines if we have space in our txBuff.
+  *
+  * @return 1 if we have space, 0 if we do not.
+  *
+  * @note We do not wrap the super's writeable() method as we don't want to
+  *       interfere with communities that use manual calls to serial.writeable().
+  */
+int MicroBitSerial::isWriteable()
+{
+    return (txBuffHead != (txBuffTail - 1)) ? 1 : 0;
+}
+
+/**
+  * Reconfigures the size of our rxBuff
+  *
+  * @param size the new size for our rxBuff
+  *
+  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+  *         for reception, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::setRxBufferSize(uint8_t size)
+{
+    if(rxInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockRx();
+
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->rxBuffSize = size + 1;
+
+    int result = initialiseRx();
+
+    unlockRx();
+
+    return result;
+}
+
+/**
+  * Reconfigures the size of our txBuff
+  *
+  * @param size the new size for our txBuff
+  *
+  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+  *         for transmission, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::setTxBufferSize(uint8_t size)
+{
+    if(txInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockTx();
+
+    // + 1 so there is a usable buffer size, of the size the user requested.
+    this->txBuffSize = size + 1;
+
+    int result = initialiseTx();
+
+    unlockTx();
+
+    return result;
+}
+
+/**
+  * The size of our rx buffer in bytes.
+  *
+  * @return the current size of rxBuff in bytes
+  */
+int MicroBitSerial::getRxBufferSize()
+{
+    return this->rxBuffSize;
+}
+
+/**
+  * The size of our tx buffer in bytes.
+  *
+  * @return the current size of txBuff in bytes
+  */
+int MicroBitSerial::getTxBufferSize()
+{
+    return this->txBuffSize;
+}
+
+/**
+  * Sets the tail to match the head of our circular buffer for reception,
+  * effectively clearing the reception buffer.
+  *
+  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+  *         for reception, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::clearRxBuffer()
+{
+    if(rxInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockRx();
+
+    rxBuffTail = rxBuffHead;
+
+    unlockRx();
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Sets the tail to match the head of our circular buffer for transmission,
+  * effectively clearing the transmission buffer.
+  *
+  * @return MICROBIT_SERIAL_IN_USE if another fiber is currently using this instance
+  *         for transmission, otherwise MICROBIT_OK.
+  */
+int MicroBitSerial::clearTxBuffer()
+{
+    if(txInUse())
+        return MICROBIT_SERIAL_IN_USE;
+
+    lockTx();
+
+    txBuffTail = txBuffHead;
+
+    unlockTx();
+
+    return MICROBIT_OK;
+}
+
+/**
+  * The number of bytes currently stored in our rx buffer waiting to be digested,
+  * by the user.
+  *
+  * @return The currently buffered number of bytes in our rxBuff.
+  */
+int MicroBitSerial::rxBufferedSize()
+{
+    if(rxBuffTail > rxBuffHead)
+        return (rxBuffSize - rxBuffTail) + rxBuffHead;
+
+    return rxBuffHead - rxBuffTail;
+}
+
+/**
+  * The number of bytes currently stored in our tx buffer waiting to be transmitted
+  * by the hardware.
+  *
+  * @return The currently buffered number of bytes in our txBuff.
+  */
+int MicroBitSerial::txBufferedSize()
+{
+    if(txBuffTail > txBuffHead)
+        return (txBuffSize - txBuffTail) + txBuffHead;
+
+    return txBuffHead - txBuffTail;
+}
+
+/**
+  * Determines if the serial bus is currently in use by another fiber for reception.
+  *
+  * @return The state of our mutex lock for reception.
+  *
+  * @note Only one fiber can call read at a time
+  */
+int MicroBitSerial::rxInUse()
+{
+    return (status & MICROBIT_SERIAL_RX_IN_USE);
+}
+
+/**
+  * Determines if the serial bus is currently in use by another fiber for transmission.
+  *
+  * @return The state of our mutex lock for transmition.
+  *
+  * @note Only one fiber can call send at a time
+  */
+int MicroBitSerial::txInUse()
+{
+    return (status & MICROBIT_SERIAL_TX_IN_USE);
+}
+
+/**
+  * Detaches a previously configured interrupt
+  *
+  * @param interruptType one of Serial::RxIrq or Serial::TxIrq
+  */
+void MicroBitSerial::detach(Serial::IrqType interruptType)
+{
+    //we detach by sending a bad value to attach, for some weird reason...
+    attach((MicroBitSerial *)NULL, &MicroBitSerial::dataReceived, interruptType);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitStorage.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,506 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for the MicroBitStorage class.
+  * This allows reading and writing of FLASH memory.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitStorage.h"
+#include "MicroBitCompat.h"
+
+/**
+  * Default constructor.
+  *
+  * Creates an instance of MicroBitStorage which acts like a KeyValueStore
+  * that allows the retrieval, addition and deletion of KeyValuePairs.
+  */
+MicroBitStorage::MicroBitStorage()
+{
+    //initialise our magic block, if required.
+    size();
+}
+
+/**
+  * Writes the given number of bytes to the address specified.
+  *
+  * @param buffer the data to write.
+  *
+  * @param address the location in memory to write to.
+  *
+  * @param length the number of bytes to write.
+  *
+  * @note currently not implemented.
+  */
+int MicroBitStorage::writeBytes(uint8_t *buffer, uint32_t address, int length)
+{
+    (void) buffer;
+    (void) address;
+    (void) length;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Method for erasing a page in flash.
+  *
+  * @param page_address Address of the first word in the page to be erased.
+  */
+void MicroBitStorage::flashPageErase(uint32_t * page_address)
+{
+    // Turn on flash erase enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+
+    // Erase page:
+    NRF_NVMC->ERASEPAGE = (uint32_t)page_address;
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+
+    // Turn off flash erase enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+}
+
+/**
+  * Function for copying words from one location to another.
+  *
+  * @param from the address to copy data from.
+  *
+  * @param to the address to copy the data to.
+  *
+  * @param sizeInWords the number of words to copy
+  */
+void MicroBitStorage::flashCopy(uint32_t* from, uint32_t* to, int sizeInWords)
+{
+    // Turn on flash write enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {};
+
+    for(int i = 0; i < sizeInWords; i++)
+    {
+        *(to + i) = *(from + i);
+        while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {};
+    }
+
+    // Turn off flash write enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {};
+}
+
+/**
+  * Method for writing a word of data in flash with a value.
+  *
+  * @param address Address of the word to change.
+  *
+  * @param value Value to be written to flash.
+  */
+void MicroBitStorage::flashWordWrite(uint32_t * address, uint32_t value)
+{
+    // Turn on flash write enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+
+    *address = value;
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+
+    // Turn off flash write enable and wait until the NVMC is ready:
+    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
+
+    while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
+}
+
+/**
+  * Function for populating the scratch page with a KeyValueStore.
+  *
+  * @param store the KeyValueStore struct to write to the scratch page.
+  */
+void MicroBitStorage::scratchKeyValueStore(KeyValueStore store)
+{
+    //calculate our various offsets
+    uint32_t *s = (uint32_t *) &store;
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+
+    uint32_t *scratchPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET));
+
+    //KeyValueStore is word aligned.
+    int wordsToWrite = sizeof(KeyValueStore) / 4;
+
+    //write the given KeyValueStore
+    for (int i = 0; i < wordsToWrite; i++)
+    {
+        flashWordWrite(scratchPointer, *s);
+        scratchPointer++;
+        s++;
+    }
+}
+
+/**
+  * Function for populating the scratch page with a KeyValuePair.
+  *
+  * @param pair the KeyValuePair struct to write to the scratch page.
+  *
+  * @param flashPointer the pointer in flash where this KeyValuePair resides. This pointer
+  * is used to determine the offset into the scratch page, where the KeyValuePair should
+  * be written.
+  */
+void MicroBitStorage::scratchKeyValuePair(KeyValuePair pair, uint32_t* flashPointer)
+{
+    //we can only write using words
+    uint32_t *p = (uint32_t *) &pair;
+
+    //calculate our various offsets
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+    uint32_t pg_num  = NRF_FICR->CODESIZE - MICROBIT_STORAGE_STORE_PAGE_OFFSET;
+
+    uint32_t *scratchPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET));
+    uint32_t *flashBlockPointer = (uint32_t *)(pg_size * pg_num);
+
+    uint32_t flashPointerOffset = flashPointer - flashBlockPointer;
+
+    scratchPointer += flashPointerOffset;
+
+    //KeyValuePair is word aligned...
+    int wordsToWrite = sizeof(KeyValuePair) / 4;
+
+    //write
+    for (int i = 0; i < wordsToWrite; i++)
+    {
+        flashWordWrite(scratchPointer, *p);
+        scratchPointer++;
+        p++;
+    }
+}
+
+/**
+  * Places a given key, and it's corresponding value into flash at the earliest
+  * available point.
+  *
+  * @param key the unique name that should be used as an identifier for the given data.
+  *            The key is presumed to be null terminated.
+  *
+  * @param data a pointer to the beginning of the data to be persisted.
+  *
+  * @param dataSize the size of the data to be persisted
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
+  *         MICROBIT_NO_RESOURCES if the storage page is full
+  */
+int MicroBitStorage::put(const char *key, uint8_t *data, int dataSize)
+{
+    KeyValuePair pair = KeyValuePair();
+
+    int keySize = strlen(key) + 1;
+
+    if(keySize > (int)sizeof(pair.key) || dataSize > (int)sizeof(pair.value) || dataSize < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    KeyValuePair *currentValue = get(key);
+
+    int upToDate = currentValue && (memcmp(currentValue->value, data, dataSize) == 0);
+
+    if(currentValue)
+        delete currentValue;
+
+    if(upToDate)
+        return MICROBIT_OK;
+
+    memcpy(pair.key, key, keySize);
+    memcpy(pair.value, data, dataSize);
+
+    //calculate our various offsets.
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+    uint32_t *flashPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_STORE_PAGE_OFFSET));
+    uint32_t *flashBlockPointer = flashPointer;
+    uint32_t *scratchPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET));
+
+    uint32_t kvStoreSize = sizeof(KeyValueStore) / 4;
+    uint32_t kvPairSize = sizeof(KeyValuePair) / 4;
+
+    int storeSize = size();
+
+    //our KeyValueStore struct is always at 0
+    flashPointer += kvStoreSize;
+
+    KeyValuePair storedPair = KeyValuePair();
+
+    int found = 0;
+
+    //erase our scratch page
+    flashPageErase(scratchPointer);
+
+    //iterate through key value pairs in flash, writing them to the scratch page.
+    for(int i = 0; i < storeSize; i++)
+    {
+        memcpy(&storedPair, flashPointer, sizeof(KeyValuePair));
+
+        //check if the keys match...
+        if(strcmp((char *)storedPair.key, (char *)pair.key) == 0)
+        {
+            found = 1;
+            //scratch our KeyValueStore struct so that it is preserved.
+            scratchKeyValueStore(KeyValueStore(MICROBIT_STORAGE_MAGIC, storeSize));
+            scratchKeyValuePair(pair, flashPointer);
+        }
+        else
+        {
+            scratchKeyValuePair(storedPair, flashPointer);
+        }
+
+        flashPointer += kvPairSize;
+    }
+
+    if(!found)
+    {
+        //if we haven't got a match for the key, check we can add a new KeyValuePair
+        if(storeSize == (int)((pg_size - kvStoreSize) / MICROBIT_STORAGE_BLOCK_SIZE))
+            return MICROBIT_NO_RESOURCES;
+
+        storeSize += 1;
+
+        //scratch our updated values.
+        scratchKeyValueStore(KeyValueStore(MICROBIT_STORAGE_MAGIC, storeSize));
+        scratchKeyValuePair(pair, flashPointer);
+    }
+
+    //erase our storage page
+    flashPageErase((uint32_t *)flashBlockPointer);
+
+    //copy from scratch to storage.
+    flashCopy((uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET)), flashBlockPointer, kvStoreSize + (storeSize * kvPairSize));
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Places a given key, and it's corresponding value into flash at the earliest
+  * available point.
+  *
+  * @param key the unique name that should be used as an identifier for the given data.
+  *
+  * @param data a pointer to the beginning of the data to be persisted.
+  *
+  * @param dataSize the size of the data to be persisted
+  *
+  * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
+  *         MICROBIT_NO_RESOURCES if the storage page is full
+  */
+int MicroBitStorage::put(ManagedString key, uint8_t* data, int dataSize)
+{
+    return put((char *)key.toCharArray(), data, dataSize);
+}
+
+/**
+  * Retreives a KeyValuePair identified by a given key.
+  *
+  * @param key the unique name used to identify a KeyValuePair in flash.
+  *
+  * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
+  *         NULL if the key was not found in storage.
+  *
+  * @note it is up to the user to free memory after use.
+  */
+KeyValuePair* MicroBitStorage::get(const char* key)
+{
+    //calculate our offsets for our storage page
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+    uint32_t pg_num  = NRF_FICR->CODESIZE - MICROBIT_STORAGE_STORE_PAGE_OFFSET;
+
+    uint32_t *flashBlockPointer = (uint32_t *)(pg_size * pg_num);
+
+    int storeSize = size();
+
+    //we haven't got anything stored, so return...
+    if(storeSize == 0)
+        return NULL;
+
+    //our KeyValueStore struct is always at 0
+    flashBlockPointer += sizeof(KeyValueStore) / 4;
+
+    KeyValuePair *pair = new KeyValuePair();
+
+    int i;
+
+    //iterate through flash until we have a match, or drop out.
+    for(i = 0; i < storeSize; i++)
+    {
+        memcpy(pair, flashBlockPointer, sizeof(KeyValuePair));
+
+        if(strcmp(key,(char *)pair->key) == 0)
+            break;
+
+        flashBlockPointer += sizeof(KeyValuePair) / 4;
+    }
+
+    //clean up
+    if(i == storeSize)
+    {
+        delete pair;
+        return NULL;
+    }
+
+    return pair;
+}
+
+/**
+  * Retreives a KeyValuePair identified by a given key.
+  *
+  * @param key the unique name used to identify a KeyValuePair in flash.
+  *
+  * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
+  *         NULL if the key was not found in storage.
+  *
+  * @note it is up to the user to free memory after use.
+  */
+KeyValuePair* MicroBitStorage::get(ManagedString key)
+{
+    return get((char *)key.toCharArray());
+}
+
+/**
+  * Removes a KeyValuePair identified by a given key.
+  *
+  * @param key the unique name used to identify a KeyValuePair in flash.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
+  *         was not found in flash.
+  */
+int MicroBitStorage::remove(const char* key)
+{
+    //calculate our various offsets
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+    uint32_t *flashPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_STORE_PAGE_OFFSET));
+    uint32_t *flashBlockPointer = flashPointer;
+    uint32_t *scratchPointer = (uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET));
+
+    uint32_t kvStoreSize = sizeof(KeyValueStore) / 4;
+    uint32_t kvPairSize = sizeof(KeyValuePair) / 4;
+
+    int storeSize = size();
+
+    //if we have no data, we have nothing to do.
+    if(storeSize == 0)
+        return MICROBIT_NO_DATA;
+
+    //our KeyValueStore struct is always at 0
+    flashPointer += kvStoreSize;
+    scratchPointer += kvStoreSize;
+
+    KeyValuePair storedPair = KeyValuePair();
+
+    int found = 0;
+
+    //set up our scratch area
+    flashPageErase(scratchPointer);
+
+    //iterate through our flash copy pairs to scratch, unless there is a key patch
+    for(int i = 0; i < storeSize; i++)
+    {
+        memcpy(&storedPair, flashPointer, sizeof(KeyValuePair));
+
+        //if we have a match, don't increment our scratchPointer
+        if(strcmp((char *)storedPair.key, (char *)key) == 0)
+        {
+            found = 1;
+            //write our new KeyValueStore data
+            scratchKeyValueStore(KeyValueStore(MICROBIT_STORAGE_MAGIC, storeSize - 1));
+        }
+        else
+        {
+            //otherwise copy the KeyValuePair from our storage page.
+            flashCopy(flashPointer, scratchPointer, sizeof(KeyValuePair) / 4);
+            scratchPointer += sizeof(KeyValuePair) / 4;
+        }
+
+        flashPointer += sizeof(KeyValuePair) / 4;
+    }
+
+    //if we haven't got a match, write our old KeyValueStore struct
+    if(!found)
+    {
+        scratchKeyValueStore(KeyValueStore(MICROBIT_STORAGE_MAGIC, storeSize));
+        return MICROBIT_NO_DATA;
+    }
+
+    //copy scratch to our storage page
+    flashPageErase((uint32_t *)flashBlockPointer);
+    flashCopy((uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET)), flashBlockPointer, kvStoreSize + (storeSize * kvPairSize));
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Removes a KeyValuePair identified by a given key.
+  *
+  * @param key the unique name used to identify a KeyValuePair in flash.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
+  *         was not found in flash.
+  */
+int MicroBitStorage::remove(ManagedString key)
+{
+    return remove((char *)key.toCharArray());
+}
+
+/**
+  * The size of the flash based KeyValueStore.
+  *
+  * @return the number of entries in the key value store
+  */
+int MicroBitStorage::size()
+{
+    uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
+    uint32_t pg_num  = NRF_FICR->CODESIZE - MICROBIT_STORAGE_STORE_PAGE_OFFSET;
+
+    uint32_t *flashBlockPointer = (uint32_t *)(pg_size * pg_num);
+
+    KeyValueStore store = KeyValueStore();
+
+    //read our data!
+    memcpy(&store, flashBlockPointer, sizeof(KeyValueStore));
+
+    //if we haven't used flash before, we need to configure it
+    if(store.magic != MICROBIT_STORAGE_MAGIC)
+    {
+        store.magic = MICROBIT_STORAGE_MAGIC;
+        store.size = 0;
+
+        //erase the scratch page and write our new KeyValueStore
+        flashPageErase((uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET)));
+        scratchKeyValueStore(store);
+
+        //erase flash, and copy the scratch page over
+        flashPageErase((uint32_t *)flashBlockPointer);
+        flashCopy((uint32_t *)(pg_size * (NRF_FICR->CODESIZE - MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET)), flashBlockPointer, pg_size/4);
+    }
+
+    return store.size;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/MicroBitThermometer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,268 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "MicroBitThermometer.h"
+#include "MicroBitSystemTimer.h"
+#include "MicroBitFiber.h"
+
+/*
+ * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include "nrf_soc.h"
+#include "nrf_sdm.h"
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic pop
+#endif
+
+/**
+  * Constructor.
+  * Create new MicroBitThermometer that gives an indication of the current temperature.
+  *
+  * @param _storage an instance of MicroBitStorage used to persist temperature offset data
+  *
+  * @param id the unique EventModel id of this component. Defaults to MICROBIT_ID_THERMOMETER.
+  *
+  * @code
+  * MicroBitStorage storage;
+  * MicroBitThermometer thermometer(storage);
+  * @endcode
+  */
+MicroBitThermometer::MicroBitThermometer(MicroBitStorage& _storage, uint16_t id) :
+    storage(&_storage)
+{
+    this->id = id;
+    this->samplePeriod = MICROBIT_THERMOMETER_PERIOD;
+    this->sampleTime = 0;
+    this->offset = 0;
+
+    KeyValuePair *tempCalibration =  storage->get("tempCal");
+
+    if(tempCalibration != NULL)
+    {
+        memcpy(&offset, tempCalibration->value, sizeof(int16_t));
+        delete tempCalibration;
+    }
+}
+
+/**
+  * Constructor.
+  * Create new MicroBitThermometer that gives an indication of the current temperature.
+  *
+  * @param id the unique EventModel id of this component. Defaults to MICROBIT_ID_THERMOMETER.
+  *
+  * @code
+  * MicroBitThermometer thermometer;
+  * @endcode
+  */
+MicroBitThermometer::MicroBitThermometer(uint16_t id) :
+    storage(NULL)
+{
+    this->id = id;
+    this->samplePeriod = MICROBIT_THERMOMETER_PERIOD;
+    this->sampleTime = 0;
+    this->offset = 0;
+}
+
+/**
+  * Gets the current temperature of the microbit.
+  *
+  * @return the current temperature, in degrees celsius.
+  *
+  * @code
+  * thermometer.getTemperature();
+  * @endcode
+  */
+int MicroBitThermometer::getTemperature()
+{
+    updateSample();
+    return temperature - offset;
+}
+
+
+/**
+  * Updates the temperature sample of this instance of MicroBitThermometer
+  * only if isSampleNeeded() indicates that an update is required.
+  *
+  * This call also will add the thermometer to fiber components to receive
+  * periodic callbacks.
+  *
+  * @return MICROBIT_OK on success.
+  */
+int MicroBitThermometer::updateSample()
+{
+    if(!(status & MICROBIT_THERMOMETER_ADDED_TO_IDLE))
+    {
+        // If we're running under a fiber scheduer, register ourselves for a periodic callback to keep our data up to date.
+        // Otherwise, we do just do this on demand, when polled through our read() interface.
+        fiber_add_idle_component(this);
+        status |= MICROBIT_THERMOMETER_ADDED_TO_IDLE;
+    }
+
+    // check if we need to update our sample...
+    if(isSampleNeeded())
+    {
+        int32_t processorTemperature;
+        uint8_t sd_enabled;
+
+        // For now, we just rely on the nrf senesor to be the most accurate.
+        // The compass module also has a temperature sensor, and has the lowest power consumption, so will run the cooler...
+        // ...however it isn't trimmed for accuracy during manufacture, so requires calibration.
+
+        sd_softdevice_is_enabled(&sd_enabled);
+
+        if (sd_enabled)
+        {
+            // If Bluetooth is enabled, we need to go through the Nordic software to safely do this
+            sd_temp_get(&processorTemperature);
+        }
+        else
+        {
+            // Othwerwise, we access the information directly...
+            uint32_t *TEMP = (uint32_t *)0x4000C508;
+
+            NRF_TEMP->TASKS_START = 1;
+
+            while (NRF_TEMP->EVENTS_DATARDY == 0);
+
+            NRF_TEMP->EVENTS_DATARDY = 0;
+
+            processorTemperature = *TEMP;
+
+            NRF_TEMP->TASKS_STOP = 1;
+        }
+
+
+        // Record our reading...
+        temperature = processorTemperature / 4;
+
+        // Schedule our next sample.
+        sampleTime = system_timer_current_time() + samplePeriod;
+
+        // Send an event to indicate that we'e updated our temperature.
+        MicroBitEvent e(id, MICROBIT_THERMOMETER_EVT_UPDATE);
+    }
+
+    return MICROBIT_OK;
+};
+
+/**
+  * Periodic callback from MicroBit idle thread.
+  */
+void MicroBitThermometer::idleTick()
+{
+    updateSample();
+}
+
+/**
+  * Determines if we're due to take another temperature reading
+  *
+  * @return 1 if we're due to take a temperature reading, 0 otherwise.
+  */
+int MicroBitThermometer::isSampleNeeded()
+{
+    return  system_timer_current_time() >= sampleTime;
+}
+
+/**
+  * Set the sample rate at which the temperatureis read (in ms).
+  *
+  * The default sample period is 1 second.
+  *
+  * @param period the requested time between samples, in milliseconds.
+  *
+  * @note the temperature is always read in the background, and is only updated
+  * when the processor is idle, or when the temperature is explicitly read.
+  */
+void MicroBitThermometer::setPeriod(int period)
+{
+    updateSample();
+    samplePeriod = period;
+}
+
+/**
+  * Reads the currently configured sample rate of the thermometer.
+  *
+  * @return The time between samples, in milliseconds.
+  */
+int MicroBitThermometer::getPeriod()
+{
+    return samplePeriod;
+}
+
+/**
+  * Set the value that is used to offset the raw silicon temperature.
+  *
+  * @param offset the offset for the silicon temperature
+  *
+  * @return MICROBIT_OK on success
+  */
+int MicroBitThermometer::setOffset(int offset)
+{
+    if(this->storage != NULL)
+        this->storage->put(ManagedString("tempCal"), (uint8_t *)&offset, sizeof(int));
+
+    this->offset = offset;
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Retreive the value that is used to offset the raw silicon temperature.
+  *
+  * @return the current offset.
+  */
+int MicroBitThermometer::getOffset()
+{
+    return offset;
+}
+
+/**
+  * This member function fetches the raw silicon temperature, and calculates
+  * the value used to offset the raw silicon temperature based on a given temperature.
+  *
+  * @param calibrationTemp the temperature used to calculate the raw silicon temperature
+  * offset.
+  *
+  * @return MICROBIT_OK on success
+  */
+int MicroBitThermometer::setCalibration(int calibrationTemp)
+{
+    updateSample();
+    return setOffset(temperature - calibrationTemp);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/drivers/TimedInterruptIn.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,55 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 Lancaster University, UK.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "TimedInterruptIn.h"
+/**
+  * Constructor.
+  *
+  * Create an instance of TimedInterruptIn that has an additional timestamp field.
+  */
+TimedInterruptIn::TimedInterruptIn(PinName name) : InterruptIn(name)
+{
+    timestamp = 0;
+}
+
+/**
+  * Stores the given timestamp for this instance of TimedInterruptIn.
+  *
+  * @param timestamp the timestamp to retain.
+  */
+void TimedInterruptIn::setTimestamp(uint64_t timestamp)
+{
+    this->timestamp = timestamp;
+}
+
+/**
+  * Retrieves the retained timestamp for this instance of TimedInterruptIn.
+  *
+  * @return the timestamp held by this instance.
+  */
+uint64_t TimedInterruptIn::getTimestamp()
+{
+    return timestamp;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/ManagedString.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,491 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a ManagedString.
+  *
+  * Uses basic reference counting to implement a copy-assignable, immutable string.
+  *
+  * This maps closely to the constructs found in many high level application languages,
+  * such as Touch Develop.
+  *
+  * Written from first principles here, for several reasons:
+  * 1) std::shared_ptr is not yet availiable on the ARMCC compiler
+  *
+  * 2) to reduce memory footprint - we don't need many of the other features in the std library
+  *
+  * 3) it makes an interesting case study for anyone interested in seeing how it works!
+  *
+  * 4) we need explicit reference counting to inter-op with low-level application langauge runtimes.
+  *
+  * 5) the reference counting needs to also work for read-only, flash-resident strings
+  */
+#include <string.h>
+#include <stdlib.h>
+
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "ManagedString.h"
+#include "MicroBitCompat.h"
+
+static const char empty[] __attribute__ ((aligned (4))) = "\xff\xff\0\0\0";
+
+/**
+  * Internal constructor helper.
+  *
+  * Configures this ManagedString to refer to the static EmptyString
+  */
+void ManagedString::initEmpty()
+{
+    ptr = (StringData*)(void*)empty;
+}
+
+/**
+  * Internal constructor helper.
+  *
+  * Creates this ManagedString based on a given null terminated char array.
+  */
+void ManagedString::initString(const char *str)
+{
+    // Initialise this ManagedString as a new string, using the data provided.
+    // We assume the string is sane, and null terminated.
+    int len = strlen(str);
+    ptr = (StringData *) malloc(4+len+1);
+    ptr->init();
+    ptr->len = len;
+    memcpy(ptr->data, str, len+1);
+}
+
+/**
+  * Constructor.
+  * Create a managed string from a specially prepared string literal.
+  *
+  * @param ptr The literal - first two bytes should be 0xff, then the length in little endian, then the literal. The literal has to be 4-byte aligned.
+  *
+  * @code
+  * static const char hello[] __attribute__ ((aligned (4))) = "\xff\xff\x05\x00" "Hello";
+  * ManagedString s((StringData*)(void*)hello);
+  * @endcode
+  */
+ManagedString::ManagedString(StringData *p)
+{
+    ptr = p;
+    ptr->incr();
+}
+
+/**
+  * Get current ptr, do not decr() it, and set the current instance to empty string.
+  *
+  * This is to be used by specialized runtimes which pass StringData around.
+  */
+StringData* ManagedString::leakData()
+{
+    StringData *res = ptr;
+    initEmpty();
+    return res;
+}
+
+/**
+  * Constructor.
+  *
+  * Create a managed string from a given integer.
+  *
+  * @param value The integer from which to create the ManagedString.
+  *
+  * @code
+  * ManagedString s(20);
+  * @endcode
+  */
+ManagedString::ManagedString(const int value)
+{
+    char str[12];
+
+    itoa(value, str);
+    initString(str);
+}
+
+/**
+  * Constructor.
+  * Create a managed string from a given char.
+  *
+  * @param value The character from which to create the ManagedString.
+  *
+  * @code
+  * ManagedString s('a');
+  * @endcode
+  */
+ManagedString::ManagedString(const char value)
+{
+    char str[2] = {value, 0};
+    initString(str);
+}
+
+
+/**
+  * Constructor.
+  *
+  * Create a managed string from a pointer to an 8-bit character buffer.
+  *
+  * The buffer is copied to ensure safe memory management (the supplied
+  * character buffer may be declared on the stack for instance).
+  *
+  * @param str The character array on which to base the new ManagedString.
+  *
+  * @code
+  * ManagedString s("abcdefg");
+  * @endcode
+  */
+ManagedString::ManagedString(const char *str)
+{
+    // Sanity check. Return EmptyString for anything distasteful
+    if (str == NULL || *str == 0)
+    {
+        initEmpty();
+        return;
+    }
+
+    initString(str);
+}
+
+/**
+  * Private Constructor.
+  *
+  * Create a managed string based on a concat of two strings.
+  * The buffer is copied to ensure sane memory management (the supplied
+  * character buffer may be declared on the stack for instance).
+  *
+  * @param str1 The first string on which to base the new ManagedString.
+  *
+  * @param str2 The second string on which to base the new ManagedString.
+  */
+ManagedString::ManagedString(const ManagedString &s1, const ManagedString &s2)
+{
+    // Calculate length of new string.
+    int len = s1.length() + s2.length();
+
+    // Create a new buffer for holding the new string data.
+    ptr = (StringData*) malloc(4+len+1);
+    ptr->init();
+    ptr->len = len;
+
+    // Enter the data, and terminate the string.
+    memcpy(ptr->data, s1.toCharArray(), s1.length());
+    memcpy(ptr->data + s1.length(), s2.toCharArray(), s2.length());
+    ptr->data[len] = 0;
+}
+
+
+/**
+  * Constructor.
+  * Create a ManagedString from a PacketBuffer. All bytes in the
+  * PacketBuffer are added to the ManagedString.
+  *
+  * @param buffer The PacktBuffer from which to create the ManagedString.
+  *
+  * @code
+  * ManagedString s = radio.datagram.recv();
+  * @endcode
+  */
+ManagedString::ManagedString(PacketBuffer buffer)
+{
+    // Allocate a new buffer ( just in case the data is not NULL terminated).
+    ptr = (StringData*) malloc(4+buffer.length()+1);
+    ptr->init();
+
+    // Store the length of the new string
+    ptr->len = buffer.length();
+    memcpy(ptr->data, buffer.getBytes(), buffer.length());
+    ptr->data[buffer.length()] = 0;
+}
+
+/**
+  * Constructor.
+  * Create a ManagedString from a pointer to an 8-bit character buffer of a given length.
+  *
+  * The buffer is copied to ensure sane memory management (the supplied
+  * character buffer may be declared on the stack for instance).
+  *
+  * @param str The character array on which to base the new ManagedString.
+  *
+  * @param length The length of the character array
+  *
+  * @code
+  * ManagedString s("abcdefg",7);
+  * @endcode
+  */
+ManagedString::ManagedString(const char *str, const int16_t length)
+{
+    // Sanity check. Return EmptyString for anything distasteful
+    if (str == NULL || *str == 0 || (uint16_t)length > strlen(str)) // XXX length should be unsigned on the interface
+    {
+        initEmpty();
+        return;
+    }
+
+
+    // Allocate a new buffer, and create a NULL terminated string.
+    ptr = (StringData*) malloc(4+length+1);
+    ptr->init();
+    // Store the length of the new string
+    ptr->len = length;
+    memcpy(ptr->data, str, length);
+    ptr->data[length] = 0;
+}
+
+/**
+  * Copy constructor.
+  * Makes a new ManagedString identical to the one supplied.
+  *
+  * Shares the character buffer and reference count with the supplied ManagedString.
+  *
+  * @param s The ManagedString to copy.
+  *
+  * @code
+  * ManagedString s("abcdefg");
+  * ManagedString p(s);
+  * @endcode
+  */
+ManagedString::ManagedString(const ManagedString &s)
+{
+    ptr = s.ptr;
+    ptr->incr();
+}
+
+
+/**
+  * Default constructor.
+  *
+  * Create an empty ManagedString.
+  *
+  * @code
+  * ManagedString s();
+  * @endcode
+  */
+ManagedString::ManagedString()
+{
+    initEmpty();
+}
+
+/**
+  * Destructor.
+  *
+  * Free this ManagedString, and decrement the reference count to the
+  * internal character buffer.
+  *
+  * If we're holding the last reference, also free the character buffer.
+  */
+ManagedString::~ManagedString()
+{
+    ptr->decr();
+}
+
+/**
+  * Copy assign operation.
+  *
+  * Called when one ManagedString is assigned the value of another.
+  *
+  * If the ManagedString being assigned is already referring to a character buffer,
+  * decrement the reference count and free up the buffer as necessary.
+  *
+  * Then, update our character buffer to refer to that of the supplied ManagedString,
+  * and increase its reference count.
+  *
+  * @param s The ManagedString to copy.
+  *
+  * @code
+  * ManagedString s("abcd");
+  * ManagedString p("efgh");
+  * p = s   // p now points to s, s' ref is incremented
+  * @endcode
+  */
+ManagedString& ManagedString::operator = (const ManagedString& s)
+{
+    if (this->ptr == s.ptr)
+        return *this;
+
+    ptr->decr();
+    ptr = s.ptr;
+    ptr->incr();
+
+    return *this;
+}
+
+/**
+  * Equality operation.
+  *
+  * Called when one ManagedString is tested to be equal to another using the '==' operator.
+  *
+  * @param s The ManagedString to test ourselves against.
+  *
+  * @return true if this ManagedString is identical to the one supplied, false otherwise.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("abcd");
+  * ManagedString p("efgh");
+  *
+  * if(p == s)
+  *     display.scroll("We are the same!");
+  * else
+  *     display.scroll("We are different!"); //p is not equal to s - this will be called
+  * @endcode
+  */
+bool ManagedString::operator== (const ManagedString& s)
+{
+    return ((length() == s.length()) && (strcmp(toCharArray(),s.toCharArray())==0));
+}
+
+/**
+  * Inequality operation.
+  *
+  * Called when one ManagedString is tested to be less than another using the '<' operator.
+  *
+  * @param s The ManagedString to test ourselves against.
+  *
+  * @return true if this ManagedString is alphabetically less than to the one supplied, false otherwise.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("a");
+  * ManagedString p("b");
+  *
+  * if(s < p)
+  *     display.scroll("a is before b!"); //a is before b
+  * else
+  *     display.scroll("b is before a!");
+  * @endcode
+  */
+bool ManagedString::operator< (const ManagedString& s)
+{
+    return (strcmp(toCharArray(), s.toCharArray())<0);
+}
+
+/**
+  * Inequality operation.
+  *
+  * Called when one ManagedString is tested to be greater than another using the '>' operator.
+  *
+  * @param s The ManagedString to test ourselves against.
+  *
+  * @return true if this ManagedString is alphabetically greater than to the one supplied, false otherwise.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("a");
+  * ManagedString p("b");
+  *
+  * if(p>a)
+  *     display.scroll("b is after a!"); //b is after a
+  * else
+  *     display.scroll("a is after b!");
+  * @endcode
+  */
+bool ManagedString::operator> (const ManagedString& s)
+{
+    return (strcmp(toCharArray(), s.toCharArray())>0);
+}
+
+/**
+  * Extracts a ManagedString from this string, at the position provided.
+  *
+  * @param start The index of the first character to extract, indexed from zero.
+  *
+  * @param length The number of characters to extract from the start position
+  *
+  * @return a ManagedString representing the requested substring.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("abcdefg");
+  *
+  * display.scroll(s.substring(0,2)) // displays "ab"
+  * @endcode
+  */
+ManagedString ManagedString::substring(int16_t start, int16_t length)
+{
+    // If the parameters are illegal, just return a reference to the empty string.
+    if (start >= this->length())
+        return ManagedString(ManagedString::EmptyString);
+
+    // Compute a safe copy length;
+    length = min(this->length()-start, length);
+
+    // Build a ManagedString from this.
+    return ManagedString(toCharArray()+start, length);
+}
+
+/**
+  * Concatenates two strings.
+  *
+  * @param lhs The first ManagedString to concatenate.
+  * @param rhs The second ManagedString to concatenate.
+  *
+  * @return a new ManagedString representing the joined strings.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("abcd");
+  * ManagedString p("efgh")
+  *
+  * display.scroll(s + p) // scrolls "abcdefgh"
+  * @endcode
+  */
+ManagedString operator+ (const ManagedString& lhs, const ManagedString& rhs)
+{
+
+    // If the either string is empty, nothing to do!
+    if (rhs.length() == 0)
+        return lhs;
+
+    if (lhs.length() == 0)
+        return rhs;
+
+    return ManagedString(lhs, rhs);
+}
+
+
+/**
+  * Provides a character value at a given position in the string, indexed from zero.
+  *
+  * @param index The position of the character to return.
+  *
+  * @return the character at position index, zero if index is invalid.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * ManagedString s("abcd");
+  *
+  * display.scroll(s.charAt(1)) // scrolls "b"
+  * @endcode
+  */
+char ManagedString::charAt(int16_t index)
+{
+    return (index >=0 && index < length()) ? ptr->data[index] : 0;
+}
+
+/**
+  * Empty string constant literal
+  */
+ManagedString ManagedString::EmptyString((StringData*)(void*)empty);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/Matrix4.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,285 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "Matrix4.h"
+#include "mbed.h"
+
+/**
+* Class definition for a simple matrix, optimised for n x 4 or 4 x n matrices.
+*
+* This class is heavily optimised for these commonly used matrices as used in 3D geometry,
+* and is not intended as a general purpose matrix class. For programmers needing more flexible
+* Matrix support, the mbed Matrix and MatrixMath classes from Ernsesto Palacios provide a good basis:
+*
+* https://developer.mbed.org/cookbook/MatrixClass
+* https://developer.mbed.org/users/Yo_Robot/code/MatrixMath/
+*/
+
+/**
+  * Constructor.
+  * Create a matrix of the given size.
+  *
+  * @param rows the number of rows in the matrix to be created.
+  *
+  * @param cols the number of columns in the matrix to be created.
+  *
+  * @code
+  * Matrix4(10, 4);        // Creates a Matrix with 10 rows and 4 columns.
+  * @endcode
+  */
+Matrix4::Matrix4(int rows, int cols)
+{
+	this->rows = rows;
+	this->cols = cols;
+
+	int size = rows * cols;
+
+	if (size > 0)
+		data = new float[size];
+	else
+		data = NULL;
+}
+
+/**
+  * Constructor.
+  * Create a matrix that is an identical copy of the given matrix.
+  *
+  * @param matrix The matrix to copy.
+  *
+  * @code
+  * Matrix newMatrix(matrix);        .
+  * @endcode
+  */
+Matrix4::Matrix4(const Matrix4 &matrix)
+{
+	this->rows = matrix.rows;
+	this->cols = matrix.cols;
+
+	int size = rows * cols;
+
+	if (size > 0)
+	{
+		data = new float[size];
+		for (int i = 0; i < size; i++)
+			data[i] = matrix.data[i];
+	}
+	else
+	{
+		data = NULL;
+	}
+
+}
+
+/**
+  * Determines the number of columns in this matrix.
+  *
+  * @return The number of columns in the matrix.
+  *
+  * @code
+  * int c = matrix.width();
+  * @endcode
+  */
+int Matrix4::width()
+{
+	return cols;
+}
+
+/**
+  * Determines the number of rows in this matrix.
+  *
+  * @return The number of rows in the matrix.
+  *
+  * @code
+  * int r = matrix.height();
+  * @endcode
+  */
+int Matrix4::height()
+{
+	return rows;
+}
+
+/**
+  * Reads the matrix element at the given position.
+  *
+  * @param row The row of the element to read.
+  *
+  * @param col The column of the element to read.
+  *
+  * @return The value of the matrix element at the given position. 0 is returned if the given index is out of range.
+  *
+  * @code
+  * float v = matrix.get(1,2);
+  * @endcode
+  */
+float Matrix4::get(int row, int col)
+{
+	if (row < 0 || col < 0 || row >= rows || col >= cols)
+		return 0;
+
+	return data[width() * row + col];
+}
+
+/**
+  * Writes the matrix element at the given position.
+  *
+  * @param row The row of the element to write.
+  *
+  * @param col The column of the element to write.
+  *
+  * @param v The new value of the element.
+  *
+  * @code
+  * matrix.set(1,2,42.0);
+  * @endcode
+  */
+void Matrix4::set(int row, int col, float v)
+{
+	if (row < 0 || col < 0 || row >= rows || col >= cols)
+		return;
+
+	data[width() * row + col] = v;
+}
+
+/**
+  * Transposes this matrix.
+  *
+  * @return the resultant matrix.
+  *
+  * @code
+  * matrix.transpose();
+  * @endcode
+  */
+Matrix4 Matrix4::transpose()
+{
+	Matrix4 result = Matrix4(cols, rows);
+
+	for (int i = 0; i < width(); i++)
+		for (int j = 0; j < height(); j++)
+			result.set(i, j, get(j, i));
+
+	return result;
+}
+
+/**
+  * Multiplies this matrix with the given matrix (if possible).
+  *
+  * @param matrix the matrix to multiply this matrix's values against.
+  *
+  * @param transpose Transpose the matrices before multiplication. Defaults to false.
+  *
+  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+  *
+  * @code
+  * Matrix result = matrixA.multiply(matrixB);
+  * @endcode
+  */
+Matrix4 Matrix4::multiply(Matrix4 &matrix, bool transpose)
+{
+    int w = transpose ? height() : width();
+    int h = transpose ? width() : height();
+
+	if (w != matrix.height())
+		return Matrix4(0, 0);
+
+	Matrix4 result(h, matrix.width());
+
+	for (int r = 0; r < result.height(); r++)
+	{
+		for (int c = 0; c < result.width(); c++)
+		{
+			float v = 0.0;
+
+			for (int i = 0; i < w; i++)
+				v += (transpose ? get(i, r) : get(r, i)) * matrix.get(i, c);
+
+			result.set(r, c, v);
+		}
+	}
+
+	return result;
+}
+
+/**
+  * Performs an optimised inversion of a 4x4 matrix.
+  * Only 4x4 matrices are supported by this operation.
+  *
+  * @return the resultant matrix. An empty matrix is returned if the operation canot be completed.
+  *
+  * @code
+  * Matrix result = matrixA.invert();
+  * @endcode
+  */
+Matrix4 Matrix4::invert()
+{
+	// We only support square matrices of size 4...
+	if (width() != height() || width() != 4)
+		return Matrix4(0, 0);
+
+	Matrix4 result(width(), height());
+
+	result.data[0] = data[5] * data[10] * data[15] - data[5] * data[11] * data[14] - data[9] * data[6] * data[15] + data[9] * data[7] * data[14] + data[13] * data[6] * data[11] - data[13] * data[7] * data[10];
+	result.data[1] = -data[1] * data[10] * data[15] + data[1] * data[11] * data[14] + data[9] * data[2] * data[15] - data[9] * data[3] * data[14] - data[13] * data[2] * data[11] + data[13] * data[3] * data[10];
+	result.data[2] = data[1] * data[6] * data[15] - data[1] * data[7] * data[14] - data[5] * data[2] * data[15] + data[5] * data[3] * data[14] + data[13] * data[2] * data[7] - data[13] * data[3] * data[6];
+	result.data[3] = -data[1] * data[6] * data[11] + data[1] * data[7] * data[10] + data[5] * data[2] * data[11] - data[5] * data[3] * data[10] - data[9] * data[2] * data[7] + data[9] * data[3] * data[6];
+	result.data[4] = -data[4] * data[10] * data[15] + data[4] * data[11] * data[14] + data[8] * data[6] * data[15] - data[8] * data[7] * data[14] - data[12] * data[6] * data[11] + data[12] * data[7] * data[10];
+	result.data[5] = data[0] * data[10] * data[15] - data[0] * data[11] * data[14] - data[8] * data[2] * data[15] + data[8] * data[3] * data[14] + data[12] * data[2] * data[11] - data[12] * data[3] * data[10];
+	result.data[6] = -data[0] * data[6] * data[15] + data[0] * data[7] * data[14] + data[4] * data[2] * data[15] - data[4] * data[3] * data[14] - data[12] * data[2] * data[7] + data[12] * data[3] * data[6];
+	result.data[7] = data[0] * data[6] * data[11] - data[0] * data[7] * data[10] - data[4] * data[2] * data[11] + data[4] * data[3] * data[10] + data[8] * data[2] * data[7] - data[8] * data[3] * data[6];
+	result.data[8] = data[4] * data[9] * data[15] - data[4] * data[11] * data[13] - data[8] * data[5] * data[15] + data[8] * data[7] * data[13] + data[12] * data[5] * data[11] - data[12] * data[7] * data[9];
+	result.data[9] = -data[0] * data[9] * data[15] + data[0] * data[11] * data[13] + data[8] * data[1] * data[15] - data[8] * data[3] * data[13] - data[12] * data[1] * data[11] + data[12] * data[3] * data[9];
+	result.data[10] = data[0] * data[5] * data[15] - data[0] * data[7] * data[13] - data[4] * data[1] * data[15] + data[4] * data[3] * data[13] + data[12] * data[1] * data[7] - data[12] * data[3] * data[5];
+	result.data[11] = -data[0] * data[5] * data[11] + data[0] * data[7] * data[9] + data[4] * data[1] * data[11] - data[4] * data[3] * data[9] - data[8] * data[1] * data[7] + data[8] * data[3] * data[5];
+	result.data[12] = -data[4] * data[9] * data[14] + data[4] * data[10] * data[13] + data[8] * data[5] * data[14] - data[8] * data[6] * data[13] - data[12] * data[5] * data[10] + data[12] * data[6] * data[9];
+	result.data[13] = data[0] * data[9] * data[14] - data[0] * data[10] * data[13] - data[8] * data[1] * data[14] + data[8] * data[2] * data[13] + data[12] * data[1] * data[10] - data[12] * data[2] * data[9];
+	result.data[14] = -data[0] * data[5] * data[14] + data[0] * data[6] * data[13] + data[4] * data[1] * data[14] - data[4] * data[2] * data[13] - data[12] * data[1] * data[6] + data[12] * data[2] * data[5];
+	result.data[15] = data[0] * data[5] * data[10] - data[0] * data[6] * data[9] - data[4] * data[1] * data[10] + data[4] * data[2] * data[9] + data[8] * data[1] * data[6] - data[8] * data[2] * data[5];
+
+	float det = data[0] * result.data[0] + data[1] * result.data[4] + data[2] * result.data[8] + data[3] * result.data[12];
+
+	if (det == 0)
+		return Matrix4(0, 0);
+
+	det = 1.0f / det;
+
+	for (int i = 0; i < 16; i++)
+		result.data[i] *= det;
+
+	return result;
+}
+
+/**
+  * Destructor.
+  *
+  * Frees any memory consumed by this Matrix4 instance.
+  */
+Matrix4::~Matrix4()
+{
+	if (data != NULL)
+	{
+		delete data;
+		data = NULL;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/MicroBitEvent.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,97 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a MicroBitEvent
+  *
+  * It represents a common event that is generated by the various components on the micro:bit.
+  */
+#include "MicroBitConfig.h"
+#include "MicroBitEvent.h"
+#include "MicroBitSystemTimer.h"
+#include "EventModel.h"
+
+EventModel* EventModel::defaultEventBus = NULL;
+
+/**
+  * Constructor.
+  *
+  * @param src The id of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
+  *
+  * @param value A component specific code indicating the cause of the event.
+  *
+  * @param mode Optional definition of how the event should be processed after construction (if at all):
+  *                 CREATE_ONLY: MicroBitEvent is initialised, and no further processing takes place.
+  *                 CREATE_AND_FIRE: MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).
+  *
+  * @code
+  * // Create and launch an event using the default configuration
+  * MicrobitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK);
+  *
+  * // Create an event only, do not fire onto an EventModel.
+  * MicrobitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK,CREATE_AND_FIRE);
+  * @endcode
+  */
+MicroBitEvent::MicroBitEvent(uint16_t source, uint16_t value, MicroBitEventLaunchMode mode)
+{
+    this->source = source;
+    this->value = value;
+    this->timestamp = system_timer_current_time_us();
+
+    if(mode != CREATE_ONLY)
+        this->fire();
+}
+
+/**
+  * Default constructor - initialises all values, and sets timestamp to the current time.
+  */
+MicroBitEvent::MicroBitEvent()
+{
+    this->source = 0;
+    this->value = 0;
+    this->timestamp = system_timer_current_time_us();
+}
+
+/**
+  * Fires this MicroBitEvent onto the Default EventModel, or a custom one!
+  */
+void MicroBitEvent::fire()
+{
+	if(EventModel::defaultEventBus)
+		EventModel::defaultEventBus->send(*this);
+}
+
+
+/**
+  * Constructor.
+  * Create a new MicroBitEventQueueItem.
+  *
+  * @param evt The event to be queued.
+  */
+MicroBitEventQueueItem::MicroBitEventQueueItem(MicroBitEvent evt)
+{
+    this->evt = evt;
+	this->next = NULL;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/MicroBitImage.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,887 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Class definition for a MicroBitImage.
+  *
+  * An MicroBitImage is a simple bitmap representation of an image.
+  * n.b. This is a mutable, managed type.
+  */
+
+#include "MicroBitConfig.h"
+#include "MicroBitImage.h"
+#include "MicroBitFont.h"
+#include "MicroBitCompat.h"
+#include "ManagedString.h"
+#include "ErrorNo.h"
+
+
+/**
+  * The null image. We actally create a small one byte buffer here, just to keep NULL pointers out of the equation.
+  */
+static const uint16_t empty[] __attribute__ ((aligned (4))) = { 0xffff, 1, 1, 0, };
+MicroBitImage MicroBitImage::EmptyImage((ImageData*)(void*)empty);
+
+/**
+  * Default Constructor.
+  * Creates a new reference to the empty MicroBitImage bitmap
+  *
+  * @code
+  * MicroBitImage i(); //an empty image instance
+  * @endcode
+  */
+MicroBitImage::MicroBitImage()
+{
+    // Create new reference to the EmptyImage and we're done.
+    init_empty();
+}
+
+
+/**
+  * Constructor.
+  * Create a blank bitmap representation of a given size.
+  *
+  * @param x the width of the image.
+  *
+  * @param y the height of the image.
+  *
+  * Bitmap buffer is linear, with 8 bits per pixel, row by row,
+  * top to bottom with no word alignment. Stride is therefore the image width in pixels.
+  * in where w and h are width and height respectively, the layout is therefore:
+  *
+  * |[0,0]...[w,o][1,0]...[w,1]  ...  [[w,h]
+  *
+  * A copy of the image is made in RAM, as images are mutable.
+  *
+  * TODO: Consider an immutable flavour, which might save us RAM for animation spritesheets...
+  * ...as these could be kept in FLASH.
+  */
+MicroBitImage::MicroBitImage(const int16_t x, const int16_t y)
+{
+    this->init(x,y,NULL);
+}
+
+/**
+  * Copy Constructor.
+  * Add ourselves as a reference to an existing MicroBitImage.
+  *
+  * @param image The MicroBitImage to reference.
+  *
+  * @code
+  * MicroBitImage i("0,1,0,1,0\n");
+  * MicroBitImage i2(i); //points to i
+  * @endcode
+  */
+MicroBitImage::MicroBitImage(const MicroBitImage &image)
+{
+    ptr = image.ptr;
+    ptr->incr();
+}
+
+/**
+  * Constructor.
+  * Create a blank bitmap representation of a given size.
+  *
+  * @param s A text based representation of the image given whitespace delimited numeric values.
+  *
+  * @code
+  * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+  * @endcode
+  */
+MicroBitImage::MicroBitImage(const char *s)
+{
+    int width = 0;
+    int height = 0;
+    int count = 0;
+    int digit = 0;
+
+    char parseBuf[10];
+
+    const char *parseReadPtr;
+    char *parseWritePtr;
+    uint8_t *bitmapPtr;
+
+    if (s == NULL)
+    {
+        init_empty();
+        return;
+    }
+
+    // First pass: Parse the string to determine the geometry of the image.
+    // We do this from first principles to avoid unecessary load of the strtok() libs etc.
+    parseReadPtr = s;
+
+    while (*parseReadPtr)
+    {
+        if (isdigit(*parseReadPtr))
+        {
+            // Ignore numbers.
+            digit = 1;
+        }
+        else if (*parseReadPtr =='\n')
+        {
+            if (digit)
+            {
+                count++;
+                digit = 0;
+            }
+
+            height++;
+
+            width = count > width ? count : width;
+            count = 0;
+        }
+        else
+        {
+            if (digit)
+            {
+                count++;
+                digit = 0;
+            }
+        }
+
+        parseReadPtr++;
+    }
+
+    this->init(width, height, NULL);
+
+    // Second pass: collect the data.
+    parseReadPtr = s;
+    parseWritePtr = parseBuf;
+    bitmapPtr = this->getBitmap();
+
+    while (*parseReadPtr)
+    {
+        if (isdigit(*parseReadPtr))
+        {
+            *parseWritePtr = *parseReadPtr;
+            parseWritePtr++;
+        }
+        else
+        {
+            *parseWritePtr = 0;
+            if (parseWritePtr > parseBuf)
+            {
+                *bitmapPtr = atoi(parseBuf);
+                bitmapPtr++;
+                parseWritePtr = parseBuf;
+            }
+        }
+
+        parseReadPtr++;
+    }
+}
+
+/**
+  * Constructor.
+  * Create an image from a specially prepared constant array, with no copying. Will call ptr->incr().
+  *
+  * @param ptr The literal - first two bytes should be 0xff, then width, 0, height, 0, and the bitmap. Width and height are 16 bit. The literal has to be 4-byte aligned.
+  *
+  * @code
+  * static const uint8_t heart[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 10, 0, 5, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i((ImageData*)(void*)heart);
+  * @endcode
+  */
+MicroBitImage::MicroBitImage(ImageData *p)
+{
+    ptr = p;
+    ptr->incr();
+}
+
+/**
+  * Get current ptr, do not decr() it, and set the current instance to empty image.
+  *
+  * This is to be used by specialized runtimes which pass ImageData around.
+  */
+ImageData *MicroBitImage::leakData()
+{
+    ImageData* res = ptr;
+    init_empty();
+    return res;
+}
+
+
+/**
+  * Constructor.
+  * Create a bitmap representation of a given size, based on a given buffer.
+  *
+  * @param x the width of the image.
+  *
+  * @param y the height of the image.
+  *
+  * @param bitmap a 2D array representing the image.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * @endcode
+  */
+MicroBitImage::MicroBitImage(const int16_t x, const int16_t y, const uint8_t *bitmap)
+{
+    this->init(x,y,bitmap);
+}
+
+/**
+  * Destructor.
+  *
+  * Removes buffer resources held by the instance.
+  */
+MicroBitImage::~MicroBitImage()
+{
+    ptr->decr();
+}
+
+/**
+  * Internal constructor which defaults to the EmptyImage instance variable
+  */
+void MicroBitImage::init_empty()
+{
+    ptr = (ImageData*)(void*)empty;
+}
+
+/**
+  * Internal constructor which provides sanity checking and initialises class properties.
+  *
+  * @param x the width of the image
+  *
+  * @param y the height of the image
+  *
+  * @param bitmap an array of integers that make up an image.
+  */
+void MicroBitImage::init(const int16_t x, const int16_t y, const uint8_t *bitmap)
+{
+    //sanity check size of image - you cannot have a negative sizes
+    if(x < 0 || y < 0)
+    {
+        init_empty();
+        return;
+    }
+
+
+    // Create a copy of the array
+    ptr = (ImageData*)malloc(sizeof(ImageData) + x * y);
+    ptr->init();
+    ptr->width = x;
+    ptr->height = y;
+
+    // create a linear buffer to represent the image. We could use a jagged/2D array here, but experimentation
+    // showed this had a negative effect on memory management (heap fragmentation etc).
+
+    if (bitmap)
+        this->printImage(x,y,bitmap);
+    else
+        this->clear();
+}
+
+/**
+  * Copy assign operation.
+  *
+  * Called when one MicroBitImage is assigned the value of another using the '=' operator.
+  *
+  * Decrement our reference count and free up the buffer as necessary.
+  *
+  * Then, update our buffer to refer to that of the supplied MicroBitImage,
+  * and increase its reference count.
+  *
+  * @param s The MicroBitImage to reference.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * MicroBitImage i1();
+  * i1 = i; // i1 now references i
+  * @endcode
+  */
+MicroBitImage& MicroBitImage::operator = (const MicroBitImage& i)
+{
+    if(ptr == i.ptr)
+        return *this;
+
+    ptr->decr();
+    ptr = i.ptr;
+    ptr->incr();
+
+    return *this;
+}
+
+/**
+  * Equality operation.
+  *
+  * Called when one MicroBitImage is tested to be equal to another using the '==' operator.
+  *
+  * @param i The MicroBitImage to test ourselves against.
+  *
+  * @return true if this MicroBitImage is identical to the one supplied, false otherwise.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * MicroBitImage i();
+  * MicroBitImage i1();
+  *
+  * if(i == i1) //will be true
+  *     display.scroll("true");
+  * @endcode
+  */
+bool MicroBitImage::operator== (const MicroBitImage& i)
+{
+    if (ptr == i.ptr)
+        return true;
+    else
+        return (ptr->width == i.ptr->width && ptr->height == i.ptr->height && (memcmp(getBitmap(), i.ptr->data, getSize())==0));
+}
+
+
+/**
+  * Resets all pixels in this image to 0.
+  *
+  * @code
+  * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+  * i.clear();
+  * @endcode
+  */
+void MicroBitImage::clear()
+{
+    memclr(getBitmap(), getSize());
+}
+
+/**
+  * Sets the pixel at the given co-ordinates to a given value.
+  *
+  * @param x The co-ordinate of the pixel to change.
+  *
+  * @param y The co-ordinate of the pixel to change.
+  *
+  * @param value The new value of the pixel (the brightness level 0-255)
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+  * i.setPixelValue(0,0,255);
+  * @endcode
+  *
+  * @note all coordinates originate from the top left of an image.
+  */
+int MicroBitImage::setPixelValue(int16_t x , int16_t y, uint8_t value)
+{
+    //sanity check
+    if(x >= getWidth() || y >= getHeight() || x < 0 || y < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    this->getBitmap()[y*getWidth()+x] = value;
+    return MICROBIT_OK;
+}
+
+/**
+  * Retrieves the value of a given pixel.
+  *
+  * @param x The x co-ordinate of the pixel to read. Must be within the dimensions of the image.
+  *
+  * @param y The y co-ordinate of the pixel to read. Must be within the dimensions of the image.
+  *
+  * @return The value assigned to the given pixel location (the brightness level 0-255), or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
+  * i.getPixelValue(0,0); //should be 0;
+  * @endcode
+  */
+int MicroBitImage::getPixelValue(int16_t x , int16_t y)
+{
+    //sanity check
+    if(x >= getWidth() || y >= getHeight() || x < 0 || y < 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    return this->getBitmap()[y*getWidth()+x];
+}
+
+/**
+  * Replaces the content of this image with that of a given 2D array representing
+  * the image.
+  *
+  * @param x the width of the image. Must be within the dimensions of the image.
+  *
+  * @param y the width of the image. Must be within the dimensions of the image.
+  *
+  * @param bitmap a 2D array representing the image.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i();
+  * i.printImage(0,0,heart);
+  * @endcode
+  *
+  * @note all coordinates originate from the top left of an image.
+  */
+int MicroBitImage::printImage(int16_t width, int16_t height, const uint8_t *bitmap)
+{
+    const uint8_t *pIn;
+    uint8_t *pOut;
+    int pixelsToCopyX, pixelsToCopyY;
+
+    // Sanity check.
+    if (width <= 0 || width <= 0 || bitmap == NULL)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Calcualte sane start pointer.
+    pixelsToCopyX = min(width,this->getWidth());
+    pixelsToCopyY = min(height,this->getHeight());
+
+    pIn = bitmap;
+    pOut = this->getBitmap();
+
+    // Copy the image, stride by stride.
+    for (int i=0; i<pixelsToCopyY; i++)
+    {
+        memcpy(pOut, pIn, pixelsToCopyX);
+        pIn += width;
+        pOut += this->getWidth();
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Pastes a given bitmap at the given co-ordinates.
+  *
+  * Any pixels in the relevant area of this image are replaced.
+  *
+  * @param image The MicroBitImage to paste.
+  *
+  * @param x The leftmost X co-ordinate in this image where the given image should be pasted. Defaults to 0.
+  *
+  * @param y The uppermost Y co-ordinate in this image where the given image should be pasted. Defaults to 0.
+  *
+  * @param alpha set to 1 if transparency clear pixels in given image should be treated as transparent. Set to 0 otherwise.  Defaults to 0.
+  *
+  * @return The number of pixels written.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart); // a big heart
+  * i.paste(i, -5, 0); // a small heart
+  * @endcode
+  */
+int MicroBitImage::paste(const MicroBitImage &image, int16_t x, int16_t y, uint8_t alpha)
+{
+    uint8_t *pIn, *pOut;
+    int cx, cy;
+    int pxWritten = 0;
+
+    // Sanity check.
+    // We permit writes that overlap us, but ones that are clearly out of scope we can filter early.
+    if (x >= getWidth() || y >= getHeight() || x+image.getWidth() <= 0 || y+image.getHeight() <= 0)
+        return 0;
+
+    //Calculate the number of byte we need to copy in each dimension.
+    cx = x < 0 ? min(image.getWidth() + x, getWidth()) : min(image.getWidth(), getWidth() - x);
+    cy = y < 0 ? min(image.getHeight() + y, getHeight()) : min(image.getHeight(), getHeight() - y);
+
+    // Calculate sane start pointer.
+    pIn = image.ptr->data;
+    pIn += (x < 0) ? -x : 0;
+    pIn += (y < 0) ? -image.getWidth()*y : 0;
+
+    pOut = getBitmap();
+    pOut += (x > 0) ? x : 0;
+    pOut += (y > 0) ? getWidth()*y : 0;
+
+    // Copy the image, stride by stride
+    // If we want primitive transparecy, we do this byte by byte.
+    // If we don't, use a more efficient block memory copy instead. Every little helps!
+
+    if (alpha)
+    {
+        for (int i=0; i<cy; i++)
+        {
+            for (int j=0; j<cx; j++)
+            {
+                // Copy this byte if appropriate.
+                if (*(pIn+j) != 0){
+                    *(pOut+j) = *(pIn+j);
+                    pxWritten++;
+                }
+            }
+
+            pIn += image.getWidth();
+            pOut += getWidth();
+        }
+    }
+    else
+    {
+        for (int i=0; i<cy; i++)
+        {
+            memcpy(pOut, pIn, cx);
+
+            pxWritten += cx;
+            pIn += image.getWidth();
+            pOut += getWidth();
+        }
+    }
+
+    return pxWritten;
+}
+
+/**
+  * Prints a character to the display at the given location
+  *
+  * @param c The character to display.
+  *
+  * @param x The x co-ordinate of on the image to place the top left of the character. Defaults to 0.
+  *
+  * @param y The y co-ordinate of on the image to place the top left of the character. Defaults to 0.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * MicroBitImage i(5,5);
+  * i.print('a');
+  * @endcode
+  */
+int MicroBitImage::print(char c, int16_t x, int16_t y)
+{
+    unsigned char v;
+    int x1, y1;
+
+    MicroBitFont font = MicroBitFont::getSystemFont();
+
+    // Sanity check. Silently ignore anything out of bounds.
+    if (x >= getWidth() || y >= getHeight() || c < MICROBIT_FONT_ASCII_START || c > font.asciiEnd)
+        return MICROBIT_INVALID_PARAMETER;
+
+    // Paste.
+    int offset = (c-MICROBIT_FONT_ASCII_START) * 5;
+
+    for (int row=0; row<MICROBIT_FONT_HEIGHT; row++)
+    {
+        v = (char)*(font.characters + offset);
+
+        offset++;
+
+        // Update our Y co-ord write position
+        y1 = y+row;
+
+        for (int col = 0; col < MICROBIT_FONT_WIDTH; col++)
+        {
+            // Update our X co-ord write position
+            x1 = x+col;
+
+            if (x1 < getWidth() && y1 < getHeight())
+                this->getBitmap()[y1*getWidth()+x1] = (v & (0x10 >> col)) ? 255 : 0;
+        }
+    }
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Shifts the pixels in this Image a given number of pixels to the left.
+  *
+  * @param n The number of pixels to shift.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart); // a big heart
+  * i.shiftLeft(5); // a small heart
+  * @endcode
+  */
+int MicroBitImage::shiftLeft(int16_t n)
+{
+    uint8_t *p = getBitmap();
+    int pixels = getWidth()-n;
+
+    if (n <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    if(n >= getWidth())
+    {
+        clear();
+        return MICROBIT_OK;
+    }
+
+    for (int y = 0; y < getHeight(); y++)
+    {
+        // Copy, and blank fill the rightmost column.
+        memcpy(p, p+n, pixels);
+        memclr(p+pixels, n);
+        p += getWidth();
+    }
+
+    return MICROBIT_OK;
+}
+
+/**
+  * Shifts the pixels in this Image a given number of pixels to the right.
+  *
+  * @param n The number of pixels to shift.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart); // a big heart
+  * i.shiftLeft(5); // a small heart
+  * i.shiftRight(5); // a big heart
+  * @endcode
+  */
+int MicroBitImage::shiftRight(int16_t n)
+{
+    uint8_t *p = getBitmap();
+    int pixels = getWidth()-n;
+
+    if (n <= 0)
+        return MICROBIT_INVALID_PARAMETER;
+
+    if(n >= getWidth())
+    {
+        clear();
+        return MICROBIT_OK;
+    }
+
+    for (int y = 0; y < getHeight(); y++)
+    {
+        // Copy, and blank fill the leftmost column.
+        memmove(p+n, p, pixels);
+        memclr(p, n);
+        p += getWidth();
+    }
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Shifts the pixels in this Image a given number of pixels to upward.
+  *
+  * @param n The number of pixels to shift.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * i.shiftUp(1);
+  * @endcode
+  */
+int MicroBitImage::shiftUp(int16_t n)
+{
+    uint8_t *pOut, *pIn;
+
+    if (n <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    if(n >= getHeight())
+    {
+        clear();
+        return MICROBIT_OK;
+    }
+
+    pOut = getBitmap();
+    pIn = getBitmap()+getWidth()*n;
+
+    for (int y = 0; y < getHeight(); y++)
+    {
+        // Copy, and blank fill the leftmost column.
+        if (y < getHeight()-n)
+            memcpy(pOut, pIn, getWidth());
+        else
+            memclr(pOut, getWidth());
+
+        pIn += getWidth();
+        pOut += getWidth();
+    }
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Shifts the pixels in this Image a given number of pixels to downward.
+  *
+  * @param n The number of pixels to shift.
+  *
+  * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * i.shiftDown(1);
+  * @endcode
+  */
+int MicroBitImage::shiftDown(int16_t n)
+{
+    uint8_t *pOut, *pIn;
+
+    if (n <= 0 )
+        return MICROBIT_INVALID_PARAMETER;
+
+    if(n >= getHeight())
+    {
+        clear();
+        return MICROBIT_OK;
+    }
+
+    pOut = getBitmap() + getWidth()*(getHeight()-1);
+    pIn = pOut - getWidth()*n;
+
+    for (int y = 0; y < getHeight(); y++)
+    {
+        // Copy, and blank fill the leftmost column.
+        if (y < getHeight()-n)
+            memcpy(pOut, pIn, getWidth());
+        else
+            memclr(pOut, getWidth());
+
+        pIn -= getWidth();
+        pOut -= getWidth();
+    }
+
+    return MICROBIT_OK;
+}
+
+
+/**
+  * Converts the bitmap to a csv ManagedString.
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * uBit.serial.printString(i.toString()); // "0,1,0,1,0,0,0,0,0,0\n..."
+  * @endcode
+  */
+ManagedString MicroBitImage::toString()
+{
+    //width including commans and \n * height
+    int stringSize = getSize() * 2;
+
+    //plus one for string terminator
+    char parseBuffer[stringSize + 1];
+
+    parseBuffer[stringSize] = '\0';
+
+    uint8_t *bitmapPtr = getBitmap();
+
+    int parseIndex = 0;
+    int widthCount = 0;
+
+    while (parseIndex < stringSize)
+    {
+        if(*bitmapPtr)
+            parseBuffer[parseIndex] = '1';
+        else
+            parseBuffer[parseIndex] = '0';
+
+        parseIndex++;
+
+        if(widthCount == getWidth()-1)
+        {
+            parseBuffer[parseIndex] = '\n';
+            widthCount = 0;
+        }
+        else
+        {
+            parseBuffer[parseIndex] = ',';
+            widthCount++;
+        }
+
+        parseIndex++;
+        bitmapPtr++;
+    }
+
+    return ManagedString(parseBuffer);
+}
+
+/**
+  * Crops the image to the given dimensions.
+  *
+  * @param startx the location to start the crop in the x-axis
+  *
+  * @param starty the location to start the crop in the y-axis
+  *
+  * @param width the width of the desired cropped region
+  *
+  * @param height the height of the desired cropped region
+  *
+  * @code
+  * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
+  * MicroBitImage i(10,5,heart);
+  * i.crop(0,0,2,2).toString() // "0,1\n1,1\n"
+  * @endcode
+  */
+MicroBitImage MicroBitImage::crop(int startx, int starty, int cropWidth, int cropHeight)
+{
+    int newWidth = startx + cropWidth;
+    int newHeight = starty + cropHeight;
+
+    if (newWidth >= getWidth() || newWidth <=0)
+        newWidth = getWidth();
+
+    if (newHeight >= getHeight() || newHeight <= 0)
+        newHeight = getHeight();
+
+    //allocate our storage.
+    uint8_t cropped[newWidth * newHeight];
+
+    //calculate the pointer to where we want to begin cropping
+    uint8_t *copyPointer = getBitmap() + (getWidth() * starty) + startx;
+
+    //get a reference to our storage
+    uint8_t *pastePointer = cropped;
+
+    //go through row by row and select our image.
+    for (int i = starty; i < newHeight; i++)
+    {
+        memcpy(pastePointer, copyPointer, newWidth);
+
+        copyPointer += getWidth();
+        pastePointer += newHeight;
+    }
+
+    return MicroBitImage(newWidth, newHeight, cropped);
+}
+
+/**
+  * Check if image is read-only (i.e., residing in flash).
+  */
+bool MicroBitImage::isReadOnly()
+{
+    return ptr->isReadOnly();
+}
+
+/**
+  * Create a copy of the image bitmap. Used particularly, when isReadOnly() is true.
+  *
+  * @return an instance of MicroBitImage which can be modified independently of the current instance
+  */
+MicroBitImage MicroBitImage::clone()
+{
+    return MicroBitImage(getWidth(), getHeight(), getBitmap());
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/PacketBuffer.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,326 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+#include "PacketBuffer.h"
+#include "ErrorNo.h"
+
+// Create the EmptyPacket reference.
+PacketBuffer PacketBuffer::EmptyPacket = PacketBuffer(1);
+
+/**
+  * Default Constructor.
+  * Creates an empty Packet Buffer.
+  *
+  * @code
+  * PacketBuffer p();
+  * @endcode
+  */
+PacketBuffer::PacketBuffer()
+{
+    this->init(NULL, 0, 0);
+}
+
+/**
+  * Constructor.
+  * Creates a new PacketBuffer of the given size.
+  *
+  * @param length The length of the buffer to create.
+  *
+  * @code
+  * PacketBuffer p(16);         // Creates a PacketBuffer 16 bytes long.
+  * @endcode
+  */
+PacketBuffer::PacketBuffer(int length)
+{
+    this->init(NULL, length, 0);
+}
+
+/**
+  * Constructor.
+  * Creates an empty Packet Buffer of the given size,
+  * and fills it with the data provided.
+  *
+  * @param data The data with which to fill the buffer.
+  *
+  * @param length The length of the buffer to create.
+  *
+  * @param rssi The radio signal strength at the time this packet was recieved. Defaults to 0.
+  *
+  * @code
+  * uint8_t buf = {13,5,2};
+  * PacketBuffer p(buf, 3);         // Creates a PacketBuffer 3 bytes long.
+  * @endcode
+  */
+PacketBuffer::PacketBuffer(uint8_t *data, int length, int rssi)
+{
+    this->init(data, length, rssi);
+}
+
+/**
+  * Copy Constructor.
+  * Add ourselves as a reference to an existing PacketBuffer.
+  *
+  * @param buffer The PacketBuffer to reference.
+  *
+  * @code
+  * PacketBuffer p();
+  * PacketBuffer p2(p); // Refers to the same packet as p.
+  * @endcode
+  */
+PacketBuffer::PacketBuffer(const PacketBuffer &buffer)
+{
+    ptr = buffer.ptr;
+    ptr->incr();
+}
+
+/**
+  * Internal constructor-initialiser.
+  *
+  * @param data The data with which to fill the buffer.
+  *
+  * @param length The length of the buffer to create.
+  *
+  * @param rssi The radio signal strength at the time this packet was recieved.
+  */
+void PacketBuffer::init(uint8_t *data, int length, int rssi)
+{
+    if (length < 0)
+        length = 0;
+
+    ptr = (PacketData *) malloc(sizeof(PacketData) + length);
+    ptr->init();
+
+    ptr->length = length;
+    ptr->rssi = rssi;
+
+    // Copy in the data buffer, if provided.
+    if (data)
+        memcpy(ptr->payload, data, length);
+}
+
+/**
+  * Destructor.
+  *
+  * Removes buffer resources held by the instance.
+  */
+PacketBuffer::~PacketBuffer()
+{
+    ptr->decr();
+}
+
+/**
+  * Copy assign operation.
+  *
+  * Called when one PacketBuffer is assigned the value of another using the '=' operator.
+  *
+  * Decrements our reference count and free up the buffer as necessary.
+  *
+  * Then, update our buffer to refer to that of the supplied PacketBuffer,
+  * and increase its reference count.
+  *
+  * @param p The PacketBuffer to reference.
+  *
+  * @code
+  * uint8_t buf = {13,5,2};
+  * PacketBuffer p1(16);
+  * PacketBuffer p2(buf, 3);
+  *
+  * p1 = p2;
+  * @endcode
+  */
+PacketBuffer& PacketBuffer::operator = (const PacketBuffer &p)
+{
+    if(ptr == p.ptr)
+        return *this;
+
+    ptr->decr();
+    ptr = p.ptr;
+    ptr->incr();
+
+    return *this;
+}
+
+/**
+  * Array access operation (read).
+  *
+  * Called when a PacketBuffer is dereferenced with a [] operation.
+  *
+  * Transparently map this through to the underlying payload for elegance of programming.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * uint8_t data = p1[0];
+  * @endcode
+  */
+uint8_t PacketBuffer::operator [] (int i) const
+{
+    return ptr->payload[i];
+}
+
+/**
+  * Array access operation (modify).
+  *
+  * Called when a PacketBuffer is dereferenced with a [] operation.
+  *
+  * Transparently map this through to the underlying payload for elegance of programming.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1[0] = 42;
+  * @endcode
+  */
+uint8_t& PacketBuffer::operator [] (int i)
+{
+    return ptr->payload[i];
+}
+
+/**
+  * Equality operation.
+  *
+  * Called when one PacketBuffer is tested to be equal to another using the '==' operator.
+  *
+  * @param p The PacketBuffer to test ourselves against.
+  *
+  * @return true if this PacketBuffer is identical to the one supplied, false otherwise.
+  *
+  * @code
+  * MicroBitDisplay display;
+  * uint8_t buf = {13,5,2};
+  * PacketBuffer p1();
+  * PacketBuffer p2();
+  *
+  * if(p1 == p2)                    // will be true
+  *     display.scroll("same!");
+  * @endcode
+  */
+bool PacketBuffer::operator== (const PacketBuffer& p)
+{
+    if (ptr == p.ptr)
+        return true;
+    else
+        return (ptr->length == p.ptr->length && (memcmp(ptr->payload, p.ptr->payload, ptr->length)==0));
+}
+
+/**
+  * Sets the byte at the given index to value provided.
+  *
+  * @param position The index of the byte to change.
+  *
+  * @param value The new value of the byte (0-255).
+  *
+  * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1.setByte(0,255);              // Sets the first byte in the buffer to the value 255.
+  * @endcode
+  */
+int PacketBuffer::setByte(int position, uint8_t value)
+{
+    if (position < ptr->length)
+    {
+        ptr->payload[position] = value;
+        return MICROBIT_OK;
+    }
+    else
+    {
+        return MICROBIT_INVALID_PARAMETER;
+    }
+}
+
+/**
+  * Determines the value of the given byte in the packet.
+  *
+  * @param position The index of the byte to read.
+  *
+  * @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1.setByte(0,255);              // Sets the first byte in the buffer to the value 255.
+  * p1.getByte(0);                  // Returns 255.
+  * @endcode
+  */
+int PacketBuffer::getByte(int position)
+{
+    if (position < ptr->length)
+        return ptr->payload[position];
+    else
+        return MICROBIT_INVALID_PARAMETER;
+}
+
+/**
+  * Provide a pointer to a memory location containing the packet data.
+  *
+  * @return The contents of this packet, as an array of bytes.
+  */
+uint8_t*PacketBuffer::getBytes()
+{
+    return ptr->payload;
+}
+
+/**
+  * Gets number of bytes in this buffer
+  *
+  * @return The size of the buffer in bytes.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1.length(); // Returns 16.
+  * @endcode
+  */
+int PacketBuffer::length()
+{
+    return ptr->length;
+}
+
+/**
+  * Retrieves the received signal strength of this packet.
+  *
+  * @return The signal strength of the radio when this packet was received, in -dbM.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1.getRSSI();                 // Returns the received signal strength.
+  * @endcode
+  */
+int PacketBuffer::getRSSI()
+{
+    return ptr->rssi;
+}
+
+/**
+  * Sets the received signal strength of this packet.
+  *
+  * @code
+  * PacketBuffer p1(16);
+  * p1.setRSSI(37);
+  * @endcode
+  */
+void PacketBuffer::setRSSI(uint8_t rssi)
+{
+    ptr->rssi = rssi;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/microbit-dal/source/types/RefCounted.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,98 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+  * Base class for payload for ref-counted objects. Used by ManagedString and MicroBitImage.
+  * There is no constructor, as this struct is typically malloc()ed.
+  */
+#include "mbed.h"
+#include "MicroBitConfig.h"
+#include "RefCounted.h"
+#include "MicroBitDisplay.h"
+
+/**
+  * Initializes for one outstanding reference.
+  */
+void RefCounted::init()
+{
+    // Initialize to one reference (lowest bit set to 1)
+    refCount = 3;
+}
+
+/**
+  * Checks if the object resides in flash memory.
+  *
+  * @param t the object to check.
+  *
+  * @return true if the object resides in flash memory, false otherwise.
+  */
+static inline bool isReadOnlyInline(RefCounted *t)
+{
+    uint32_t refCount = t->refCount;
+
+    if (refCount == 0xffff)
+        return true; // object in flash
+
+    // Do some sanity checking while we're here
+    if (refCount == 1 ||        // object should have been deleted
+        (refCount & 1) == 0)    // refCount doesn't look right
+        microbit_panic(MICROBIT_HEAP_ERROR);
+
+    // Not read only
+    return false;
+}
+
+/**
+  * Checks if the object resides in flash memory.
+  *
+  * @return true if the object resides in flash memory, false otherwise.
+  */
+bool RefCounted::isReadOnly()
+{
+    return isReadOnlyInline(this);
+}
+
+/**
+  * Increment reference count.
+  */
+void RefCounted::incr()
+{
+    if (!isReadOnlyInline(this))
+        refCount += 2;
+}
+
+/**
+  * Decrement reference count.
+  */
+void RefCounted::decr()
+{
+    if (isReadOnlyInline(this))
+        return;
+
+    refCount -= 2;
+    if (refCount == 1) {
+        free(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/module.json	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,13 @@
+{
+  "name": "microbit",
+  "version": "2.0.0-rc4",
+  "description": "A simple to use collection of the most commonly used components in the micro:bit runtime",
+  "license": "MIT",
+  "dependencies": {
+    "microbit-dal": "lancaster-university/microbit-dal"
+  },
+  "extraIncludes": [
+    "inc"
+  ],
+  "targetDependencies": {}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/microbit/source/MicroBit.cpp	Mon Oct 17 12:41:20 2016 +0000
@@ -0,0 +1,223 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 British Broadcasting Corporation.
+This software is provided by Lancaster University by arrangement with the BBC.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MicroBitConfig.h"
+/*
+ * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ
+ * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL)
+ * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this
+ * as a compatability option, but does not support the options used...
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include "MicroBit.h"
+
+#include "nrf_soc.h"
+
+/*
+ * Return to our predefined compiler settings.
+ */
+#if !defined(__arm)
+#pragma GCC diagnostic pop
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_DBG)
+// We create and initialize to NULL here, but MicroBitSerial will automatically update this as needed in its constructor.
+RawSerial* SERIAL_DEBUG = NULL;
+#endif
+
+/**
+  * Constructor.
+  *
+  * Create a representation of a MicroBit device, which includes member variables
+  * that represent various device drivers used to control aspects of the micro:bit.
+  */
+MicroBit::MicroBit() :
+    serial(USBTX, USBRX),
+	resetButton(MICROBIT_PIN_BUTTON_RESET),
+    storage(),
+    i2c(I2C_SDA0, I2C_SCL0),
+    messageBus(),
+    display(),
+    buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A),
+    buttonB(MICROBIT_PIN_BUTTON_B, MICROBIT_ID_BUTTON_B),
+    buttonAB(MICROBIT_ID_BUTTON_A,MICROBIT_ID_BUTTON_B, MICROBIT_ID_BUTTON_AB),
+    accelerometer(i2c),
+    compass(i2c, accelerometer, storage),
+    compassCalibrator(compass, accelerometer, display),
+    thermometer(storage),
+    io(MICROBIT_ID_IO_P0,MICROBIT_ID_IO_P1,MICROBIT_ID_IO_P2,
+       MICROBIT_ID_IO_P3,MICROBIT_ID_IO_P4,MICROBIT_ID_IO_P5,
+       MICROBIT_ID_IO_P6,MICROBIT_ID_IO_P7,MICROBIT_ID_IO_P8,
+       MICROBIT_ID_IO_P9,MICROBIT_ID_IO_P10,MICROBIT_ID_IO_P11,
+       MICROBIT_ID_IO_P12,MICROBIT_ID_IO_P13,MICROBIT_ID_IO_P14,
+       MICROBIT_ID_IO_P15,MICROBIT_ID_IO_P16,MICROBIT_ID_IO_P19,
+       MICROBIT_ID_IO_P20),
+    bleManager(storage),
+    radio(),
+    ble(NULL)
+{
+    // Clear our status
+    status = 0;
+
+    // Bring up soft reset functionality as soon as possible.
+    resetButton.mode(PullUp);
+    resetButton.fall(this, &MicroBit::reset);
+}
+
+/**
+  * Post constructor initialisation method.
+  *
+  * This call will initialised the scheduler, memory allocator and Bluetooth stack.
+  *
+  * This is required as the Bluetooth stack can't be brought up in a
+  * static context i.e. in a constructor.
+  *
+  * @code
+  * uBit.init();
+  * @endcode
+  *
+  * @note This method must be called before user code utilises any functionality
+  *       contained by uBit.
+  */
+void MicroBit::init()
+{
+    if (status & MICROBIT_INITIALIZED)
+        return;
+
+#if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR)
+    // Bring up a nested heap allocator.
+    microbit_create_nested_heap(MICROBIT_NESTED_HEAP_SIZE);
+#endif
+
+    // Bring up fiber scheduler.
+    scheduler_init(messageBus);
+
+    // Seed our random number generator
+    seedRandom();
+
+    // Create an event handler to trap any handlers being created for I2C services.
+    // We do this to enable initialisation of those services only when they're used,
+    // which saves processor time, memeory and battery life.
+    messageBus.listen(MICROBIT_ID_MESSAGE_BUS_LISTENER, MICROBIT_EVT_ANY, this, &MicroBit::onListenerRegisteredEvent);
+
+    status |= MICROBIT_INITIALIZED;
+
+#if CONFIG_ENABLED(MICROBIT_BLE_PAIRING_MODE)
+    // Test if we need to enter BLE pairing mode...
+    int i=0;
+    sleep(100);
+    while (buttonA.isPressed() && buttonB.isPressed() && i<10)
+    {
+        sleep(100);
+        i++;
+
+        if (i == 10)
+        {
+#if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR) && CONFIG_ENABLED(MICROBIT_HEAP_REUSE_SD)
+            microbit_create_heap(MICROBIT_SD_GATT_TABLE_START + MICROBIT_SD_GATT_TABLE_SIZE, MICROBIT_SD_LIMIT);
+#endif
+            // Start the BLE stack, if it isn't already running.
+            if (!ble)
+            {
+                bleManager.init(getName(), getSerial(), messageBus, true);
+                ble = bleManager.ble;
+            }
+
+            // Enter pairing mode, using the LED matrix for any necessary pairing operations
+            bleManager.pairingMode(display, buttonA);
+        }
+    }
+#endif
+
+    // Attempt to bring up a second heap region, using unused memory normally reserved for Soft Device.
+#if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR) && CONFIG_ENABLED(MICROBIT_HEAP_REUSE_SD)
+#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED)
+    microbit_create_heap(MICROBIT_SD_GATT_TABLE_START + MICROBIT_SD_GATT_TABLE_SIZE, MICROBIT_SD_LIMIT);
+#else
+    microbit_create_heap(MICROBIT_SRAM_BASE, MICROBIT_SD_LIMIT);
+#endif
+#endif
+
+#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED)
+    // Start the BLE stack, if it isn't already running.
+    if (!ble)
+    {
+        bleManager.init(getName(), getSerial(), messageBus, false);
+        ble = bleManager.ble;
+    }
+#endif
+}
+
+/**
+  * A listener to perform actions as a result of Message Bus reflection.
+  *
+  * In some cases we want to perform lazy instantiation of components, such as
+  * the compass and the accelerometer, where we only want to add them to the idle
+  * fiber when someone has the intention of using these components.
+  */
+void MicroBit::onListenerRegisteredEvent(MicroBitEvent evt)
+{
+    switch(evt.value)
+    {
+        case MICROBIT_ID_BUTTON_AB:
+            // A user has registered to receive events from the buttonAB multibutton.
+            // Disable click events from being generated by ButtonA and ButtonB, and defer the
+            // control of this to the multibutton handler.
+            //
+            // This way, buttons look independent unless a buttonAB is requested, at which
+            // point button A+B clicks can be correclty handled without breaking
+            // causal ordering.
+            buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+            buttonB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
+            buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
+            break;
+
+        case MICROBIT_ID_COMPASS:
+            // A listener has been registered for the compass.
+            // The compass uses lazy instantiation, we just need to read the data once to start it running.
+            // Touch the compass through the heading() function to ensure it is calibrated. if it isn't this will launch any associated calibration algorithms.
+            compass.heading();
+
+            break;
+
+        case MICROBIT_ID_ACCELEROMETER:
+        case MICROBIT_ID_GESTURE:
+            // A listener has been registered for the accelerometer.
+            // The accelerometer uses lazy instantiation, we just need to read the data once to start it running.
+            accelerometer.updateSample();
+            break;
+
+        case MICROBIT_ID_THERMOMETER:
+            // A listener has been registered for the thermometer.
+            // The thermometer uses lazy instantiation, we just need to read the data once to start it running.
+            thermometer.updateSample();
+            break;
+    }
+}
\ No newline at end of file